2024-12-12 05:32:56 +00:00
|
|
|
import itertools
|
|
|
|
def solve(file):
|
|
|
|
grid = [l.strip() for l in file]
|
|
|
|
ny = len(grid)
|
|
|
|
nx = len(grid[0])
|
|
|
|
def get(p):
|
|
|
|
x,y = p
|
|
|
|
if 0 <= x < nx and 0 <= y < ny:
|
|
|
|
return grid[y][x]
|
|
|
|
return '.'
|
|
|
|
|
|
|
|
def flood(initial_point):
|
|
|
|
c = get(initial_point)
|
|
|
|
stack = [initial_point]
|
|
|
|
count = {} # set of points connected to x,y. value is the number of connected neighboring points
|
|
|
|
while stack:
|
|
|
|
p = stack.pop()
|
|
|
|
if p not in count:
|
|
|
|
count[p] = 0
|
|
|
|
x,y = p
|
|
|
|
for n in (x+1,y), (x-1,y), (x,y+1), (x,y-1):
|
|
|
|
if get(n) == c:
|
|
|
|
stack.append(n)
|
|
|
|
count[p] += 1
|
|
|
|
return count
|
|
|
|
|
|
|
|
points = lambda: itertools.product(range(nx), range(ny))
|
|
|
|
|
|
|
|
done = set() # set of points which have been counted as part of a shape
|
|
|
|
total = 0
|
2024-12-12 05:42:20 +00:00
|
|
|
total2 = 0
|
2024-12-12 05:32:56 +00:00
|
|
|
for p in points():
|
|
|
|
if p in done: continue
|
|
|
|
shape = flood(p)
|
|
|
|
done |= shape.keys()
|
|
|
|
area = len(shape)
|
|
|
|
perim = 0
|
|
|
|
for p,n in shape.items():
|
|
|
|
perim += 4-n
|
|
|
|
#print(get(p), area, perim)
|
|
|
|
total += area * perim
|
2024-12-12 05:42:20 +00:00
|
|
|
total2 += area * discount(shape)
|
2024-12-12 05:32:56 +00:00
|
|
|
|
|
|
|
print(total)
|
2024-12-12 05:42:20 +00:00
|
|
|
print(total2)
|
|
|
|
|
|
|
|
def discount(shape):
|
|
|
|
def sides(p):
|
|
|
|
x,y = p
|
|
|
|
s = 0
|
|
|
|
if (x+1,y) in shape: s += 1
|
|
|
|
if (x-1,y) in shape: s += 2
|
|
|
|
if (x,y+1) in shape: s += 4
|
|
|
|
if (x,y-1) in shape: s += 8
|
|
|
|
return s
|
|
|
|
|
|
|
|
# only count a side as free if the neighbor to the north or west
|
|
|
|
# does not have the same side free
|
|
|
|
perim = 0
|
|
|
|
for p in shape:
|
|
|
|
x,y = p
|
|
|
|
free = sides(p) ^ 15
|
|
|
|
if (x-1,y) in shape:
|
|
|
|
free &= sides((x-1,y))
|
|
|
|
if (x,y-1) in shape:
|
|
|
|
free &= sides((x,y-1))
|
|
|
|
perim += free.bit_count()
|
|
|
|
return perim
|
2024-12-12 05:32:56 +00:00
|
|
|
|
|
|
|
solve(open("sample4.in"))
|
|
|
|
solve(open("input"))
|