-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrunner.js
123 lines (104 loc) · 2.91 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
// AOC Runner
// Author: Scoder12
import { performance } from 'perf_hooks';
import * as fs from 'fs/promises';
import * as readline from 'readline';
process.on('unhandledRejection', error => {
console.error(error);
process.exit(1);
});
export const formatFilename = day => {
// You can customize this function to your liking
return day.toString().padStart(2, '0');
};
export 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.replace(/[\r\n]+$/, '');
};
export const run = async (day, year = 2022) => {
console.log(`AOC ${year} Day ${day}`);
const mod = await import('./' + formatFilename(day) + '.js');
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);
});
});
export 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;
}
}
};