Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

main.go 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. go vmp.Run()
  59. vmp.Input <- int(d)
  60. state := <-vmp.Output
  61. if state == 0 {
  62. grid[yp][xp] = wall
  63. } else {
  64. if state == 2 {
  65. grid[yp][xp] = oxygen
  66. stepsToOxygen = s.steps + 1
  67. oxygenX = xp
  68. oxygenY = yp
  69. } else {
  70. grid[yp][xp] = open
  71. }
  72. queue <- step{
  73. vm: vmp,
  74. x: xp,
  75. y: yp,
  76. steps: s.steps + 1,
  77. }
  78. }
  79. }
  80. default:
  81. return
  82. }
  83. }
  84. }
  85. func disperse(grid [100][100]tile, x, y int) (maxSteps int) {
  86. queue := make(chan step, 100)
  87. queue <- step{
  88. x: x,
  89. y: y,
  90. }
  91. for {
  92. select {
  93. case s := <-queue:
  94. maxSteps = common.Max(maxSteps, s.steps)
  95. for _, d := range directions {
  96. xp, yp := s.next(d)
  97. if grid[yp][xp] == filled || grid[yp][xp] == wall {
  98. continue
  99. }
  100. grid[yp][xp] = filled
  101. queue <- step{
  102. x: xp,
  103. y: yp,
  104. steps: s.steps + 1,
  105. }
  106. }
  107. default:
  108. return
  109. }
  110. }
  111. }
  112. func main() {
  113. input := common.ReadCsvAsInts("15/input.txt")
  114. memory := make([]int, len(input))
  115. copy(memory, input)
  116. vm := intcode.NewVirtualMachine(memory)
  117. vm.Input = make(chan int, 1)
  118. vm.Output = make(chan int, 1)
  119. go vm.Run()
  120. grid, stepsToOxygen, oxyX, oxyY := explore(vm)
  121. println(stepsToOxygen)
  122. println(disperse(grid, oxyX, oxyY))
  123. }