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