day 12, knowing what part1 has built, part2 was longer than expected

This commit is contained in:
setop 2024-12-13 00:01:42 +01:00
parent 38f158b30d
commit ac5746a2c9
1 changed files with 56 additions and 0 deletions

56
d12/run.py Normal file
View File

@ -0,0 +1,56 @@
import sys
from grid import *
G = [list(l) for l in sys.stdin.read().strip().split("\n")]
def build_zone(G, x:int, y:int, zone:set[tuple[int,int]]):
zone.add((x, y))
v = get_in_grid(G, x, y)
for dx, dy in MOVE4:
xn = x +dx
yn = y + dy
if (xn, yn) not in zone:
if get_in_grid(G, xn, yn) == v:
build_zone(G, xn, yn, zone)
def perimeter(zone:set[tuple[int,int]]) -> int:
return sum (
(x+dx, y+dy) not in zone
for (x,y) in zone
for (dx, dy) in MOVE4)
def corners(zone:set[tuple[int,int]]) -> int:
corners = 0
for x,y in zone:
# define tile neighbourhood
[N,E,S,W] = [(x+dx,y+dy)in zone for (dx,dy) in MOVE4]
[SE,NW,NE,SW] = [(x+dx,y+dy)in zone for (dx,dy) in DIAG4]
# alone == no adjacent
if not (W or N or E or S): corners+=4
# touches zone on just 1 side
if (W+N+E+S==1): corners+=2
# outside corners
if (S and E and not N and not W): corners+=1
if (S and W and not N and not E): corners+=1
if (N and E and not S and not W): corners+=1
if (N and W and not S and not E): corners+=1
# inside corners
if (E and N and not NE): corners+=1
if (E and S and not SE): corners+=1
if (W and N and not NW): corners+=1
if (W and S and not SW): corners+=1
return corners
T1 = T2 = 0
checked = set()
W, H = grid_geom(G)
for y in range(W):
for x in range(H):
if (x,y) in checked: continue
zone = set()
build_zone(G, x, y, zone)
area = len(zone)
T1 += area * perimeter(zone)
T2 += area * corners(zone)
checked |= zone
print(T1, T2)