From ac5746a2c9b86142d080da2a4961ead577f1db68 Mon Sep 17 00:00:00 2001 From: setop Date: Fri, 13 Dec 2024 00:01:42 +0100 Subject: [PATCH] day 12, knowing what part1 has built, part2 was longer than expected --- d12/run.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 d12/run.py diff --git a/d12/run.py b/d12/run.py new file mode 100644 index 0000000..d1062cd --- /dev/null +++ b/d12/run.py @@ -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)