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 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/csmith/aoc-2019/common"
  5. "github.com/csmith/aoc-2019/intcode"
  6. "strconv"
  7. )
  8. const (
  9. up = '^'
  10. down = 'v'
  11. left = '<'
  12. right = '>'
  13. borked = 'X'
  14. )
  15. func rotate(from, to rune) rune {
  16. if from == up && to == left || from == left && to == down || from == down && to == right || from == right && to == up {
  17. return 'L'
  18. } else {
  19. return 'R'
  20. }
  21. }
  22. func next(picture [][]rune, x, y int, direction rune) (nextDirection, turn rune) {
  23. if x > 0 && direction != right && picture[y][x-1] == '#' {
  24. nextDirection = left
  25. } else if x < len(picture[0])-1 && direction != left && picture[y][x+1] == '#' {
  26. nextDirection = right
  27. } else if y > 0 && direction != down && picture[y-1][x] == '#' {
  28. nextDirection = up
  29. } else if y < len(picture)-1 && direction != up && picture[y+1][x] == '#' {
  30. nextDirection = down
  31. } else {
  32. return borked, borked
  33. }
  34. return nextDirection, rotate(direction, nextDirection)
  35. }
  36. func follow(picture [][]rune, x, y int, direction rune) (int, int, int) {
  37. deltaX, deltaY := 0, 0
  38. switch direction {
  39. case up:
  40. deltaY = -1
  41. case down:
  42. deltaY = 1
  43. case left:
  44. deltaX = -1
  45. case right:
  46. deltaX = +1
  47. case borked:
  48. return x, y, borked
  49. }
  50. length := 0
  51. for x+deltaX >= 0 && x+deltaX <= len(picture[0])-1 && y+deltaY >= 0 && y+deltaY <= len(picture)-1 && picture[y+deltaY][x+deltaX] == '#' {
  52. x += deltaX
  53. y += deltaY
  54. length++
  55. }
  56. return x, y, length
  57. }
  58. func readPicture(memory []int) [][]rune {
  59. vm := intcode.NewVirtualMachine(memory)
  60. vm.Input = make(chan int, 1)
  61. vm.Output = make(chan int, 1)
  62. go vm.Run()
  63. var picture [][]rune
  64. var currentRow []rune
  65. for {
  66. char, more := <-vm.Output
  67. if !more {
  68. break
  69. }
  70. if char == '\n' && len(currentRow) > 0 {
  71. picture = append(picture, currentRow)
  72. currentRow = make([]rune, 0)
  73. } else {
  74. currentRow = append(currentRow, rune(char))
  75. }
  76. }
  77. return picture
  78. }
  79. func analysePicture(picture [][]rune) (sum int, robot rune, robotX, robotY int) {
  80. robot = borked
  81. for y, line := range picture {
  82. for x, r := range line {
  83. if r == '#' &&
  84. x > 0 && line[x-1] == '#' &&
  85. x < len(line)-1 && line[x+1] == '#' &&
  86. y > 0 && picture[y-1][x] == '#' &&
  87. y < len(picture)-1 && picture[y+1][x] == '#' {
  88. sum += x * y
  89. }
  90. if r == up || r == down || r == left || r == right {
  91. robotX = x
  92. robotY = y
  93. robot = r
  94. }
  95. }
  96. }
  97. return
  98. }
  99. func buildRoute(picture [][]rune, robot rune, robotX, robotY int) []string {
  100. var (
  101. length int
  102. turn rune
  103. res []string
  104. )
  105. for {
  106. robot, turn = next(picture, robotX, robotY, robot)
  107. robotX, robotY, length = follow(picture, robotX, robotY, robot)
  108. if robot == borked {
  109. break
  110. }
  111. res = append(res, string(turn))
  112. res = append(res, strconv.Itoa(length))
  113. }
  114. return res
  115. }
  116. func calculateDust(input []int, m, a, b, c string) int {
  117. vm := intcode.NewVirtualMachine(input)
  118. vm.Input = make(chan int, 1)
  119. vm.Output = make(chan int, 1)
  120. vm.Memory[0] = 2
  121. go vm.Run()
  122. go func() {
  123. for _, line := range []string{m, a, b, c, "n"} {
  124. for _, r := range line {
  125. vm.Input <- int(r)
  126. }
  127. vm.Input <- '\n'
  128. }
  129. }()
  130. return common.Last(vm.Output)
  131. }
  132. func main() {
  133. input := common.ReadCsvAsInts("17/input.txt")
  134. memory := make([]int, len(input))
  135. copy(memory, input)
  136. picture := readPicture(input)
  137. sum, robot, robotX, robotY := analysePicture(picture)
  138. route := buildRoute(picture, robot, robotX, robotY)
  139. m, a, b, c := compress(route)
  140. dust := calculateDust(memory, m, a, b, c)
  141. fmt.Println(sum)
  142. fmt.Println(dust)
  143. }