Spaces:
Running
Running
| 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") |