12.1, 12.2 python fast
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
from collections import defaultdict
|
||||
d4 = [(-1, 0), (0, 1), (1, 0), (0, -1)]
|
||||
|
||||
|
||||
|
||||
def make_field(data):
|
||||
data = data.strip().split("\n")
|
||||
data = ['.'*len(data[0])] + data + ['.'*len(data[0])]
|
||||
data = ['.'+x+'.' for x in data]
|
||||
return data
|
||||
|
||||
def regions(data, collect=len):
|
||||
def walk(i, j, c):
|
||||
nonlocal borders
|
||||
if data[i][j]!=c:
|
||||
return
|
||||
if (i, j) not in region:
|
||||
region.add((i, j))
|
||||
for di, dj in d4:
|
||||
if (i+di, j+dj) not in region:
|
||||
borders += 1
|
||||
else:
|
||||
borders -= 1
|
||||
for di, dj in d4:
|
||||
walk(i+di, j+dj, c)
|
||||
unmarked = {(i, j) for i in range(1, len(data)-1) for j in range(1, len(data)-1)}
|
||||
regions = []
|
||||
while unmarked:
|
||||
i, j = next(iter(unmarked))
|
||||
region = set()
|
||||
borders = 0
|
||||
walk(i, j, data[i][j])
|
||||
regions.append((collect(region), borders))
|
||||
unmarked -= region
|
||||
return regions
|
||||
|
||||
def sides(data):
|
||||
for region, _ in regions(data, collect=lambda x: x):
|
||||
net = defaultdict(lambda: [0,0,0,0])
|
||||
for i, j in region:
|
||||
net[(i, j)][3] = 1
|
||||
net[(i+1, j)][0] = 1
|
||||
net[(i, j+1)][2] = 1
|
||||
net[(i+1, j+1)][1] = 1
|
||||
net2 = defaultdict(list)
|
||||
for (i, j), (a,b,c,d) in net.items():
|
||||
if a!=d:
|
||||
net2[(i, j)].append((i, j+1))
|
||||
if a!=b:
|
||||
net2[(i, j)].append((i-1, j))
|
||||
if b!=c:
|
||||
net2[(i, j)].append((i, j-1))
|
||||
if c!=d:
|
||||
net2[(i, j)].append((i+1, j))
|
||||
borders = 0
|
||||
while net2:
|
||||
s = min(net2)
|
||||
p = s
|
||||
n = net2[s][0]
|
||||
net2[s].remove(n)
|
||||
|
||||
borders += 1
|
||||
while not n==s:
|
||||
pi, pj = p
|
||||
ni, nj = n
|
||||
net2[n].remove(p)
|
||||
if len(net2[n])!=1:
|
||||
a = (ni + nj-pj, nj + ni-pi)
|
||||
else:
|
||||
a = (ai, aj) = net2[n][0]
|
||||
net2[n].remove(a)
|
||||
if len(net2[n])==0:
|
||||
del net2[n]
|
||||
if not((abs(ni-pi)==abs(ai-ni)==1) or (abs(nj-pj)==abs(aj-nj)==1)):
|
||||
borders += 1
|
||||
p = n
|
||||
n = a
|
||||
del net2[n]
|
||||
yield len(region), borders
|
||||
|
||||
|
||||
data = open("input.txt").read()
|
||||
|
||||
print(sum(a*b for a, b in regions(make_field(data))))
|
||||
|
||||
print(sum(a*b for a, b in sides(make_field(data))))
|
||||
|
||||
import cProfile
|
||||
cProfile.run('sum(a*b for a, b in sides(make_field(data)))')
|
||||
Reference in New Issue
Block a user