def parse_input(file): with open(file, 'r') as f: grid = [line.strip() for line in f.readlines()] return grid def find_antennas(grid): antennas = {} for y, row in enumerate(grid): for x, char in enumerate(row): if char != '.': if char not in antennas: antennas[char] = [] antennas[char].append((x, y)) return antennas def calculate_antinodes_part_one(antennas): antinodes = set() for freq, positions in antennas.items(): n = len(positions) for i in range(n): for j in range(i + 1, n): x1, y1 = positions[i] x2, y2 = positions[j] # Check for antinodes on the line between (x1, y1) and (x2, y2) if x1 == x2: # Vertical line for y in range(min(y1, y2) - abs(y2 - y1), max(y1, y2) + abs(y2 - y1) + 1): if y != y1 and y != y2: antinodes.add((x1, y)) elif y1 == y2: # Horizontal line for x in range(min(x1, x2) - abs(x2 - x1), max(x1, x2) + abs(x2 - x1) + 1): if x != x1 and x != x2: antinodes.add((x, y1)) else: # Diagonal line dx = x2 - x1 dy = y2 - y1 for k in range(-max(abs(dx), abs(dy)), max(abs(dx), abs(dy)) + 1): x = x1 + k * dx y = y1 + k * dy if (x, y) != (x1, y1) and (x, y) != (x2, y2): antinodes.add((x, y)) return antinodes def calculate_antinodes_part_two(antennas): antinodes = set() for freq, positions in antennas.items(): n = len(positions) for i in range(n): for j in range(i + 1, n): x1, y1 = positions[i] x2, y2 = positions[j] # Mark all points in line with at least two antennas if x1 == x2: # Vertical line for y in range(min(y1, y2), max(y1, y2) + 1): antinodes.add((x1, y)) elif y1 == y2: # Horizontal line for x in range(min(x1, x2), max(x1, x2) + 1): antinodes.add((x, y1)) else: # Diagonal line dx = x2 - x1 dy = y2 - y1 for k in range(max(abs(dx), abs(dy)) + 1): x = x1 + k * (dx // abs(dx)) y = y1 + k * (dy // abs(dy)) antinodes.add((x, y)) return antinodes def main(): file = "input.txt" grid = parse_input(file) antennas = find_antennas(grid) # Part One antinodes_part_one = calculate_antinodes_part_one(antennas) print(len(antinodes_part_one)) # Part Two antinodes_part_two = calculate_antinodes_part_two(antennas) print(len(antinodes_part_two)) main()