選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

main.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/csmith/aoc-2019/common"
  5. "math"
  6. "strings"
  7. )
  8. var directions = map[byte]common.Point{
  9. 'L': {X: -1, Y: 0},
  10. 'R': {X: +1, Y: 0},
  11. 'U': {X: 0, Y: -1},
  12. 'D': {X: 0, Y: +1},
  13. }
  14. // buildMap constructs a map of points that one or more wires hit, to a slice
  15. // of ints representing the number of steps each wire takes to reach that point.
  16. // The number of steps is 0 if the point is the origin or if the wire doesn't
  17. // reach that point.
  18. func buildMap(origin common.Point, wires []string) map[common.Point][]int64 {
  19. points := map[common.Point][]int64{}
  20. for n, wire := range wires {
  21. var (
  22. pos = origin
  23. steps int64 = 0
  24. moves = strings.Split(wire, ",")
  25. )
  26. for _, move := range moves {
  27. dir := directions[move[0]]
  28. length := common.MustAtoi(move[1:])
  29. for i := 0; i < length; i++ {
  30. pos = pos.Plus(dir)
  31. steps++
  32. val, ok := points[pos]
  33. if !ok {
  34. points[pos] = make([]int64, len(wires))
  35. val = points[pos]
  36. }
  37. val[n] = steps
  38. }
  39. }
  40. }
  41. return points
  42. }
  43. // combinedSteps computes the total number of steps each wire had to take, given a slice of measurements. If not all
  44. // wires have measurement, the second return parameter will be false.
  45. func combinedSteps(steps []int64) (int64, bool) {
  46. var res int64 = 0
  47. for _, distance := range steps {
  48. if distance == 0 {
  49. return 0, false
  50. } else {
  51. res += distance
  52. }
  53. }
  54. return res, true
  55. }
  56. func main() {
  57. wires := common.ReadFileAsStrings("03/input.txt")
  58. origin := common.Point{X: 0, Y: 0}
  59. points := buildMap(origin, wires)
  60. var (
  61. bestDistance int64 = math.MaxInt64
  62. bestSteps int64 = math.MaxInt64
  63. )
  64. for pos, v := range points {
  65. if combinedSteps, hitAll := combinedSteps(v); hitAll {
  66. if distance := pos.Manhattan(origin); distance < bestDistance {
  67. bestDistance = distance
  68. }
  69. if combinedSteps < bestSteps {
  70. bestSteps = combinedSteps
  71. }
  72. }
  73. }
  74. fmt.Println(bestDistance)
  75. fmt.Println(bestSteps)
  76. }