-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path09.py
48 lines (33 loc) · 1.08 KB
/
09.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
from collections import defaultdict
from math import prod
from utils import iter_lines, rinput
def parse(inp):
dct = defaultdict(lambda: 10)
for y, row in enumerate(iter_lines(inp)):
for x, val in enumerate(row):
dct[(x, y)] = int(val)
return dct
def neighbourhood(x, y):
yield from ((x, y - 1), (x, y + 1), (x - 1, y), (x + 1, y))
def get_low_points(hmap):
for coords, cell_height in hmap.copy().items():
if all(cell_height < hmap[adj] for adj in neighbourhood(*coords)):
yield coords, cell_height
def solve1(inp):
print(sum(h + 1 for _, h in get_low_points(parse(inp))))
def solve2(inp):
hmap = parse(inp)
basins = sorted(flood(hmap, coords) for coords, _ in get_low_points(hmap))
print(prod(basins[-3:]))
def flood(hmap, base):
q = [base]
basin = {base}
while q:
x, y = q.pop(0)
for adj in neighbourhood(x, y):
if hmap[adj] < 9 and adj not in basin:
q.append(adj)
basin.add(adj)
return len(basin)
solve1(rinput(9))
solve2(rinput(9))