2023 Day 8 Part 2
This commit is contained in:
parent
3bddc3760c
commit
b1a9c5dbb3
1 changed files with 58 additions and 6 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in a new issue