code.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8. func readInput(file *os.File) [][]byte {
  9. scanner := bufio.NewScanner(file)
  10. var board [][]byte
  11. for scanner.Scan() {
  12. line := scanner.Text()
  13. if line == "" {
  14. break
  15. }
  16. var row []byte
  17. for i := range line {
  18. row = append(row, line[i])
  19. }
  20. board = append(board, row)
  21. }
  22. return board
  23. }
  24. const (
  25. Horizontal = '-'
  26. Vertical = '|'
  27. Slash = '/'
  28. Backslash = '\\'
  29. Empty = '.'
  30. Mark = '#'
  31. )
  32. const (
  33. North = iota
  34. South
  35. East
  36. West
  37. )
  38. type Beam struct {
  39. y, x int
  40. direction int
  41. }
  42. func (b *Beam) canContinue(board [][]byte, height int, width int) []Beam {
  43. var beams []Beam
  44. if b.x < 0 || b.x >= width || b.y < 0 || b.y >= height {
  45. return beams
  46. }
  47. switch board[b.y][b.x] {
  48. case Horizontal:
  49. if b.direction != East && b.direction != West {
  50. b.direction = East
  51. beams = append(beams, *b)
  52. b.direction = West
  53. beams = append(beams, *b)
  54. return beams
  55. }
  56. case Vertical:
  57. if b.direction != South && b.direction != North {
  58. b.direction = South
  59. beams = append(beams, *b)
  60. b.direction = North
  61. beams = append(beams, *b)
  62. return beams
  63. }
  64. case Slash:
  65. switch b.direction {
  66. case North:
  67. b.direction = East
  68. case South:
  69. b.direction = West
  70. case East:
  71. b.direction = North
  72. case West:
  73. b.direction = South
  74. }
  75. case Backslash:
  76. switch b.direction {
  77. case North:
  78. b.direction = West
  79. case South:
  80. b.direction = East
  81. case East:
  82. b.direction = South
  83. case West:
  84. b.direction = North
  85. }
  86. }
  87. return append(beams, *b)
  88. }
  89. func (b *Beam) move(board [][]byte, height int, width int) []Beam {
  90. switch b.direction {
  91. case North:
  92. b.y--
  93. case South:
  94. b.y++
  95. case East:
  96. b.x++
  97. case West:
  98. b.x--
  99. }
  100. return b.canContinue(board, height, width)
  101. }
  102. func emptyBoard(height int, width int) [][]byte {
  103. var board [][]byte
  104. for i := 0; i < height; i++ {
  105. board = append(board, make([]byte, width))
  106. }
  107. return board
  108. }
  109. func count(board [][]byte) int {
  110. var result int
  111. for y := range board {
  112. for x := range board[y] {
  113. if board[y][x] == Mark {
  114. result++
  115. }
  116. }
  117. }
  118. return result
  119. }
  120. func part1(board [][]byte) int {
  121. height := len(board)
  122. width := len(board[0])
  123. var result int
  124. trackBoard := emptyBoard(height, width)
  125. beams := []Beam{Beam{y: 0, x: 0, direction: East}}
  126. for {
  127. change := false
  128. var newBeams []Beam
  129. for i := range beams {
  130. if trackBoard[beams[i].y][beams[i].x] != Mark {
  131. trackBoard[beams[i].y][beams[i].x] = Mark
  132. change = true
  133. }
  134. newBeams = append(newBeams, beams[i].move(board, height, width)...)
  135. }
  136. if !change {
  137. break
  138. }
  139. beams = newBeams
  140. }
  141. fmt.Println(count(trackBoard), trackBoard)
  142. return result
  143. }
  144. func main() {
  145. if len(os.Args) < 2 {
  146. log.Fatal("You need to specify a file!")
  147. }
  148. filePath := os.Args[1]
  149. file, err := os.Open(filePath)
  150. if err != nil {
  151. log.Fatalf("Failed to open %s!\n", filePath)
  152. }
  153. board := readInput(file)
  154. fmt.Println(part1(board))
  155. }