92 lines
2.6 KiB
Python
Executable File
92 lines
2.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import cv2 as cv
|
|
|
|
from useful import *
|
|
|
|
bit = {(-1, 0): 8,
|
|
(1, 0): 4,
|
|
(0, -1): 2,
|
|
(0, 1): 1}
|
|
udlr = {'|': 12, # 1<<3 (u) + 1<<2 (d)
|
|
'J': 10,
|
|
'L': 9,
|
|
'7': 6,
|
|
'F': 5,
|
|
'-': 3,
|
|
'.': 0,
|
|
'S': 65535}
|
|
|
|
cs = [[udlr[c] for c in l] for l in lines(open(0))]
|
|
ca = np.pad(np.array(cs, dtype=int), 1)
|
|
visited = np.zeros(ca.shape, dtype=int)
|
|
pos = next(zip(*np.nonzero(ca == 65535)))
|
|
|
|
def sub(a, b):
|
|
return (a[0] - b[0], a[1] - b[1])
|
|
|
|
def neg(a):
|
|
return (-a[0], -a[1])
|
|
|
|
def cango(origin, step):
|
|
test = sub(origin, step) # note: subtraction to match udlr
|
|
return ca[test] & bit[step] and ca[origin] & bit[neg(step)] and not visited[test]
|
|
|
|
def draw(uptofour, linger=16): # different colors:
|
|
# blank, faded, pipe, special
|
|
palette = [(x & 255, x >> 8 & 255, x >> 16)
|
|
for x in [0x7f9aa5, 0x74878f, 0x433c34, 0xae8c67]]
|
|
colored = np.transpose(np.asarray(np.vectorize(
|
|
lambda x: palette[x])(
|
|
uptofour[3:-3,3:-3])), axes=(1, 2, 0)).astype('uint8')
|
|
zoom = 840 // max(colored.shape[:2])
|
|
cv.imshow('pipes', np.kron(colored, np.ones((zoom, zoom, 1), dtype='uint8')))
|
|
cv.waitKey(linger)
|
|
|
|
grill = ((np.kron(np.ones(ca.shape), np.asarray([[0, 8, 0],
|
|
[2, 15, 1],
|
|
[0, 4, 0]])).astype(int) &
|
|
np.kron(ca, np.ones((3, 3))).astype(int)) > 0).astype('uint8')
|
|
|
|
canvas = np.kron(1 + 2 * (ca == 65535), np.ones((3, 3))).astype('uint8') * grill # colorize animal
|
|
|
|
draw(canvas, linger=2000)
|
|
|
|
def drawvisit(y, x):
|
|
canvas[y*3:y*3+3,x*3:x*3+3] *= 2
|
|
canvas[y*3:y*3+3,x*3:x*3+3] %= 4
|
|
if not time % 69: # about 100 unique frames for us
|
|
draw(canvas)
|
|
|
|
time = 1
|
|
while True:
|
|
visited[pos] = time
|
|
drawvisit(*pos)
|
|
time += 1
|
|
goto = [s for s in bit.keys() if cango(pos, s)] # should give one result except in the beginning
|
|
if not goto:
|
|
break
|
|
pos = sub(pos, goto[0])
|
|
print(time // 2)
|
|
|
|
fillvas = np.kron(2 * (visited > 0), np.ones((3, 3))).astype('uint8') * grill # 2 if part of loop...
|
|
mask = np.pad(fillvas, (1,1))
|
|
for color in [4, 3, 2, 1]: # outside: 4, inside: 3
|
|
try:
|
|
empty = next(zip(*np.nonzero(fillvas == 0)))
|
|
except StopIteration: # all filled!
|
|
break
|
|
cv.floodFill(fillvas, mask, empty, color)
|
|
#assert color == 2
|
|
smallvas = fillvas[1::3,1::3]
|
|
print(len(np.where(smallvas == 3)[0]))
|
|
|
|
# also paint regardless if part of loop
|
|
fillvas *= (1 - grill)
|
|
fillvas |= (2 * grill)
|
|
fillvas %= 4
|
|
|
|
draw(canvas, linger=2000)
|
|
|
|
draw(fillvas, linger=0)
|