code.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "math"
  7. "os"
  8. "sort"
  9. )
  10. type box struct {
  11. x, y, z int
  12. id, best int
  13. inCircuit bool
  14. }
  15. func (p box) DistanceTo(other box) float64 {
  16. dx := other.x - p.x
  17. dy := other.y - p.y
  18. dz := other.z - p.z
  19. return math.Sqrt(float64(dx*dx + dy*dy + dz*dz))
  20. }
  21. func readInput(file *os.File) []box {
  22. scanner := bufio.NewScanner(file)
  23. var boxes []box
  24. var id int
  25. for scanner.Scan() {
  26. line := scanner.Text()
  27. if line == "" {
  28. continue
  29. }
  30. var x, y, z int
  31. n, err := fmt.Sscanf(line, "%d,%d,%d", &x, &y, &z)
  32. if n != 3 || err != nil {
  33. log.Fatalf("Bad input: %s", line)
  34. }
  35. boxes = append(boxes, box{x: x, y: y, z: z, id: id})
  36. id++
  37. }
  38. return boxes
  39. }
  40. type circuit struct {
  41. first, second int
  42. boxes []box
  43. }
  44. type distance struct {
  45. first, second int
  46. value float64
  47. }
  48. func part1(boxes []box) int {
  49. var result int
  50. var distances []distance
  51. for i := range boxes {
  52. for j := i + 1; j < len(boxes); j++ {
  53. howFar := boxes[j].DistanceTo(boxes[i])
  54. distances = append(distances, distance{first: boxes[i].id, second: boxes[j].id, value: howFar})
  55. }
  56. }
  57. sort.Slice(distances, func(i, j int) bool { return distances[i].value < distances[j].value })
  58. var circuits [][]int
  59. for i := range distances {
  60. first := boxes[distances[i].first]
  61. second := boxes[distances[i].second]
  62. if first.inCircuit && second.inCircuit {
  63. continue
  64. }
  65. if !first.inCircuit && !second.inCircuit {
  66. circuits = append(circuits, []int{first.id, second.id})
  67. boxes[distances[i].first].inCircuit = true
  68. boxes[distances[i].second].inCircuit = true
  69. } else if !first.inCircuit {
  70. var found bool
  71. for j := range circuits {
  72. for k := range circuits[j] {
  73. if circuits[j][k] == second.id {
  74. found = true
  75. circuits[j] = append(circuits[j], first.id)
  76. break
  77. }
  78. }
  79. }
  80. boxes[distances[i].first].inCircuit = true
  81. if !found {
  82. circuits = append(circuits, []int{first.id})
  83. }
  84. } else if !second.inCircuit {
  85. var found bool
  86. for j := range circuits {
  87. for k := range circuits[j] {
  88. if circuits[j][k] == first.id {
  89. found = true
  90. circuits[j] = append(circuits[j], second.id)
  91. break
  92. }
  93. }
  94. }
  95. boxes[distances[i].second].inCircuit = true
  96. if !found {
  97. circuits = append(circuits, []int{second.id})
  98. }
  99. }
  100. }
  101. fmt.Println(circuits)
  102. return result
  103. }
  104. func main() {
  105. if len(os.Args) < 2 {
  106. log.Fatal("You need to specify a file!")
  107. }
  108. filePath := os.Args[1]
  109. file, err := os.Open(filePath)
  110. if err != nil {
  111. log.Fatalf("Failed to open %s!\n", filePath)
  112. }
  113. boxes := readInput(file)
  114. part1(boxes)
  115. }