advent_of_code/2021/9/9_2.py

132 lines
3.3 KiB
Python
Raw Permalink Normal View History

2021-12-09 18:15:37 +01:00
#!/usr/bin/env python
# 2021 - Advent Of Code - 9 part 2
def parse_file(file):
hmap = []
2022-04-05 13:27:24 +02:00
with open(file, encoding="utf-8") as f:
2021-12-09 18:15:37 +01:00
for line in f.readlines():
linemap = []
for n in line.strip():
linemap.append(int(n))
hmap.append(linemap)
return hmap
def find_lowpoints(hmap):
2022-04-05 14:02:10 +02:00
# pylint: disable=R0912
2021-12-09 18:15:37 +01:00
lpoints = []
# first line
x = 0
y = 0
if hmap[y][x] < hmap[y][x + 1] and hmap[y][x] < hmap[y + 1][x]:
lpoints.append([x, y])
for x in range(1, len(hmap[y]) - 1):
v = hmap[y][x]
if v < hmap[y][x - 1] and v < hmap[y][x + 1] and v < hmap[y + 1][x]:
lpoints.append([x, y])
x = len(hmap[y]) - 1
if hmap[y][x] < hmap[y][x - 1] and hmap[y][x] < hmap[y + 1][x]:
lpoints.append([x, y])
# middle lines
for y in range(1, len(hmap) - 1):
x = 0
if hmap[y][x] < hmap[y][x + 1] and hmap[y][x] < hmap[y - 1][x] and hmap[y][x] < hmap[y + 1][x]:
lpoints.append([x, y])
for x in range(1, len(hmap[y]) - 1):
v = hmap[y][x]
if v < hmap[y][x - 1] and v < hmap[y][x + 1] and v < hmap[y - 1][x] and v < hmap[y + 1][x]:
lpoints.append([x, y])
x = len(hmap[y]) - 1
if hmap[y][x] < hmap[y][x - 1] and hmap[y][x] < hmap[y - 1][x] and hmap[y][x] < hmap[y + 1][x]:
lpoints.append([x, y])
# last line
y = len(hmap) - 1
x = 0
if hmap[y][x] < hmap[y][x + 1] and hmap[y][x] < hmap[y - 1][x]:
lpoints.append([x, y])
for x in range(1, len(hmap[y]) - 1):
v = hmap[y][x]
if v < hmap[y][x - 1] and v < hmap[y][x + 1] and v < hmap[y - 1][x]:
lpoints.append([x, y])
x = len(hmap[y]) - 1
if hmap[y][x] < hmap[y][x - 1] and hmap[y][x] < hmap[y - 1][x]:
lpoints.append([x, y])
return lpoints
def find_basin(hmap, bpoints, point):
bpoints.append(point)
# print(f'bpoints: {bpoints}')
x = point[0]
y = point[1]
# halt if edge, already in list or value is 9
# up
if y > 0:
if hmap[y-1][x] != 9:
if [x, y-1] not in bpoints:
find_basin(hmap, bpoints, [x, y-1])
# down
if y < len(hmap) - 1:
if hmap[y+1][x] != 9:
if [x, y+1] not in bpoints:
find_basin(hmap, bpoints, [x, y+1])
# left
if x > 0:
if hmap[y][x-1] != 9:
if [x-1, y] not in bpoints:
find_basin(hmap, bpoints, [x-1, y])
# right
if x < len(hmap[y]) - 1:
if hmap[y][x+1] != 9:
if [x+1, y] not in bpoints:
find_basin(hmap, bpoints, [x+1, y])
return bpoints
# heightmap = parse_file('input_example.txt')
heightmap = parse_file('input.txt')
# print_hmap(heightmap)
low_points = find_lowpoints(heightmap)
risk_levels = 0
basins = []
for p in low_points:
basins_points = []
find_basin(heightmap, basins_points, p)
basins.append(basins_points)
sizes = [0] * len(basins)
i = 0
for b in basins:
size = 0
for p in b:
size += 1
sizes[i] = size
i += 1
# 3 biggest basins
biggest_basins = sorted(zip(sizes, basins))[-3:]
product = 1
for s, b in biggest_basins:
print(f'basin size: {s}')
product *= s
print(f'product: {product}')