main.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package main
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "log"
  8. "os"
  9. "strconv"
  10. "strings"
  11. )
  12. type Coord struct {
  13. x, y int
  14. }
  15. type Robots struct {
  16. P []Coord
  17. V []Coord
  18. }
  19. func main() {
  20. robots := Robots{
  21. P: make([]Coord, 0, 16),
  22. V: make([]Coord, 0, 16),
  23. }
  24. r := bufio.NewReader(os.Stdin)
  25. // Read input
  26. i := 0
  27. for {
  28. i++
  29. line, err := r.ReadString('\n')
  30. if errors.Is(err, io.EOF) {
  31. break
  32. }
  33. if err != nil {
  34. log.Fatalf("While reading input: %v", err)
  35. }
  36. if len(line) > 0 {
  37. line = line[:len(line)-1]
  38. }
  39. fs := strings.Fields(line)
  40. if len(fs) != 2 {
  41. log.Fatalf("Unexpected number of fields in line: %#v", line)
  42. }
  43. // Position
  44. parts := strings.Split(fs[0], "=")
  45. parts = strings.Split(parts[1], ",")
  46. x, err := strconv.ParseInt(parts[0], 10, 32)
  47. if err != nil {
  48. log.Fatalf("While parsing x coordinate of position at line %d: %q", i, line)
  49. }
  50. y, err := strconv.ParseInt(parts[1], 10, 32)
  51. if err != nil {
  52. log.Fatalf("While parsing y coordinate of position at line %d: %q", i, line)
  53. }
  54. robots.P = append(robots.P, Coord{int(x), int(y)})
  55. // Velocity
  56. parts = strings.Split(fs[1], "=")
  57. parts = strings.Split(parts[1], ",")
  58. x, err = strconv.ParseInt(parts[0], 10, 32)
  59. if err != nil {
  60. log.Fatalf("While parsing x component of velocity at line %d: %q", i, line)
  61. }
  62. y, err = strconv.ParseInt(parts[1], 10, 32)
  63. if err != nil {
  64. log.Fatalf("While parsing y component of velocity at line %d: %q", i, line)
  65. }
  66. robots.V = append(robots.V, Coord{int(x), int(y)})
  67. }
  68. width, height := 11, 7
  69. counts := make(map[Coord]int)
  70. // Calculate counts after 100 timesteps
  71. for i := range robots.P {
  72. v := robots.V[i]
  73. for j := 0; j < 100; j++ {
  74. robots.P[i].x += v.x
  75. robots.P[i].y += v.y
  76. }
  77. wrappedX := addIfNegative(robots.P[i].x%width, width)
  78. wrappedY := addIfNegative(robots.P[i].y%height, height)
  79. coord := Coord{wrappedX, wrappedY}
  80. if _, ok := counts[coord]; !ok {
  81. counts[coord] = 0
  82. }
  83. counts[coord]++
  84. }
  85. xmid := width / 2
  86. ymid := height / 2
  87. quadrants := make([]int, 4)
  88. for k, v := range counts {
  89. if k.x == xmid || k.y == ymid {
  90. continue
  91. }
  92. switch {
  93. case k.x < xmid && k.y < ymid:
  94. quadrants[0] += v
  95. case k.x > xmid && k.y < ymid:
  96. quadrants[1] += v
  97. case k.x < xmid && k.y > ymid:
  98. quadrants[2] += v
  99. case k.x > xmid && k.y > ymid:
  100. quadrants[3] += v
  101. }
  102. }
  103. fmt.Printf("%d\n", quadrants[0]*quadrants[1]*quadrants[2]*quadrants[3])
  104. }
  105. func addIfNegative(a, b int) int {
  106. if a < 0 {
  107. return a + b
  108. }
  109. return a
  110. }