day 10 much faster fill with numpy

main
magical 2023-12-10 07:37:50 +00:00
parent 3b5b9f3839
commit 55158903e6
1 changed files with 21 additions and 25 deletions

View File

@ -64,7 +64,9 @@ def find_loop(grid, start):
def enclosedby(grid, points):
# upsample by 3x3
fill = [[0]*(X*3) for _ in range(Y*3)]
import numpy
fill = numpy.zeros((Y*3,X*3+1), dtype='uint8')
#fill = [[0]*(X*3) for _ in range(Y*3)]
for i,j in points:
d = grid[i,j]
if d == N|S: t=[[0,1,0],[0,1,0],[0,1,0]]
@ -76,7 +78,7 @@ def enclosedby(grid, points):
else: raise Exception("invalid d=%d at (%s,%s)" % (d, i, j))
for k in range(3):
for l in range(3):
fill[i*3+k][j*3+l] = t[k][l]
fill[i*3+k, j*3+l] = t[k][l]
def draw(fill):
for row in fill:
@ -86,39 +88,33 @@ def enclosedby(grid, points):
# fill edges
for i in range(Y*3):
if fill[i][ 0 ] == 0: fill[i][ 0 ] = 2
if fill[i][X*3-1] == 0: fill[i][X*3-1] = 2
if fill[i, 0 ] == 0: fill[i, 0 ] = 2
if fill[i, X*3-1] == 0: fill[i, X*3-1] = 2
for j in range(X*3):
if fill[ 0 ][j] == 0: fill[ 0 ][j] = 2
if fill[Y*3-1][j] == 0: fill[Y*3-1][j] = 2
if fill[ 0 , j] == 0: fill[ 0 , j] = 2
if fill[Y*3-1, j] == 0: fill[Y*3-1, j] = 2
# flood fill
next = {}
def set(i,j):
if 0 <= i < Y*3 and 0 <= j < X*3:
if fill[i][j] == 0:
next[i,j] = 2
while True:
changed = True
while changed:
#draw(fill)
next.clear()
changed = False
for i in range(Y*3):
for j in range(X*3):
if fill[i][j] == 2:
set(i-1,j)
set(i+1,j)
set(i,j-1)
set(i,j+1)
if next:
for (i,j),c in next.items():
fill[i][j] = c
continue
break
f = (fill[i] == 2)
f = numpy.roll(f, 1) | numpy.roll(f, -1)
if i > 0: f |= (fill[i-1] == 2)
if i < Y*3-1: f |= (fill[i+1] == 2)
f[-1] = False
f &= (fill[i] == 0)
if f.any():
fill[i, f] = 2
changed = True
draw(fill)
# downsample
inside = []
for i,j in grid:
f = [fill[i*3+k][j*3+l]==0 for k in range(3) for l in range(3)]
f = [fill[i*3+k, j*3+l]==0 for k in range(3) for l in range(3)]
if all(f):
inside.append((i,j))