-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08.py
119 lines (82 loc) · 2.62 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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import time, re, math
from common import *
def part1():
lines = getDayInput(8, 1)
directions = list(lines.pop(0))
nodes = []
for node in lines:
split = re.compile("\w{3}").findall(node)
nodes.append({
"name": split[0],
"left": split[1],
"right": split[2]
})
currentNode = next(n for n in nodes if n["name"] == "AAA")
dirAmount = len(directions)
dirIndex = 0
steps = 0
while currentNode["name"] != "ZZZ":
if dirIndex >= dirAmount:
dirIndex = 0
# print(dirIndex, dirAmount)
left = currentNode["left"]
right = currentNode["right"]
if directions[dirIndex] == "L":
currentNode = next(n for n in nodes if n["name"] == left)
elif directions[dirIndex] == "R":
currentNode = next(n for n in nodes if n["name"] == right)
dirIndex += 1
steps += 1
return steps
def part2():
lines = getDayInput(8, 2)
directions = list(lines.pop(0))
nodes = []
for node in lines:
split = re.compile("\w{3}").findall(node)
nodes.append({
"name": split[0],
"left": split[1],
"right": split[2]
})
searchNodes = [n for n in nodes if n["name"].endswith("A")]
searcherCount = len(searchNodes)
# find our first Z
stepsToZ = []
for i in range(0, searcherCount):
stepsToZ.append(0)
atZ = 0 # how many of our searchers have found their Z?
dirAmount = len(directions)
dirIndex = 0
while atZ < searcherCount: # until all searchers have found their Z
if dirIndex >= dirAmount: # wrap around the directions list
dirIndex = 0
# print(f"step {steps}: {directions[dirIndex]}")
for i in range(0, searcherCount):
if searchNodes[i] is None:
continue
stepsToZ[i] += 1
# print(f"step {steps}: {i} is at {searchNodes[i]['name']}")
left = searchNodes[i]["left"]
right = searchNodes[i]["right"]
if directions[dirIndex] == "L":
searchNodes[i] = next(n for n in nodes if n["name"] == left)
elif directions[dirIndex] == "R":
searchNodes[i] = next(n for n in nodes if n["name"] == right)
if searchNodes[i]["name"].endswith("Z"):
atZ += 1
searchNodes[i] = None
dirIndex += 1
# print(f"step {steps}: {atZ}")
# find the LCM of all the steps to Z
# i made the mistake of checking reddit before i'd finished this
# and somehow this is the solution?? feels like cheating
# i also don't like how this is more maths-y than code-y, isn't as fun :(
# hey ho - my brute-force solution would've worked..... eventually >_>
return math.lcm(*stepsToZ)
startTime = time.time()
print(f"Part 1: {part1()}")
print(f"Time: {round(time.time() - startTime, 2)} seconds")
startTime = time.time()
print(f"Part 2: {part2()}")
print(f"Time: {round(time.time() - startTime, 2)} seconds")