this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

a checkpoint, i've been flailing on this one

+128 -52
+80 -52
2023/day08/part2.ts
··· 1 - type Node = { L: string; R: string }; 2 - 1 + type Node = { L: string; R: string; stepsToZCache: Record<string, number> }; 3 2 type Network = Record<string, Node>; 4 - 5 3 type Path = { 6 - possiblePaths: string[]; 4 + checkpoint: string; 5 + sinceCheckpoint: number; 6 + zsSeen: string[]; 7 + current: string; 7 8 }; 8 9 9 - // 10 + // for every node in the network, calculate the steps 10 11 11 - export function answer(input: string) { 12 - const [instructions, , ...networkRaw] = input.split("\n"); 12 + export function answer(input: string): number { 13 + const [instructionsRaw, , ...networkRaw] = input.split("\n"); 14 + const instructions = instructionsRaw.split(""); 13 15 14 - const parseNetwork = (lines: string[]): Network => 15 - lines.reduce((network, line) => { 16 - const [id, leftAndRight] = line.split(" = "); 17 - const [L, R] = leftAndRight.replaceAll(/[\(\)]/g, "").split(", "); 18 - return { ...network, [id]: { L, R } }; 19 - }, {}); 16 + const network: Network = networkRaw.reduce((network, line) => { 17 + const [id, leftAndRight] = line.split(" = "); 18 + const [L, R] = leftAndRight.replaceAll(/[\(\)]/g, "").split(", "); 19 + return { ...network, [id]: { L, R, stepsToZCache: {} } }; 20 + }, {}); 20 21 21 - const network: Network = parseNetwork(networkRaw); 22 + const cacheKey = (instIdx: number, endNode: string) => 23 + `${endNode}.${instIdx}`; 22 24 23 - // build the paths to X for each starting path 24 - // step forward by longest path 25 - // new positions are stepSize % pathSize 25 + const allPaths: Path[] = Object.keys(network).map((n) => ({ 26 + checkpoint: n, 27 + sinceCheckpoint: 0, 28 + current: n, 29 + zsSeen: [], 30 + })); 26 31 27 - const paths = Object.keys(network) 28 - .filter((n) => n.endsWith("A")) 29 - .map((p) => { 30 - const path = buildPath(p, network, instructions); 31 - console.log(`plength: ${path.length}, last: ${path[path.length - 1]}`); 32 - return { current: path.length - 1, path }; 33 - }); 32 + walkPaths(allPaths, instructions, network); 34 33 35 - const stepSize = Math.max(...paths.map(({ path }) => path.length)); 36 - let stepTotal = stepSize; 34 + // const startPaths: Path[] = Object.keys(network) 35 + // .filter((n) => n.endsWith("A")) 36 + // .map((n) => ({ checkpoint: n, sinceCheckpoint: 0, current: n, zsSeen: [] })); 37 37 38 - while (!paths.every((p) => p.path[p.current] === "Z")) { 39 - console.log(`step by ${stepSize}`); 40 - paths.forEach((p) => { 41 - p.current += stepSize; 42 - p.current = p.path.length % p.current; 43 - console.log(p); 44 - }); 45 - stepTotal += stepSize; 46 - } 38 + // const endNodes = Object.keys(network).filter((n) => n.endsWith("Z")); 47 39 48 - return stepTotal; 40 + // MATH?!!! 41 + // - permutations of `stepsToZ` 42 + // - what operation can I perform with these numbers to know that it is the right answer? 43 + 44 + return 1; 49 45 } 50 46 51 - function buildPath( 52 - start: string, 53 - network: Network, 54 - instructions: string, 55 - ): string[] { 56 - let currentNode = start; 57 - let stepCount = 0; 58 - const endingChars = [start[2]]; 59 - while (!currentNode.endsWith("Z")) { 60 - for (const dir of instructions.split("")) { 61 - currentNode = network[currentNode][dir as keyof Node]; 62 - stepCount++; 63 - endingChars.push(currentNode[2]); 64 - if (currentNode.endsWith("Z")) break; 47 + function walkPaths(paths: Path[], instructions: string[], network: Network) { 48 + const endNodes = Object.keys(network).filter((n) => n.endsWith("Z")); 49 + 50 + let step = -1; 51 + while (true) { 52 + step++; 53 + for (let instIdx = 0; instIdx < instructions.length; instIdx++) { 54 + paths.forEach((p, _pathIdx) => { 55 + p.sinceCheckpoint++; 56 + 57 + p.current = network[p.current][instructions[instIdx] as "L" | "R"]; 58 + 59 + if (p.current.endsWith("Z")) { 60 + console.log( 61 + `found path to z! ${p.checkpoint} from inst ${instIdx} takes ${p.sinceCheckpoint} steps`, 62 + ); 63 + network[p.checkpoint].stepsToZCache[`${instIdx}`] = p.sinceCheckpoint; 64 + 65 + p.checkpoint = p.current; 66 + p.sinceCheckpoint = 0; 67 + } 68 + }); 69 + 70 + // const stepsToZ = paths 71 + // .map((p) => 72 + // endNodes.map( 73 + // (n) => network[p.current].stepsToZCache[`${n}.${instIdx}`], 74 + // ), 75 + // ) 76 + // .flat(); 77 + const stepsToZ = paths.map( 78 + (p) => network[p.current].stepsToZCache[`${instIdx}`], 79 + ); 80 + 81 + console.log( 82 + Object.keys(network).map( 83 + (n) => `${n}: ${JSON.stringify(network[n].stepsToZCache)}`, 84 + ), 85 + ); 86 + 87 + if ( 88 + Object.values(network).every( 89 + (n) => Object.values(n.stepsToZCache).length === endNodes.length, 90 + ) 91 + ) { 92 + return; 93 + // return stepsToZ.reduce((product, x) => (product *= x), 1); 94 + } 65 95 } 66 96 } 67 - 68 - return endingChars; 69 97 } 70 98 71 99 if (import.meta.main) {
+48
2023/day08/part2_slow.ts
··· 1 + type Node = { L: string; R: string }; 2 + type Network = Record<string, Node>; 3 + 4 + export function answer(input: string): number { 5 + const [instructions, , ...networkRaw] = input.split("\n"); 6 + 7 + const network: Network = networkRaw.reduce((network, line) => { 8 + const [id, leftAndRight] = line.split(" = "); 9 + const [L, R] = leftAndRight.replaceAll(/[\(\)]/g, "").split(", "); 10 + return { ...network, [id]: { L, R } }; 11 + }, {}); 12 + 13 + const pathsFinished = (paths: string[]): boolean => 14 + paths.every((p) => p.endsWith("Z")); 15 + 16 + const step = (paths: string[], dir: keyof Node): string[] => 17 + paths.map((c) => network[c][dir]); 18 + 19 + let paths = Object.keys(network).filter((n) => n.endsWith("A")); 20 + let stepCount = 0; 21 + 22 + while (!pathsFinished(paths)) { 23 + for (const dir of instructions.split("")) { 24 + paths = step(paths, dir as keyof Node); 25 + stepCount++; 26 + if (pathsFinished(paths)) break; 27 + } 28 + } 29 + 30 + return stepCount; 31 + } 32 + 33 + function log(paths: string[], step: number) { 34 + console.log( 35 + `${stepCount.toString().padStart(20, "0")}: ${paths 36 + .map((p, i) => (p.endsWith("Z") ? i : ".")) 37 + .join("")}`, 38 + ); 39 + } 40 + 41 + if (import.meta.main) { 42 + const input = ( 43 + await Deno.readFile("input").then((bytes) => 44 + new TextDecoder().decode(bytes), 45 + ) 46 + ).trim(); 47 + console.log(answer(input)); 48 + }