57 lines
1.7 KiB
Python
57 lines
1.7 KiB
Python
|
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)
|