-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path9.py
87 lines (69 loc) · 2.38 KB
/
9.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
INPUT_FILE = f"input/{__file__.split('.')[0].rstrip('b')}"
locations = []
def getInput():
with open(INPUT_FILE, 'r') as f:
return f.read().splitlines()
def partOne():
inp = getInput()
locations = []
# cheating by surrounding the matrix in 20s to avoid bounds errors
locations.append([20] * (len(inp[0]) + 2))
for line in inp:
locations.append([20] + list(map(int, list(line))) + [20])
locations.append([20] * (len(inp[0]) + 2))
risk = 0
for idx, row in enumerate(locations):
for idx2, val in enumerate(row):
if (val < locations[idx - 1][idx2] and val < locations[idx + 1][idx2] and
val < locations[idx][idx2 - 1] and val < locations[idx][idx2 + 1]):
risk += val + 1
return risk
def partTwo():
inp = getInput()
# cheating by surrounding the matrix in 20s to avoid bounds errors
locations.append([20] * (len(inp[0]) + 2))
for line in inp:
locations.append([20] + list(map(int, list(line))) + [20])
locations.append([20] * (len(inp[0]) + 2))
lowPoints = []
for idx, row in enumerate(locations):
for idx2, val in enumerate(row):
if (val < locations[idx - 1][idx2] and val < locations[idx + 1][idx2] and
val < locations[idx][idx2 - 1] and val < locations[idx][idx2 + 1]):
lowPoints.append([idx, idx2])
mult = 1
sizes = []
for point in lowPoints:
sizes.append(getBasinSize(point[0], point[1]))
sizes = sorted(sizes)[-3:]
for i in sizes:
mult *= i
return mult
# literally just bfs
def getBasinSize(point1, point2):
visited = []
queue = []
basinSize = 0
queue.append([point1, point2])
while len(queue) > 0:
s = queue.pop()
neighbors = getNeighbors(s)
for neighbor in neighbors:
if neighbor not in visited and locations[neighbor[0]][neighbor[1]] < 9:
basinSize += 1
visited.append(neighbor)
queue.append(neighbor)
return basinSize
def getNeighbors(point):
x, y = point
return [
[x + 1, y],
[x - 1, y],
[x, y + 1],
[x, y - 1]
]
if __name__ == "__main__":
one = partOne()
two = partTwo()
print(f"Part one: {one}")
print(f"Part two: {two}")