06_orbit.py 990 B

123456789101112131415161718192021222324252627282930313233
  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 = {node: p for p, nodes in graph.items() for node in nodes}
  18. def find_root(node):
  19. yield node
  20. if node in parents:
  21. yield from find_root(parents[node])
  22. path_a = {node: dist for dist, node in enumerate(find_root(a))}
  23. for dist, node in enumerate(find_root(b)):
  24. if node in path_a:
  25. return path_a[node] + dist - 2
  26. graph = read_graph(sys.stdin)
  27. print(count_orbits(graph, 'COM'))
  28. print(shortest_path(graph, 'YOU', 'SAN'))