|
| 1 | +// @ts-ignore - tl_ls is missing @types/node |
| 2 | +import { EOL } from "node:os"; |
| 3 | +// @ts-ignore - tl_ls doesn't know about Bun |
| 4 | +const inputLines = (await Bun.file("input").text()).trim().split(EOL); |
| 5 | + |
| 6 | +type Equation = { total: number, values: Array<number> }; |
| 7 | +const OPERATORS = ["+", "*"] as const; |
| 8 | +type Operator = (typeof OPERATORS)[number]; |
| 9 | + |
| 10 | +function testSolution(equation: Equation, operators: Array<Operator>) { |
| 11 | + let computedSolution = equation.values[0]; |
| 12 | + for (let inx = 0; inx < equation.values.length; inx++) { |
| 13 | + const value = equation.values[inx + 1]; |
| 14 | + switch (operators[inx]) { |
| 15 | + case "+": computedSolution += value; break; |
| 16 | + case "*": computedSolution *= value; break; |
| 17 | + } |
| 18 | + } |
| 19 | + return computedSolution === equation.total; |
| 20 | +} |
| 21 | + |
| 22 | +function generateCandidates(equation: Equation, prev: Array<Operator>): Array<Array<Operator>> { |
| 23 | + if (prev.length == (equation.values.length - 1)) return [prev]; |
| 24 | + const candidates: Array<Array<Operator>> = []; |
| 25 | + for (let operator of OPERATORS) { |
| 26 | + const extension = [...prev, operator]; |
| 27 | + const newCandidates = generateCandidates(equation, extension); |
| 28 | + candidates.push(...newCandidates); |
| 29 | + } |
| 30 | + return candidates; |
| 31 | +} |
| 32 | + |
| 33 | +function isPossibleEquation(equation: Equation): boolean { |
| 34 | + const operatorCandidates: Array<Array<Operator>> = generateCandidates(equation, []); |
| 35 | + |
| 36 | + for (let operatorCandidate of operatorCandidates) { |
| 37 | + if (testSolution(equation, operatorCandidate)) return true; |
| 38 | + } |
| 39 | + |
| 40 | + return false; |
| 41 | +} |
| 42 | + |
| 43 | +const equations: Array<Equation> = inputLines.map((line: string) => { |
| 44 | + const [totalString, valuesString] = line.split(/:\s+/); |
| 45 | + const total = parseInt(totalString); |
| 46 | + const values = valuesString.split(/\s+/).map((valueString) => parseInt(valueString)); |
| 47 | + |
| 48 | + return { total, values } as Equation; |
| 49 | +}); |
| 50 | + |
| 51 | +const solution1 = equations |
| 52 | + .filter(isPossibleEquation) |
| 53 | + .map((equation) => equation.total) |
| 54 | + .reduce((acc, total) => acc + total, 0); |
| 55 | + |
| 56 | +const solution2 = -1; |
| 57 | + |
| 58 | +console.log("Part 1:", solution1); |
| 59 | +console.log("Part 2:", solution2); |
0 commit comments