day 10 more efficient fill
i also tried getting rid of the 'next' dict and just keeping track of a boolean of whether we changed anything on each pass, but that made it slower somehow. cache effects i guess?main
parent
3ba6804013
commit
3b5b9f3839
65
day10/sol.py
65
day10/sol.py
|
@ -31,13 +31,6 @@ for i, row in enumerate(map):
|
||||||
|
|
||||||
#print(grid)
|
#print(grid)
|
||||||
|
|
||||||
def draw(grid):
|
|
||||||
y = max([i for i,j in grid.keys()])
|
|
||||||
x = max([j for i,j in grid.keys()])
|
|
||||||
for i in range(y+1):
|
|
||||||
print("".join(".+O"[grid[i,j]] if (i,j) in grid else "x" for j in range(x+1)))
|
|
||||||
print()
|
|
||||||
|
|
||||||
def find_loop(grid, start):
|
def find_loop(grid, start):
|
||||||
front = [(0,start)]
|
front = [(0,start)]
|
||||||
dist = {}
|
dist = {}
|
||||||
|
@ -71,57 +64,61 @@ def find_loop(grid, start):
|
||||||
|
|
||||||
def enclosedby(grid, points):
|
def enclosedby(grid, points):
|
||||||
# upsample by 3x3
|
# upsample by 3x3
|
||||||
fill = {}
|
fill = [[0]*(X*3) for _ in range(Y*3)]
|
||||||
for i,j in grid:
|
|
||||||
for k in range(3):
|
|
||||||
for l in range(3):
|
|
||||||
fill[i*3+k,j*3+l] = 0
|
|
||||||
#print(*sorted(fill.keys()), sep="\n")
|
|
||||||
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]]
|
||||||
elif d == N|W: t=[[0,1,0],[1,1,0],[0,0,0]]
|
elif d == N|W: t=[[0,1,0],[1,1,0],[0,0,0]]
|
||||||
elif d == N|E: t=[[0,1,0],[0,1,1],[0,0,0]]
|
elif d == N|E: t=[[0,1,0],[0,1,1],[0,0,0]]
|
||||||
elif d == S|W: t=[[0,0,0],[1,1,0],[0,1,0]]
|
elif d == S|W: t=[[0,0,0],[1,1,0],[0,1,0]]
|
||||||
elif d == S|E:t=[[0,0,0],[0,1,1],[0,1,0]]
|
elif d == S|E: t=[[0,0,0],[0,1,1],[0,1,0]]
|
||||||
elif d == E|W:t=[[0,0,0],[1,1,1],[0,0,0]]
|
elif d == E|W: t=[[0,0,0],[1,1,1],[0,0,0]]
|
||||||
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]
|
||||||
#print(fill)
|
|
||||||
|
def draw(fill):
|
||||||
|
for row in fill:
|
||||||
|
print("".join(".+O"[f] for f in row))
|
||||||
|
|
||||||
|
draw(fill)
|
||||||
|
|
||||||
# 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 = {}
|
||||||
def set(i,j):
|
def set(i,j):
|
||||||
if (i,j) in fill:
|
if 0 <= i < Y*3 and 0 <= j < X*3:
|
||||||
if fill[i,j] == 0:
|
if fill[i][j] == 0:
|
||||||
next[i,j] = 2
|
next[i,j] = 2
|
||||||
while True:
|
while True:
|
||||||
#draw(fill)
|
#draw(fill)
|
||||||
next = {}
|
next.clear()
|
||||||
for i,j in fill:
|
for i in range(Y*3):
|
||||||
if fill[i,j] == 2:
|
for j in range(X*3):
|
||||||
set(i-1,j)
|
if fill[i][j] == 2:
|
||||||
set(i+1,j)
|
set(i-1,j)
|
||||||
set(i,j-1)
|
set(i+1,j)
|
||||||
set(i,j+1)
|
set(i,j-1)
|
||||||
if not next:
|
set(i,j+1)
|
||||||
break
|
if next:
|
||||||
fill.update(next)
|
for (i,j),c in next.items():
|
||||||
|
fill[i][j] = c
|
||||||
|
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