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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/csmith/aoc-2019/common"
  5. "github.com/csmith/aoc-2019/intcode"
  6. )
  7. type tile uint8
  8. type direction int
  9. const (
  10. unknown tile = iota
  11. wall tile = iota
  12. open tile = iota
  13. start tile = iota
  14. oxygen tile = iota
  15. filled tile = iota
  16. north direction = 1
  17. south direction = 2
  18. west direction = 3
  19. east direction = 4
  20. )
  21. var directions = [4]direction{north, south, west, east}
  22. type step struct {
  23. vm *intcode.VirtualMachine
  24. x int
  25. y int
  26. steps int
  27. }
  28. func (s step) next(direction direction) (int, int) {
  29. switch direction {
  30. case north:
  31. return s.x, s.y - 1
  32. case south:
  33. return s.x, s.y + 1
  34. case west:
  35. return s.x - 1, s.y
  36. case east:
  37. return s.x + 1, s.y
  38. }
  39. panic(fmt.Sprintf("unknown direction: %v", direction))
  40. }
  41. func explore(vm *intcode.VirtualMachine) (grid [100][100]tile, stepsToOxygen int, oxygenX int, oxygenY int) {
  42. queue := make(chan step, 100)
  43. queue <- step{
  44. vm: vm,
  45. x: 50,
  46. y: 50,
  47. }
  48. grid[50][50] = start
  49. for {
  50. select {
  51. case s := <-queue:
  52. for _, d := range directions {
  53. xp, yp := s.next(d)
  54. if grid[yp][xp] != unknown {
  55. continue
  56. }
  57. vmp := s.vm.Clone()
  58. state := *vmp.RunForInput(int(d))
  59. if state == 0 {
  60. grid[yp][xp] = wall
  61. } else {
  62. if state == 2 {
  63. grid[yp][xp] = oxygen
  64. stepsToOxygen = s.steps + 1
  65. oxygenX = xp
  66. oxygenY = yp
  67. } else {
  68. grid[yp][xp] = open
  69. }
  70. queue <- step{
  71. vm: vmp,
  72. x: xp,
  73. y: yp,
  74. steps: s.steps + 1,
  75. }
  76. }
  77. }
  78. default:
  79. return
  80. }
  81. }
  82. }
  83. func disperse(grid [100][100]tile, x, y int) (maxSteps int) {
  84. queue := make(chan step, 100)
  85. queue <- step{
  86. x: x,
  87. y: y,
  88. }
  89. for {
  90. select {
  91. case s := <-queue:
  92. maxSteps = common.Max(maxSteps, s.steps)
  93. for _, d := range directions {
  94. xp, yp := s.next(d)
  95. if grid[yp][xp] == filled || grid[yp][xp] == wall {
  96. continue
  97. }
  98. grid[yp][xp] = filled
  99. queue <- step{
  100. x: xp,
  101. y: yp,
  102. steps: s.steps + 1,
  103. }
  104. }
  105. default:
  106. return
  107. }
  108. }
  109. }
  110. func main() {
  111. input := common.ReadCsvAsInts("15/input.txt")
  112. memory := make([]int, len(input))
  113. copy(memory, input)
  114. vm := intcode.NewVirtualMachine(memory)
  115. vm.Input = make(chan int, 1)
  116. vm.Output = make(chan int, 1)
  117. go vm.Run()
  118. grid, stepsToOxygen, oxyX, oxyY := explore(vm)
  119. println(stepsToOxygen)
  120. println(disperse(grid, oxyX, oxyY))
  121. }