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