code.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "os"
  7. "strconv"
  8. "strings"
  9. )
  10. func readInput(file string) [][][]int {
  11. content, err := ioutil.ReadFile(file)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. lines := strings.Split(string(content), "\n")
  16. var points [][][]int
  17. for _, line := range lines {
  18. if line == "" {
  19. continue
  20. }
  21. pointsString := strings.Split(line, " -> ")
  22. if len(pointsString) != 2 {
  23. log.Fatal("Invalid line: ", line)
  24. }
  25. start := strings.Split(pointsString[0], ",")
  26. if len(start) != 2 {
  27. log.Fatal("Invalid start point: ", start)
  28. }
  29. startPoint := make([]int, 2)
  30. startPoint[0], err = strconv.Atoi(start[0])
  31. if err != nil {
  32. log.Fatal(err)
  33. }
  34. startPoint[1], err = strconv.Atoi(start[1])
  35. if err != nil {
  36. log.Fatal(err)
  37. }
  38. end := strings.Split(pointsString[1], ",")
  39. if len(end) != 2 {
  40. log.Fatal("Invalid end point: ", end)
  41. }
  42. endPoint := make([]int, 2)
  43. endPoint[0], err = strconv.Atoi(end[0])
  44. if err != nil {
  45. log.Fatal(err)
  46. }
  47. endPoint[1], err = strconv.Atoi(end[1])
  48. if err != nil {
  49. log.Fatal(err)
  50. }
  51. points = append(points, [][]int{startPoint, endPoint})
  52. }
  53. return points
  54. }
  55. func largest(points [][][]int, index int) int {
  56. largest := 0
  57. for _, point := range points {
  58. if point[0][index] > largest {
  59. largest = point[0][index]
  60. } else if point[1][index] > largest {
  61. largest = point[1][index]
  62. }
  63. }
  64. return largest
  65. }
  66. func makeDiagram(points [][][]int) [][]int {
  67. largestX := largest(points, 0)
  68. largestY := largest(points, 1)
  69. diagram := make([][]int, largestY+1)
  70. for i, _ := range diagram {
  71. diagram[i] = make([]int, largestX+1)
  72. }
  73. return diagram
  74. }
  75. func fillDiagram(points [][][]int, diagram [][]int) {
  76. for _, point := range points {
  77. if point[0][0] != point[1][0] && point[0][1] != point[1][1] {
  78. continue
  79. }
  80. if point[0][0] == point[1][0] {
  81. start := point[0][1]
  82. end := point[1][1]
  83. if start > end {
  84. start, end = end, start
  85. }
  86. for i := start; i <= end; i++ {
  87. diagram[i][point[0][0]]++
  88. }
  89. } else {
  90. start := point[0][0]
  91. end := point[1][0]
  92. if start > end {
  93. start, end = end, start
  94. }
  95. for i := start; i <= end; i++ {
  96. diagram[point[0][1]][i]++
  97. }
  98. }
  99. }
  100. }
  101. func part1(diagram [][]int) int {
  102. var count int
  103. for _, row := range diagram {
  104. for _, value := range row {
  105. if value >= 2 {
  106. count++
  107. }
  108. }
  109. }
  110. return count
  111. }
  112. func fillDiagramDiagonal(points [][][]int, diagram [][]int) {
  113. for _, point := range points {
  114. if point[0][0] == point[1][0] {
  115. start := point[0][1]
  116. end := point[1][1]
  117. if start > end {
  118. start, end = end, start
  119. }
  120. for i := start; i <= end; i++ {
  121. diagram[i][point[0][0]]++
  122. }
  123. } else if point[0][1] == point[1][1] {
  124. start := point[0][0]
  125. end := point[1][0]
  126. if start > end {
  127. start, end = end, start
  128. }
  129. for i := start; i <= end; i++ {
  130. diagram[point[0][1]][i]++
  131. }
  132. } else {
  133. start := point[0]
  134. end := point[1]
  135. if start[0] > end[0] {
  136. start, end = end, start
  137. }
  138. goUp := true
  139. if start[1] < end[1] {
  140. goUp = false
  141. }
  142. x := start[0]
  143. y := start[1]
  144. for {
  145. if x > end[0] {
  146. break
  147. }
  148. if goUp && y < end[1] {
  149. break
  150. } else if !goUp && y > end[1] {
  151. break
  152. }
  153. diagram[y][x]++
  154. x++
  155. if goUp {
  156. y--
  157. } else {
  158. y++
  159. }
  160. }
  161. }
  162. }
  163. }
  164. func main() {
  165. if len(os.Args) < 2 {
  166. log.Fatal("Please provide a file name as argument")
  167. }
  168. input := readInput(os.Args[1])
  169. diagram := makeDiagram(input)
  170. fillDiagram(input, diagram)
  171. fmt.Println("Part1: ", part1(diagram))
  172. diagram = makeDiagram(input)
  173. fillDiagramDiagonal(input, diagram)
  174. fmt.Println("Part2: ", part1(diagram))
  175. }