day 10 much faster fill with numpy
parent
3b5b9f3839
commit
55158903e6
46
day10/sol.py
46
day10/sol.py
|
@ -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))
|
||||
|
||||
|
|
Loading…
Reference in New Issue