-
Notifications
You must be signed in to change notification settings - Fork 0
/
a09.py
95 lines (71 loc) · 2.09 KB
/
a09.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
example = """
2199943210
3987894921
9856789892
8767896789
9899965678
""".strip()
f = open("input/09.input")
text = f.read().strip()
def parse(t):
return [[int(a) for a in line] for line in t.split("\n")]
def valid(x, y, cols, rows):
return x >= 0 and x < cols and y >= 0 and y < rows
def is_low_point(parsed, x, y):
rows = len(parsed)
cols = len(parsed[0])
for dy in [-1, 0, 1]:
for dx in [-1, 0, 1]:
if dy == dx == 0:
continue
pos_y = y + dy
pos_x = x + dx
if valid(pos_x, pos_y, cols, rows) and parsed[pos_y][pos_x] <= parsed[y][x]:
return False
return True
def part1(text):
parsed = parse(text)
rows = len(parsed)
cols = len(parsed[0])
lows = []
for y in range(rows):
for x in range(cols):
if is_low_point(parsed, x, y):
lows.append((x, y))
return len(lows) + sum(map(lambda xy: parsed[xy[1]][xy[0]], lows))
def find_basin(parsed, start):
rows = len(parsed)
cols = len(parsed[0])
visited = set([start])
queue = [start]
while len(queue) > 0:
x, y = queue.pop()
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
pos_y = y + dy
pos_x = x + dx
if valid(pos_x, pos_y, cols, rows) and parsed[pos_y][pos_x] < 9 and (pos_x, pos_y) not in visited:
visited.add((pos_x, pos_y))
queue.append((pos_x, pos_y))
return visited
def part2(text):
parsed = parse(text)
visited = set()
rows = len(parsed)
cols = len(parsed[0])
basins = []
for y in range(rows):
for x in range(cols):
node = (x, y)
if parsed[y][x] != 9 and node not in visited:
basin = find_basin(parsed, node)
visited |= basin
basins.append(len(basin))
basins.sort()
return basins[-1] * basins[-2] * basins[-3]
def main(text):
print("Part1:", part1(text))
print("Part2:", part2(text))
print("==== EXAMPLES ====")
main(example)
print("==== SOLUTION RESULT ====")
main(text)