81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
package day08
|
|
|
|
import (
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
type Coordinate struct {
|
|
Row int
|
|
Col int
|
|
}
|
|
|
|
func Part1(input string) int {
|
|
grid, antennaMap := parseInput(input)
|
|
result := findAntinodes(grid, antennaMap, true)
|
|
return result
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
grid, antennaMap := parseInput(input)
|
|
result := findAntinodes(grid, antennaMap, false)
|
|
return result
|
|
}
|
|
|
|
func parseInput(input string) ([][]rune, map[rune][]Coordinate) {
|
|
lines := strings.Split(input, "\n")
|
|
rowCount := len(lines)
|
|
colCount := len(lines[0])
|
|
grid := make([][]rune, rowCount)
|
|
antennaMap := make(map[rune][]Coordinate)
|
|
|
|
for row := 0; row < rowCount; row++ {
|
|
grid[row] = []rune(lines[row])
|
|
for col := 0; col < colCount; col++ {
|
|
frequency := grid[row][col]
|
|
if frequency != '.' {
|
|
antennaMap[frequency] = append(antennaMap[frequency], Coordinate{Row: row, Col: col})
|
|
}
|
|
}
|
|
}
|
|
|
|
return grid, antennaMap
|
|
}
|
|
|
|
func findAntinodes(grid [][]rune, antennaMap map[rune][]Coordinate, onlySpecial bool) int {
|
|
rowCount := len(grid)
|
|
colCount := len(grid[0])
|
|
uniqueAntinodes := make(map[Coordinate]struct{})
|
|
|
|
for row := 0; row < rowCount; row++ {
|
|
for col := 0; col < colCount; col++ {
|
|
for _, antennaPositions := range antennaMap {
|
|
for i, firstAntenna := range antennaPositions {
|
|
for j, secondAntenna := range antennaPositions {
|
|
//I know I know thats too many for loops
|
|
if i != j {
|
|
distance1 := int(math.Abs(float64(row-firstAntenna.Row)) + math.Abs(float64(col-firstAntenna.Col)))
|
|
distance2 := int(math.Abs(float64(row-secondAntenna.Row)) + math.Abs(float64(col-secondAntenna.Col)))
|
|
|
|
rowDiff1 := row - firstAntenna.Row
|
|
rowDiff2 := row - secondAntenna.Row
|
|
colDiff1 := col - firstAntenna.Col
|
|
colDiff2 := col - secondAntenna.Col
|
|
|
|
if rowDiff1*colDiff2 == rowDiff2*colDiff1 {
|
|
if (distance1 == 2*distance2 || distance1*2 == distance2) && onlySpecial {
|
|
uniqueAntinodes[Coordinate{Row: row, Col: col}] = struct{}{}
|
|
} else if !onlySpecial {
|
|
uniqueAntinodes[Coordinate{Row: row, Col: col}] = struct{}{}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return len(uniqueAntinodes)
|
|
}
|