06_orbit.py 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. #!/usr/bin/env python3
  2. import sys
  3. def read_graph(f):
  4. graph = {}
  5. for line in f:
  6. planet, moon = line.rstrip().split(')')
  7. graph.setdefault(planet, []).append(moon)
  8. return graph
  9. def count_orbits(graph, root):
  10. def dfs(node, depth, vis):
  11. vis.add(node)
  12. return depth + sum(dfs(nb, depth + 1, vis)
  13. for nb in graph.get(node, [])
  14. if nb not in vis)
  15. return dfs(root, 0, set())
  16. def shortest_path(graph, a, b):
  17. parents = {}
  18. for planet, moons in graph.items():
  19. for moon in moons:
  20. parents[moon] = planet
  21. def find_root(node):
  22. yield node
  23. if node in parents:
  24. yield from find_root(parents[node])
  25. path_a = {node: dist for dist, node in enumerate(find_root(a))}
  26. for dist, node in enumerate(find_root(b)):
  27. if node in path_a:
  28. return path_a[node] + dist
  29. graph = read_graph(sys.stdin)
  30. print(count_orbits(graph, 'COM'))
  31. print(shortest_path(graph, 'YOU', 'SAN') - 2)