-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday06.py
67 lines (51 loc) · 1.89 KB
/
day06.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
from util import Day
def get_endpoints(pairs: list) -> list:
list_pairs = pairs.copy()
x, y = zip(*pairs)
return list(set(y) - set(x))
def get_chain(pairs: list) -> dict:
list_pairs = pairs.copy()
return {y: (x if x != "COM" else 1) for x, y in list_pairs}
def traverse_orbits(all_orbits: dict, end_points: list):
chain = all_orbits.copy()
list_points = end_points.copy()
orbits = 1
for point in end_points:
node = point
nodes = []
sub_orbits = []
i = 0
# Traverse Chain from endpoint until a "visited" node appears
while type(node) != int:
nodes.append(node)
sub_orbits.append(i)
node = chain[node]
i += 1
sub_orbits = [node + x for x in sub_orbits] # add rest of chains from stop node
orbits += sum(sub_orbits[1:])
# print(sub_orbits)
# Populate chains with node values and mark them visited
for j, el in enumerate(nodes[::-1]):
chain[el] = j + node
[chain.pop(k) for k in all_orbits if type(chain[k]) != int]
return orbits, chain
def center_search(orbits: list, end_one: str, end_two: str):
chain = orbits.copy()
center_one, one = traverse_orbits(chain, [end_one])
center_two, two = traverse_orbits(chain, [end_two])
common = set(one.keys()) & set(two.keys())
closest = max(one[x] for x in common)
return one[end_one] - 1 + two[end_two] - 1 - closest * 2
if __name__ == "__main__":
part1 = Day(6, 1)
part1.load()
part1.apply(str.split, sep=")")
chain = get_chain(part1.data)
end_points = get_endpoints(part1.data)
orbits, traverse = traverse_orbits(chain, end_points)
part1.answer(orbits, v=True)
part2 = Day(6, 2)
part2.load()
part2.apply(str.split, sep=")")
chain = get_chain(part2.data)
part2.answer(center_search(chain, "SAN", "YOU"), v=True)