This repository has been archived by the owner on May 28, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
06_orbit_map.py
74 lines (56 loc) · 1.94 KB
/
06_orbit_map.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
######################################
# --- Day 6: Universal Orbit Map --- #
######################################
import AOCUtils
from collections import deque
class Tree:
def __init__(self, children):
self.root = Node("COM")
self.checksum = 0
self.depths = {"COM": 0}
queue = deque([self.root])
while queue:
cur = queue.popleft()
if cur.name not in children: continue
depth = self.depths[cur.name] + 1
for childName in children[cur.name]:
cur.children.append(Node(childName))
self.depths[childName] = depth
queue += cur.children
def getChecksum(self):
return sum(self.depths.values())
def getPath(self, name):
# BFS from root to name
queue = deque([(self.root, [])])
while queue:
cur, path = queue.popleft()
if cur.name == name:
return path + [name]
for child in cur.children:
newPath = path + [cur.name]
queue.append((child, newPath))
def getLCA(self, nameA, nameB):
pathA = self.getPath(nameA)
pathB = self.getPath(nameB)
# Find lowest common ancestor by comparing both paths
minLen = min(len(pathA), len(pathB))
for i in range(minLen):
if pathA[i] != pathB[i]:
return pathA[i-1]
class Node:
def __init__(self, name):
self.name = name
self.children = []
######################################
orbits = [s.split(")") for s in AOCUtils.loadInput(6)]
children = dict()
for orb in orbits:
if orb[0] not in children:
children[orb[0]] = []
children[orb[0]].append(orb[1])
tree = Tree(children)
print("Part 1: {}".format(tree.getChecksum()))
lca = tree.getLCA("YOU", "SAN")
dist = tree.depths["YOU"] + tree.depths["SAN"] - 2*tree.depths[lca] - 2
print("Part 2: {}".format(dist))
AOCUtils.printTimeTaken()