-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrunner.js
130 lines (110 loc) · 2.92 KB
/
runner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// AOC Runner
// Author: Scoder12
const { performance } = require('perf_hooks');
const fs = require('fs').promises;
const readline = require('readline');
process.on('unhandledRejection', error => {
console.error(error);
process.exit(1);
});
const formatFilename = day => {
// You can customize this function to your liking
return day.toString().padStart(2, '0');
};
const formatRuntime = ms => {
// You can customize this function to your liking
// microseconds
if (ms <= 1) {
return Math.round(ms * 1000) + 'µs';
}
// miliseconds
if (ms < 1000) {
const wholeMs = Math.floor(ms);
return wholeMs + 'ms ' + formatRuntime(ms - wholeMs);
}
const sec = ms / 1000;
if (sec < 60) {
const wholeSec = Math.floor(sec);
const remMs = ms - wholeSec * 1000;
return wholeSec + 's ' + formatRuntime(remMs);
}
// Minutes (hopefully it doesn't get to this point lol)
return `${Math.floor(sec / 60)}m ` + formatRuntime((sec % 60) * 1000);
};
const runPart = async (part, mod, data) => {
const funcname = 'part' + part;
const func = mod ? mod[funcname] : undefined;
if (typeof func === 'function') {
console.log('Running Part', part);
const start = performance.now();
let output = func(data);
// You might want to comment this out to get a slight performance benefit
if (output instanceof Promise) {
output = await output;
}
const end = performance.now();
console.log('Output:', output);
const rtime = end - start;
console.log('Took:', formatRuntime(rtime));
return rtime;
} else {
console.log(`No ${funcname} function`);
return 0;
}
};
const getData = async day => {
const fname = formatFilename(day) + '.txt';
let data;
try {
const buf = await fs.readFile(fname);
data = buf.toString('utf-8');
} catch (e) {
if (e && e.message) {
e.message = `Error while reading ${fname}: ` + e.message;
}
throw e;
}
return data.trim();
};
const run = async (day, year = 2020) => {
console.log(`AOC ${year} Day ${day}`);
const mod = require('./' + formatFilename(day));
const data = await getData(day);
const part1Time = await runPart(1, mod, data);
const part2Time = await runPart(2, mod, data);
if (part1Time != 0 && part2Time != 0) {
console.log(`Total time: ${formatRuntime(part1Time + part2Time)}`);
}
};
const ask = question =>
new Promise(resolve => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(question, answer => {
rl.close();
resolve(answer);
});
});
const getDay = async maxDay => {
// eslint-disable-next-line no-constant-condition
while (true) {
let question = 'Enter day' + (maxDay ? ` (max ${maxDay})` : '') + ': ';
const inp = await ask(question);
const day = Number(inp);
if (isNaN(day)) {
console.log('Invalid day');
} else if (maxDay && day > maxDay) {
console.log(`Must be at most ${maxDay}`);
} else {
return day;
}
}
};
module.exports = {
formatFilename,
formatRuntime,
run,
getDay
};