-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08.py
74 lines (62 loc) · 1.97 KB
/
day08.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from day import Day
from aocd import submit
from utils.parser import Parser
from itertools import cycle
import math
class Map(dict):
def __init__(self, data):
data = Parser(data)
data.parse_list_of_lists()
self._instructions = data.data[0][0]
self._mapping = data.data[1:][0]
self.current = "AAA"
self.steps = 0
self.rl_to_index = {"R": 1, "L": 0}
self._parse()
def _parse(self):
for mapping in self._mapping:
a, b = mapping.split(" = ")
self[a] = b[1:-1].split(", ")
def run(self):
# Run until we find the end
for instruction in cycle(self._instructions):
self.current = self[self.current][self.rl_to_index[instruction]]
self.steps += 1
if self.current == "ZZZ":
return self.steps
def find_starts(self):
starts = []
for v in self.keys():
if v[-1] == "A":
starts.append(v)
return starts
def run_parallel(self):
cycles = []
# Find cycles for all starts
for start in self.find_starts():
self.steps = 0
self.current = start
# Run until we find a cycle
for instruction in cycle(self._instructions):
self.current = self[self.current][self.rl_to_index[instruction]]
self.steps += 1
if self.current[-1] == "Z":
cycles.append(self.steps)
break
# Find the least common multiple of all cycles
return math.lcm(*cycles)
def main(day, part=1):
if part == 1:
return Map(day.data).run()
if part == 2:
return Map(day.data).run_parallel()
if __name__ == "__main__":
day = Day(8)
day.download()
day.load(process=False)
p1 = main(day)
print(p1)
submit(p1, part="a", day=8, year=2023)
p2 = main(day, part=2)
print(p2)
submit(p2, part="b", day=8, year=2023)