day8.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package main
  2. import (
  3. "bufio"
  4. "flag"
  5. "fmt"
  6. "os"
  7. "time"
  8. )
  9. var grid []string
  10. func main() {
  11. example := flag.Bool("example", false, "example or input")
  12. print := flag.Bool("print", false, "verbose")
  13. flag.Parse()
  14. filename := "input.txt"
  15. if *example {
  16. filename = "example.txt"
  17. }
  18. file, err := os.Open(filename)
  19. if err != nil {
  20. fmt.Println(err)
  21. return
  22. }
  23. defer file.Close()
  24. scanner := bufio.NewScanner(file)
  25. for scanner.Scan() {
  26. grid = append(grid, scanner.Text())
  27. }
  28. if err := scanner.Err(); err != nil {
  29. fmt.Println(err)
  30. return
  31. }
  32. antennas := findAntennas(grid)
  33. // part 1
  34. start := time.Now()
  35. antinodes := generateAntinodes(grid, antennas, true)
  36. end1 := time.Since(start)
  37. if *print {
  38. for p := range antinodes {
  39. grid[p[1]] = replaceCharAt(grid[p[1]], p[0], '#')
  40. }
  41. for _, line := range grid {
  42. fmt.Println(line)
  43. }
  44. }
  45. fmt.Println("Total antinodes:", len(antinodes), "with time:", end1)
  46. // part 2
  47. start = time.Now()
  48. antinodes2 := generateAntinodes(grid, antennas, false)
  49. end2 := time.Since(start)
  50. if *print {
  51. for p := range antinodes2 {
  52. grid[p[1]] = replaceCharAt(grid[p[1]], p[0], '#')
  53. }
  54. for _, line := range grid {
  55. fmt.Println(line)
  56. }
  57. }
  58. for _, anantenna := range antennas {
  59. for _, point := range anantenna {
  60. antinodes2[point] = true
  61. }
  62. }
  63. fmt.Println("Total antinodes inline:", len(antinodes2), "with time:", end2)
  64. }
  65. func findAntennas(grid []string) map[rune][][2]int {
  66. antennas := make(map[rune][][2]int)
  67. for y, row := range grid {
  68. for x, cell := range row {
  69. if cell != '.' {
  70. antennas[rune(cell)] = append(antennas[rune(cell)], [2]int{x, y})
  71. }
  72. }
  73. }
  74. return antennas
  75. }
  76. func generateAntinodes(grid []string, antennas map[rune][][2]int, ones bool) map[[2]int]bool {
  77. antinodes := make(map[[2]int]bool)
  78. height := len(grid)
  79. width := len(grid[0])
  80. for _, positions := range antennas {
  81. for i := 0; i < len(positions); i++ {
  82. for j := i + 1; j < len(positions); j++ {
  83. x1, y1 := positions[i][0], positions[i][1]
  84. x2, y2 := positions[j][0], positions[j][1]
  85. dx, dy := x2-x1, y2-y1
  86. addAntinodes(antinodes, x2, dx, y2, dy, width, height, ones)
  87. addAntinodes(antinodes, x1, -dx, y1, -dy, width, height, ones)
  88. }
  89. }
  90. }
  91. return antinodes
  92. }
  93. func addAntinodes(antinodes map[[2]int]bool, x, dx, y, dy, width, height int, ones bool) {
  94. ax, ay := x+dx, y+dy
  95. for {
  96. if ax >= 0 && ax < width && ay >= 0 && ay < height {
  97. antinodes[[2]int{ax, ay}] = true
  98. ax, ay = ax+dx, ay+dy
  99. if ones {
  100. break
  101. }
  102. } else {
  103. break
  104. }
  105. }
  106. }
  107. func replaceCharAt(s string, index int, newChar rune) string {
  108. runes := []rune(s)
  109. runes[index] = newChar
  110. return string(runes)
  111. }