From b1a9c5dbb3b302e7457dd6c2178412a26b634b31 Mon Sep 17 00:00:00 2001 From: Jeremy Kaplan Date: Thu, 7 Dec 2023 21:51:32 -0800 Subject: [PATCH] 2023 Day 8 Part 2 --- 2023/day08.nim | 64 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/2023/day08.nim b/2023/day08.nim index cf62849..75e7963 100644 --- a/2023/day08.nim +++ b/2023/day08.nim @@ -40,19 +40,71 @@ proc parseMap(text: string): Map = for node in parts[1].strip.splitLines.map(parseNode): result.nodes[node.id] = node +func step(map: Map, loc: string, n: int): string = + case map.moves[n mod len(map.moves)]: + of L: map.nodes[loc].left + of R: map.nodes[loc].right + proc dbg[T](v: T): T = (echo(v); v) proc part1(): int = let text = readFile("input/day08.txt") var map = parseMap(text) - var mv = 0 var loc = "AAA" while loc != "ZZZ": - case map.moves[mv mod len(map.moves)]: - of L: loc = map.nodes[loc].left - of R: loc = map.nodes[loc].right - mv = mv + 1 - return mv + loc = map.step(loc, result) + inc result + +func isDone(loc: string): bool = + loc.endsWith('Z') + +func walk(map: Map, start: string): seq[int] = + var loc = start + var mv = 0 + while true: + if loc.isDone: + result.add mv + if result.len > 2: + if result[^1] - result[^2] == result[^2] - result[^3]: + return + loc = map.step(loc, mv) + inc mv + +func gcd(a: int, b: int): int = + var a = a + var b = b + while b != 0: + let t = b + b = a mod b + a = t + return a + +func gcd(nums: seq[int]): int = + result = gcd(nums[0], nums[1]) + for n in nums[2..^1]: + result = gcd(result, n) + +proc part2(): int = + let text = readFile("input/day08.txt") + var map = parseMap(text) + + var starts: seq[string] + for loc in map.nodes.keys: + if loc.endsWith('A'): + starts.add loc + + var periods: seq[int] + for start in starts: + let times = map.walk(start) + assert(3 * times[0] == times[2]) + periods.add times[0] + + let gcd = gcd(periods) + + result = periods[0] + for p in periods[1..^1]: + result *= int(p / gcd) echo part1() +echo part2()