-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday08.py
68 lines (53 loc) · 1.53 KB
/
day08.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
from itertools import combinations
INPUT = 'input'
def main():
city = [parse(line) for line in lines()]
height, width = len(city), len(city[0])
def in_bounds(x, y): return 0 <= x < width and 0 <= y < height
antennas = find_antennas(city)
ans1 = len({
antinode
for ants in antennas.values()
for pair in combinations(ants, 2)
for antinode in calc_antinodes(*pair)
if in_bounds(*antinode)})
ans2 = len({
antinode
for ants in antennas.values()
for pair in combinations(ants, 2)
for antinode in calc_more_antinodes(*pair, in_bounds)})
print(f'Part 1: {ans1}\nPart 2: {ans2}')
def calc_more_antinodes(antenna1, antenna2, filter):
x1, y1 = antenna1
x2, y2 = antenna2
dx = x2 - x1
dy = y2 - y1
x, y = antenna1
while filter(x, y):
yield (x, y)
x += dx
y += dy
x, y = antenna1
while filter(x, y):
yield (x, y)
x -= dx
y -= dy
def calc_antinodes(antenna1, antenna2):
x1, y1 = antenna1
x2, y2 = antenna2
dx = x2 - x1
dy = y2 - y1
return (x2 + dx, y2 + dy), (x1 - dx, y1 - dy)
def find_antennas(map):
antennas = {}
for y, row in enumerate(map):
for x, char in enumerate(row):
if char != '.':
antennas[char] = antennas.get(char, []) + [(x, y)]
return antennas
def parse(line):
return line
def lines(): return read().splitlines()
def read():
return open(f'./input/2024/day08/{INPUT}.txt').read().strip()
main()