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) }