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 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))