day 12, knowing what part1 has built, part2 was longer than expected
This commit is contained in:
		
							
								
								
									
										56
									
								
								d12/run.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								d12/run.py
									
									
									
									
									
										Normal 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)
 | 
			
		||||
		Reference in New Issue
	
	Block a user