-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12b.py
95 lines (85 loc) · 1.24 KB
/
12b.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
b=[*open('12')]
w=len(b)
b=''.join(s.strip()for s in b)
D=0,1,0,-1
fol=(
((-1,-1),(0,-1)),
((1,-1),(1,0)),
((1,1),(0,1)),
((-1,1),(-1,0))
)
def look(p,d):
x=p%w
y=p//w
v=b[p]
t=0
for i,(dx,dy) in enumerate(fol[d]):
xx=x+dx
yy=y+dy
if 0<=xx<w and 0<=yy<w:
vv=b[yy*w+xx]
else:
vv=-1
t+=(vv==v)*(1<<i)
return t
def mrc(p,d):
dx,dy=fol[d][0]
x=p%w+dx
y=p//w+dy
assert 0<=x<w and 0<=y<w
return y*w+x
def tr(p):
sp=p
sd=d=0
sides=0
ss={p}
i=0
while 1:
v=look(p,d)
if v in (0,1):
d=(d+1)%4
sides+=1
elif v==3:
p=mrc(p,d)
d=(d+3)%4
sides+=1
else:
p,_=m(p,d)
ss.add(p)
if p==sp and d==sd:
return sides,sum(ss)
def m(p,d):
x=p%w+D[d]
y=p//w+D[~d]
if 0<=x<w and 0<=y<w:
return y*w+x, b[y*w+x]
return 0,0
def fr(p,ps):
t=0
ps.add(p)
for d in 0,1,2,3:
np,v=m(p,d)
if np not in ps and v==b[p]:
t+=fr(np,ps)
if v!=b[p]:
t+=1
return t
done=set()
t=0
for i in range(w*w):
if i in done: continue
s=set()
p=fr(i,s)
edges=set()
sides=0
for p in s:
_,vv=m(p,3)
if b[i]==vv: continue
sides_,ss=tr(p)
if ss not in edges:
sides+=sides_
edges.add(ss)
print(b[i],i%w,i//w,len(s),sides)
done|=s
t+=len(s)*sides
print(t)