aoc-automation
Version:
Advent of Code tool to automate the repetitive parts of AoC.
156 lines (151 loc) • 4.84 kB
JavaScript
import fs from "fs";
import kleur from "kleur";
import { stripIndent } from "common-tags";
import { saveConfig, readConfig } from "./io/config.js";
import toFixed from "./utils/toFixed.js";
import getDayData from "./utils/getDayData.js";
const runTests = async (tests, solution, part, trimTestInputs = true) => {
for (let i = 0; i < tests.length; i++) {
const { name, input, expected } = tests[i];
const data = trimTestInputs ? stripIndent(input) : input;
const testName = `Part ${part}, test ${i + 1}${name ? `, ${name}` : ""}`;
const result = await solution(data, testName);
if (result === expected) {
console.log(kleur.green(`${testName} - passed with result: ${result}`));
} else {
console.log(kleur.red(`${testName} - failed`));
console.log(`
Result:`);
console.dir(result);
console.log(`
Expected:`);
console.dir(expected);
console.log();
}
}
};
const runSolution = async (solution, input, part) => {
const t0 = process.hrtime.bigint();
const result = await solution(input);
const t1 = process.hrtime.bigint();
const time = Number(t1 - t0) / 1e6;
if (!["string", "number", "bigint", "undefined"].includes(typeof result)) {
console.log(
kleur.yellow(
`Warning - the result type of part ${part} should be a string, a number or a bigint, got:`
),
kleur.red(typeof result)
);
}
console.log(`
Part ${part} (in ${toFixed(time)}ms):`);
if (typeof result === "string" && /\n/.test(result)) {
console.log(result);
} else {
console.dir(result);
}
return { result, time };
};
const runAsync = async (solutions, inputFile, year, day) => {
var _a, _b;
const config = readConfig();
if ((_a = solutions == null ? void 0 : solutions.part1) == null ? void 0 : _a.tests) {
await runTests(
solutions.part1.tests,
solutions.part1.solution,
1,
solutions.trimTestInputs
);
}
if ((_b = solutions == null ? void 0 : solutions.part2) == null ? void 0 : _b.tests) {
await runTests(
solutions.part2.tests,
solutions.part2.solution,
2,
solutions.trimTestInputs
);
}
if (solutions.onlyTests) {
return;
}
const input = fs.readFileSync(inputFile).toString();
let output1;
let output2;
let totalTime = 0;
if (solutions.part1) {
output1 = await runSolution(solutions.part1.solution, input, 1);
totalTime += output1.time;
}
if (solutions.part2) {
output2 = await runSolution(solutions.part2.solution, input, 2);
totalTime += output2.time;
}
console.log(`
Total time: ${toFixed(totalTime)}ms`);
const configYear = config.years.find((y) => y.year === year);
configYear.days[day - 1].part1.result = (output1 == null ? void 0 : output1.result) === void 0 ? null : String(output1.result);
configYear.days[day - 1].part1.time = (output1 == null ? void 0 : output1.result) === void 0 ? null : output1.time;
configYear.days[day - 1].part2.result = (output2 == null ? void 0 : output2.result) === void 0 ? null : String(output2.result);
configYear.days[day - 1].part2.time = (output2 == null ? void 0 : output2.result) === void 0 ? null : output2.time;
saveConfig(config);
};
const run = (solutions, customInputFile) => {
let year = null;
let day = null;
let inputFile = null;
if (customInputFile) {
const dayName = (customInputFile.match(/day\d\d/) || [])[0];
inputFile = customInputFile;
day = dayName ? Number(dayName.slice(-2)) : null;
} else {
const dayData = getDayData();
year = dayData.year;
day = dayData.day;
inputFile = dayData.inputFile;
}
if (inputFile === null) {
console.log(
kleur.red(stripIndent`
Couldn't detect the day directory!
Please make sure that the day folder is named "dayXX",
where each X means number from 0 to 9.
`)
);
return;
}
if (year === null) {
console.log(
kleur.red(stripIndent`
Couldn't detect the year number!
Make sure that your directory contains the year number
in format "XXXX" from 2015 to the current year.
`)
);
return;
}
if (day === null) {
console.log(
kleur.red(stripIndent`
Couldn't detect the day number!
Make sure that your directory or file name contains the day number
in format "dayXX", where each X means number from 0 to 9.
`)
);
return;
}
if (!fs.existsSync(inputFile)) {
console.log(
kleur.red(stripIndent`
There is no "input.txt" file in the solution directory!
Please add the file or specify custom file location
via the second argument of the \`run\` function.
`)
);
return;
}
runAsync(solutions, inputFile, year, day);
};
var src_default = run;
export {
src_default as default
};