You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.go 1.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/csmith/aoc-2019/common"
  5. )
  6. func countOrbits(satellites map[string][]string, start string, depth int) (res int) {
  7. for _, satellite := range satellites[start] {
  8. res += depth + 1 + countOrbits(satellites, satellite, depth+1)
  9. }
  10. return
  11. }
  12. func routeToCenter(orbits map[string]string, start string) (res []string) {
  13. next := start
  14. for next != "COM" {
  15. next = orbits[next]
  16. res = append(res, next)
  17. }
  18. return
  19. }
  20. func countToCenter(orbits map[string]string, start string) (res map[string]int) {
  21. res = make(map[string]int)
  22. steps := 0
  23. next := start
  24. for next != "COM" {
  25. next = orbits[next]
  26. res[next] = steps
  27. steps++
  28. }
  29. return
  30. }
  31. func shortestPath(orbits map[string]string, from, to string) int {
  32. route := routeToCenter(orbits, from)
  33. steps := countToCenter(orbits, to)
  34. for i, body := range route {
  35. if count, ok := steps[body]; ok {
  36. return count + i
  37. }
  38. }
  39. panic(fmt.Sprintf("No path found between %s and %s.", from, to))
  40. }
  41. func main() {
  42. lines := common.ReadFileAsStrings("06/input.txt")
  43. satellites := make(map[string][]string, len(lines))
  44. orbits := make(map[string]string, len(lines))
  45. for _, line := range lines {
  46. around := line[0:3]
  47. body := line[4:7]
  48. satellites[around] = append(satellites[around], body)
  49. orbits[body] = around
  50. }
  51. println(countOrbits(satellites, "COM", 0))
  52. println(shortestPath(orbits, "YOU", "SAN"))
  53. }