From 55158903e6d52cda228f1f233c09878a302d9ccc Mon Sep 17 00:00:00 2001 From: Andrew Ekstedt Date: Sun, 10 Dec 2023 07:37:50 +0000 Subject: [PATCH] day 10 much faster fill with numpy --- day10/sol.py | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/day10/sol.py b/day10/sol.py index 137f617..9cb6545 100644 --- a/day10/sol.py +++ b/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))