| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- package main
- import (
- "bufio"
- "flag"
- "fmt"
- "os"
- "time"
- )
- var grid []string
- func main() {
- example := flag.Bool("example", false, "example or input")
- print := flag.Bool("print", false, "verbose")
- flag.Parse()
- filename := "input.txt"
- if *example {
- filename = "example.txt"
- }
- file, err := os.Open(filename)
- if err != nil {
- fmt.Println(err)
- return
- }
- defer file.Close()
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- grid = append(grid, scanner.Text())
- }
- if err := scanner.Err(); err != nil {
- fmt.Println(err)
- return
- }
- antennas := findAntennas(grid)
- // part 1
- start := time.Now()
- antinodes := generateAntinodes(grid, antennas, true)
- end1 := time.Since(start)
- if *print {
- for p := range antinodes {
- grid[p[1]] = replaceCharAt(grid[p[1]], p[0], '#')
- }
- for _, line := range grid {
- fmt.Println(line)
- }
- }
- fmt.Println("Total antinodes:", len(antinodes), "with time:", end1)
- // part 2
- start = time.Now()
- antinodes2 := generateAntinodes(grid, antennas, false)
- end2 := time.Since(start)
- if *print {
- for p := range antinodes2 {
- grid[p[1]] = replaceCharAt(grid[p[1]], p[0], '#')
- }
- for _, line := range grid {
- fmt.Println(line)
- }
- }
- for _, anantenna := range antennas {
- for _, point := range anantenna {
- antinodes2[point] = true
- }
- }
- fmt.Println("Total antinodes inline:", len(antinodes2), "with time:", end2)
- }
- func findAntennas(grid []string) map[rune][][2]int {
- antennas := make(map[rune][][2]int)
- for y, row := range grid {
- for x, cell := range row {
- if cell != '.' {
- antennas[rune(cell)] = append(antennas[rune(cell)], [2]int{x, y})
- }
- }
- }
- return antennas
- }
- func generateAntinodes(grid []string, antennas map[rune][][2]int, ones bool) map[[2]int]bool {
- antinodes := make(map[[2]int]bool)
- height := len(grid)
- width := len(grid[0])
- for _, positions := range antennas {
- for i := 0; i < len(positions); i++ {
- for j := i + 1; j < len(positions); j++ {
- x1, y1 := positions[i][0], positions[i][1]
- x2, y2 := positions[j][0], positions[j][1]
- dx, dy := x2-x1, y2-y1
- addAntinodes(antinodes, x2, dx, y2, dy, width, height, ones)
- addAntinodes(antinodes, x1, -dx, y1, -dy, width, height, ones)
- }
- }
- }
- return antinodes
- }
- func addAntinodes(antinodes map[[2]int]bool, x, dx, y, dy, width, height int, ones bool) {
- ax, ay := x+dx, y+dy
- for {
- if ax >= 0 && ax < width && ay >= 0 && ay < height {
- antinodes[[2]int{ax, ay}] = true
- ax, ay = ax+dx, ay+dy
- if ones {
- break
- }
- } else {
- break
- }
- }
- }
- func replaceCharAt(s string, index int, newChar rune) string {
- runes := []rune(s)
- runes[index] = newChar
- return string(runes)
- }
|