def read_input(file_path): with open(file_path, 'r') as f: return [line.strip() for line in f.readlines()] def find_antennas(grid): antennas = {} for y in range(len(grid)): for x in range(len(grid[y])): if grid[y][x] not in '.': freq = grid[y][x] if freq not in antennas: antennas[freq] = [] antennas[freq].append((x, y)) return antennas def is_collinear(p1, p2, p3): x1, y1 = p1 x2, y2 = p2 x3, y3 = p3 return (y2-y1)*(x3-x1) == (y3-y1)*(x2-x1) def distance_squared(p1, p2): return (p2[0]-p1[0])**2 + (p2[1]-p1[1])**2 def find_antinodes_part1(grid, antennas): antinodes = set() height, width = len(grid), len(grid[0]) for freq, positions in antennas.items(): if len(positions) < 2: continue for i in range(len(positions)): for j in range(i+1, len(positions)): a1, a2 = positions[i], positions[j] # Check all points in the grid for y in range(height): for x in range(width): point = (x, y) if point == a1 or point == a2: continue if is_collinear(a1, a2, point): d1 = distance_squared(point, a1) d2 = distance_squared(point, a2) if d1 == 2*d2 or d2 == 2*d1: antinodes.add(point) return len(antinodes) def find_antinodes_part2(grid, antennas): antinodes = set() height, width = len(grid), len(grid[0]) for freq, positions in antennas.items(): if len(positions) < 2: continue # Add antenna positions as antinodes if there are multiple antennas of same frequency antinodes.update(positions) # Check all points in the grid for y in range(height): for x in range(width): point = (x, y) # Count how many pairs of antennas this point is collinear with for i in range(len(positions)): for j in range(i+1, len(positions)): if is_collinear(positions[i], positions[j], point): antinodes.add(point) return len(antinodes) def solve(file_path): grid = read_input(file_path) antennas = find_antennas(grid) part1 = find_antinodes_part1(grid, antennas) part2 = find_antinodes_part2(grid, antennas) print(str(part1)) print(str(part2)) solve("./input.txt")