62 lines
1.4 KiB
Python
62 lines
1.4 KiB
Python
from lib import get_data
|
|
from lib import Grid2D
|
|
from collections import defaultdict
|
|
from collections import deque
|
|
|
|
data = get_data(__file__)
|
|
|
|
DIRS = {
|
|
"N": (-1, 0),
|
|
"E": (0, 1),
|
|
"S": (1, 0),
|
|
"W": (0, -1),
|
|
}.values()
|
|
|
|
|
|
g = Grid2D(data)
|
|
cs = defaultdict(set)
|
|
for row in range(g.n_rows):
|
|
for col in range(g.n_cols):
|
|
c = g[(row, col)]
|
|
cs[c].add((row, col))
|
|
|
|
t1, t2 = 0, 0
|
|
for c, cs in cs.items():
|
|
while cs:
|
|
peri = 0
|
|
start = cs.pop()
|
|
seen = set()
|
|
queue = deque([start])
|
|
fences = set()
|
|
while queue:
|
|
pos = queue.popleft()
|
|
if pos in seen:
|
|
continue
|
|
seen.add(pos)
|
|
|
|
for d in DIRS:
|
|
nb = d[0] + pos[0], d[1] + pos[1]
|
|
if g.contains(nb) and g[nb] == c:
|
|
queue.append(nb)
|
|
cs.discard(nb)
|
|
else:
|
|
peri += 1
|
|
nb = tuple(list(nb) + [d])
|
|
fences.add(nb)
|
|
|
|
nfences = set()
|
|
for row, col, dir in fences:
|
|
for dr, dc in [(1, 0), (0, 1)]:
|
|
nr, nc = row + dr, col + dc
|
|
if (nr, nc, dir) in fences:
|
|
break
|
|
else:
|
|
nfences.add((row, col, dir))
|
|
|
|
c_area = len(seen)
|
|
t1 += c_area * peri
|
|
t2 += c_area * len(nfences)
|
|
|
|
print(t1)
|
|
print(t2)
|