advent-of-code/2024/12/two.py
2024-12-25 12:59:49 +01:00

137 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import sys
input_file = sys.argv[1]
with open(input_file) as fd:
lines = [line.rstrip() for line in fd.readlines()]
height = len(lines)
width = len(lines[0])
visited: set[tuple[int, int]] = set()
directions = [
(0, 1),
(0, -1),
(1, 0),
(-1, 0),
]
def get_region(
pos: tuple[int, int], region: set[tuple[int, int]]
) -> set[tuple[int, int]]:
region.add(pos)
i, j = pos
ochar = lines[i][j]
for direction in directions:
i, j = pos[0] + direction[0], pos[1] + direction[1]
if i not in range(height) or j not in range(width):
continue
if (i, j) in region:
continue
char = lines[i][j]
if char != ochar:
continue
region |= get_region((i, j), region)
return region
# def get_sides(region: set[tuple[int, int]]) -> int:
# peri = 0
# for axis in (0, 1):
# oaxis = 0 if axis else 1
# iss = set([pos[axis] for pos in region])
# sta: set[int] = set()
# sto: set[int] = set()
# for i in iss:
# line = [pos[oaxis] for pos in region if pos[axis] == i]
# line.sort()
# last_j = None
# for j in line:
# if last_j is None:
# sta.add(j)
# elif last_j == j - 1:
# pass
# else:
# sta.add(j)
# sto.add(last_j)
# last_j = j
# if last_j is not None:
# sto.add(last_j)
# peri += len(sta) + len(sto)
# return peri
def get_perimeter(region: set[tuple[int, int]]) -> int:
peri = 0
for axis in (0, 1):
oaxis = 0 if axis else 1
iss = set([pos[axis] for pos in region])
for dire in (-1, 1):
print(47, axis, dire, iss, peri)
for i in iss:
oi = i + dire
line = [pos[oaxis] for pos in region if pos[axis] == i]
line.sort()
# last_j = None
for j in line:
if not axis:
opos = oi, j
else:
opos = j, oi
if opos in region:
continue
peri += 1
return peri
def get_sides(region: set[tuple[int, int]]) -> int:
peri = 0
for axis in (0, 1):
oaxis = 0 if axis else 1
iss = set([pos[axis] for pos in region])
for dire in (-1, 1):
print(47, axis, dire, iss, peri)
for i in iss:
oi = i + dire
line = [pos[oaxis] for pos in region if pos[axis] == i]
line.sort()
last_j = None
for j in line:
if not axis:
opos = oi, j
else:
opos = j, oi
if opos in region:
last_j = None
continue
if last_j == j - 1:
pass
else:
peri += 1
last_j = j
return peri
tprice = 0
for i in range(height):
for j in range(width):
pos = i, j
if pos in visited:
continue
region = get_region(pos, set())
visited |= region
area = len(region)
sides = get_sides(region)
price = area * sides
tprice += price
char = lines[i][j]
print(f"{char}: {area} × {sides} = {price}$")
print(tprice)