aoc-2023/day_19/solve_2.ts

59 lines
1.7 KiB
TypeScript
Raw Normal View History

2024-12-09 22:41:02 +09:00
import { parseInput, Workflow } from "./parser.ts";
import { partition, MaterialRange } from "./range.ts";
const input = await Deno.readTextFile("input.txt");
const parsed = parseInput(input);
class Executor {
workflowTable: Map<string, Workflow>
constructor(rules: Workflow[]) {
this.workflowTable = new Map();
for (const rule of rules) {
this.workflowTable.set(rule.name, rule);
}
}
caculRange(start: string, material: MaterialRange) {
if (start === "A") {
return [material];
}
if (start === "R") {
return [];
}
const gotoRules = this.workflowTable.get(start)!;
const ret = [] as MaterialRange[];
let dest = gotoRules.always;
for (const rule of gotoRules.rules) {
const cond = partition(rule.condition, material)
if (cond === null) {
// skip
continue;
}
else if (cond instanceof Array) {
const [falseRange, trueRange] = cond;
ret.push(...this.caculRange(rule.dest, trueRange));
material = falseRange;
}
else {
dest = rule.dest;
break;
}
}
ret.push(...this.caculRange(dest, material));
return ret;
}
}
const executor = new Executor(parsed.rules);
const ranges = executor.caculRange("in", {
x: [1, 4000],
m: [1, 4000],
a: [1, 4000],
s: [1, 4000]
});
const countRange = (x: [number, number])=> x[1] - x[0] + 1;
console.log(ranges.map(r=> {
return countRange(r.x) * countRange(r.m) * countRange(r.a) * countRange(r.s);
}).reduce((a, b) => a + b, 0))