2024-12-08 - Resonant Collinearity
(original .ipynb)
Day 8 puzzle input is a grid showing the positions of certain antennae each operating on different frequencies (same letter/digit = same frequency), mine is here). Part 1 involves finding "antinodes" (can't be bothered explaining, it's stupid) and counting how many there are. Part 2 involves adjusting how the "antinodes" are calculated and counting them again.
from collections import defaultdict from itertools import combinations puzzle_input_str = open("./puzzle_input/day8.txt").read() test_input_str = """............ ........0... .....0...... .......0.... ....0....... ......A..... ............ ............ ........A... .........A.. ............ ............""" def parse_input(input_str): input_lines = input_str.splitlines() antennas = defaultdict(lambda:[]) for r, row in enumerate(input_lines): for c, col in enumerate(row): if col != ".": antennas[col].append((r, c)) return antennas, len(input_lines), len(input_lines[0]) def antinodes(pos_a_r, pos_a_c, pos_b_r, pos_b_c): dr = pos_a_r-pos_b_r dc = pos_a_c-pos_b_c return ( (pos_a_r+dr, pos_a_c+dc), (pos_b_r-dr, pos_b_c-dc), ) def in_graph(max_r, max_c, r, c): return r >= 0 and r < max_r and c >= 0 and c < max_c def part_one(input_str): all_antennas, max_r, max_c = parse_input(input_str) antinode_positions = set() for antenna_name, antennas in all_antennas.items(): for antenna_a, antenna_b in combinations(antennas, 2): for antinode in antinodes(*antenna_a, *antenna_b): if in_graph(max_r, max_c, *antinode): antinode_positions.add(antinode) return len(antinode_positions) assert 14 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 291
from itertools import chain def antinodes_2(max_r, max_c, pos_a_r, pos_a_c, pos_b_r, pos_b_c): dr_base = pos_a_r-pos_b_r dc_base = pos_a_c-pos_b_c for dr, dc in ((dr_base, dc_base), (-dr_base, -dc_base)): for start_r, start_c in ((pos_a_r, pos_a_c), (pos_b_r, pos_b_c)): r, c = start_r+dr, start_c+dc while in_graph(max_r, max_c, r, c): yield (r, c) r += dr c += dc def part_two(input_str): all_antennas, max_r, max_c = parse_input(input_str) antinode_positions = set() for antenna_name, antennas in all_antennas.items(): for antenna_a, antenna_b in combinations(antennas, 2): for antinode in antinodes_2(max_r, max_c, *antenna_a, *antenna_b): if in_graph(max_r, max_c, *antinode): antinode_positions.add(antinode) return len(antinode_positions) assert 34 == part_two(test_input_str) print("part two:", part_two(puzzle_input_str))
part two: 1015