mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
from collections import defaultdict
|
|
|
|
|
|
def part1(input: str) -> int:
|
|
grid = [list(line) for line in input.splitlines()]
|
|
map_antenna_to_coords: dict[str, list[tuple[int, int]]] = defaultdict(list)
|
|
for i in range(len(grid)):
|
|
for j in range(len(grid[0])):
|
|
if grid[i][j] != ".":
|
|
map_antenna_to_coords[grid[i][j]].append((i, j))
|
|
|
|
rows = len(grid)
|
|
cols = len(grid[0])
|
|
|
|
anti_node_coords: set[tuple[int, int]] = set()
|
|
|
|
for _, coords in map_antenna_to_coords.items():
|
|
|
|
for i in range(len(coords)):
|
|
c1 = coords[i]
|
|
for j in range(i + 1, len(coords)):
|
|
c2 = coords[j]
|
|
|
|
if c1 == c2:
|
|
continue
|
|
|
|
rowDiff: int = c2[0] - c1[0]
|
|
colDiff: int = c2[1] - c1[1]
|
|
|
|
maybeRow: int = c1[0] - rowDiff
|
|
maybeCol: int = c1[1] - colDiff
|
|
if (
|
|
0 <= maybeRow < rows
|
|
and 0 <= maybeCol < cols
|
|
and (maybeRow, maybeCol) != c1
|
|
and (maybeRow, maybeCol) != c2
|
|
):
|
|
anti_node_coords.add((maybeRow, maybeCol))
|
|
|
|
maybeRow: int = c2[0] + rowDiff
|
|
maybeCol: int = c2[1] + colDiff
|
|
if (
|
|
0 <= maybeRow < rows
|
|
and 0 <= maybeCol < cols
|
|
and (maybeRow, maybeCol) != c1
|
|
and (maybeRow, maybeCol) != c2
|
|
):
|
|
anti_node_coords.add((maybeRow, maybeCol))
|
|
|
|
return len(anti_node_coords)
|
|
|
|
|
|
def part2(input: str) -> int:
|
|
grid = [list(line) for line in input.splitlines()]
|
|
map_antenna_to_coords: dict[str, list[tuple[int, int]]] = defaultdict(list)
|
|
for i in range(len(grid)):
|
|
for j in range(len(grid[0])):
|
|
if grid[i][j] != ".":
|
|
map_antenna_to_coords[grid[i][j]].append((i, j))
|
|
|
|
rows = len(grid)
|
|
cols = len(grid[0])
|
|
|
|
anti_node_coords: set[tuple[int, int]] = set()
|
|
|
|
for _, coords in map_antenna_to_coords.items():
|
|
|
|
for i in range(len(coords)):
|
|
c1 = coords[i]
|
|
|
|
# a more elegant solution would be to calculate the starting point of the antenna's line
|
|
# then do a single loop to find all anti-node coords
|
|
# instead, i'll just go left and right from c1, and add c1 manually
|
|
anti_node_coords.add(c1)
|
|
|
|
for j in range(i + 1, len(coords)):
|
|
c2 = coords[j]
|
|
|
|
if c1 == c2:
|
|
continue
|
|
|
|
rowDiff: int = c2[0] - c1[0]
|
|
colDiff: int = c2[1] - c1[1]
|
|
|
|
maybeRow: int = c1[0] - rowDiff
|
|
maybeCol: int = c1[1] - colDiff
|
|
while 0 <= maybeRow < rows and 0 <= maybeCol < cols:
|
|
anti_node_coords.add((maybeRow, maybeCol))
|
|
maybeRow -= rowDiff
|
|
maybeCol -= colDiff
|
|
|
|
maybeRow: int = c1[0] + rowDiff
|
|
maybeCol: int = c1[1] + colDiff
|
|
while 0 <= maybeRow < rows and 0 <= maybeCol < cols:
|
|
anti_node_coords.add((maybeRow, maybeCol))
|
|
maybeRow += rowDiff
|
|
maybeCol += colDiff
|
|
|
|
return len(anti_node_coords)
|
|
|
|
|
|
example = """............
|
|
........0...
|
|
.....0......
|
|
.......0....
|
|
....0.......
|
|
......A.....
|
|
............
|
|
............
|
|
........A...
|
|
.........A..
|
|
............
|
|
............"""
|
|
|
|
input = open("input.txt").read()
|
|
|
|
print(f"part1 example: {part1(example)} want 14")
|
|
print(f"part1: {part1(input)} want 396")
|
|
print(f"part2 example: {part2(example)} want 34")
|
|
print(f"part2: {part2(input)} want 1200")
|