From 8ca55aec8b63f8ea4a77eccd6edf7016c3b54f8b Mon Sep 17 00:00:00 2001 From: Seth Etter Date: Sat, 9 Dec 2023 21:57:09 -0600 Subject: [PATCH] ok, lcm was the missing piece --- 2023/day08/part2.ts | 77 ++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 54 deletions(-) diff --git a/2023/day08/part2.ts b/2023/day08/part2.ts index 677f59e..5806862 100644 --- a/2023/day08/part2.ts +++ b/2023/day08/part2.ts @@ -1,13 +1,7 @@ type Node = { L: string; R: string }; type Network = Record; -type Path = { - start: string; - current: string; - history: string[]; -}; - -export function answer(input: string): number { +export function answer(input: string) { const [instructionsRaw, , ...networkRaw] = input.split("\n"); const network: Network = networkRaw.reduce((network, line) => { @@ -16,60 +10,35 @@ export function answer(input: string): number { return { ...network, [id]: { L, R } }; }, {}); - const instructions = instructionsRaw.split(""); - - const next = (node: string, i: number): string => - network[node][instructions[i] as "L" | "R"]; - - const startNodes = Object.keys(network).filter((n) => n.endsWith("A")); - const endNodes = Object.keys(network).filter((n) => n.endsWith("Z")); + const instructions = instructionsRaw.split("") as ("L" | "R")[]; - const paths: Path[] = startNodes.map((n) => ({ - start: n, - current: n, - history: [], - })); + const paths = Object.keys(network).filter((n) => n.endsWith("A")); - const stepsToZCache: Record = {}; - - const stepPath = (p: Path, instIdx: number, step: number) => { - p.history.push(p.current); - p.current = next(p.current, instIdx); - - if (p.current.endsWith("Z")) { - p.history.forEach((prev, i) => { - console.log(`${instIdx}.${prev}.${p.current} = ${step - i + 1}`); - stepsToZCache[`${instIdx}.${prev}.${p.current}`] = step - i + 1; - }); + const stepsToZ = (node: string) => { + let step = 0; + while (!node.endsWith("Z")) { + for (const dir of instructions) { + node = network[node][dir]; + step++; + if (node.endsWith("Z")) break; + } } + return step; }; - let step = 0; - while (true) { - for (let instIdx = 0; instIdx < instructions.length; instIdx++) { - const stepsToZFromCurrent: number[] = []; - - paths.forEach((p) => { - stepPath(p, instIdx, step); - for (const en of endNodes) { - const steps = stepsToZCache[`${instIdx}.${p.current}.${en}`]; - if (steps) stepsToZFromCurrent.push(steps); - } - }); - - const pathsToZ = paths.map((p) => - endNodes - .map((en) => stepsToZCache[`${instIdx}.${p.current}.${en}`]) - .filter((s) => s !== undefined), - ); + return lcm(paths.map((p) => stepsToZ(p))); +} - if (pathsToZ.every((p) => p.length > 0)) { - return pathsToZ.reduce((product, x) => (product *= x[x.length - 1]), 1); - } +function lcm(nums: number[]): number { + const [a, b, ...rest] = nums; + const c = (a * b) / gcf(a, b); + if (rest.length === 0) return c; + return lcm([c, ...rest]); +} - step++; - } - } +function gcf(a: number, b: number): number { + if (b === 0) return a; + return gcf(b, a % b); } if (import.meta.main) { -- 2.51.2