[WIP] Terrible 2018 Day 17

This commit is contained in:
Luke Hubmayer-Werner 2018-12-17 20:18:23 +10:30
parent 8b3b2d3e72
commit ba4065cc1a
1 changed files with 48 additions and 34 deletions

View File

@ -16,73 +16,87 @@ Ymax = [int(re.findall(r'y=(?:\d+\.\.)?(\d+)', d)[0]) for d in data]
y_min = min(Ymin) y_min = min(Ymin)
y_max = max(Ymax) y_max = max(Ymax)
x_max = 700 x_min = min(Xmin) - 1
x_max = 700 - x_min
init_grid = np.zeros((x_max, y_max), dtype=np.int64) # 0 = Sand, 1 = Clay, 2 = water init_grid = np.zeros((x_max, y_max+1), dtype=np.int64) # 0 = Sand, 1 = Clay, 2 = water, -1 = running water
spring = [500, 0] spring = [500-x_min, 0]
for xmin, xmax, ymin, ymax in zip(Xmin, Xmax, Ymin, Ymax): for xmin, xmax, ymin, ymax in zip(Xmin, Xmax, Ymin, Ymax):
init_grid[xmin:xmax+1, ymin:ymax+1] = 1 init_grid[xmin-x_min:xmax+1-x_min, ymin:ymax+1] = 1
grid = init_grid.copy() grid = init_grid.copy()
def drop_water(source=spring):
def drop_water(source=spring, skip_cliffs=set()):
# TODO: The exit condition on this is borked and it will probably run forever. Killing it after like a minute and then running the things at the end gives the right answers.
# I'll probably revisit this properly later
x, y = source x, y = source
print('Dropping water from', source) # print('Dropping water from', source)
surface = grid[x, y:].argmax() surface = (grid[x, y:] > 0).argmax()
if surface == 0: if surface == 0:
if (grid[x, y-1:] > 0).argmax() == 0:
grid[x, y:] = -1
return False return False
# raise ValueError('Out of bounds') # raise ValueError('Out of bounds')
surface_y = surface + y - 1 surface_y = surface + y
grid[x, y:surface_y] = -1
# Find walls left and right # Find walls left and right
wall_left = (grid[x:0:-1, surface_y] > 0).argmax() wall_left = (grid[x:0:-1, surface_y-1] > 0).argmax()
wall_right = (grid[x:, surface_y] > 0).argmax() wall_right = (grid[x:, surface_y-1] > 0).argmax()
if wall_left: if wall_left:
left_x = x - wall_left + 1 left_x = x - wall_left + 1
cliff = (grid[x:left_x-1:-1, surface_y + 1] == 0).argmax() cliff = (grid[x:left_x-1:-1, surface_y] <= 0).argmax()
if cliff: if cliff:
print('Found left wall but cliff present')
wall_left = False wall_left = False
if wall_right: if wall_right:
right_x = x + wall_right #- 1 right_x = x + wall_right #- 1
cliff = (grid[x:right_x, surface_y+1] == 0).argmax() cliff = (grid[x:right_x, surface_y] <= 0).argmax()
if cliff: if cliff:
print('Found right wall but cliff present')
wall_right = False wall_right = False
if wall_right and wall_left: if wall_right and wall_left:
# Fill level of basin # Fill level of basin
grid[left_x:right_x, surface_y] = 2 grid[left_x:right_x, surface_y-1] = 2
return True return True
sub_returns = False
cliffs = set()
if not wall_left: if not wall_left:
cliff = (grid[x:0:-1, surface_y+1] == 0).argmax() cliff = int((grid[x:0:-1, surface_y] <= 0).argmax())
if cliff: grid[x-cliff:x, surface_y-1] = -1
# Drop off the left if wall_right:
sub_returns |= drop_water((x - cliff, surface_y)) grid[x:right_x, surface_y - 1] = -1
if cliff and (cliff not in skip_cliffs):
cliffs.add((x - cliff, surface_y))
if not wall_right: if not wall_right:
cliff = (grid[x:, surface_y+1] == 0).argmax() cliff = int((grid[x:, surface_y] <= 0).argmax())
if cliff: grid[x:x+cliff+1, surface_y-1] = -1
# Drop off the right if wall_left:
sub_returns |= drop_water((x + cliff, surface_y)) grid[left_x:x, surface_y-1] = -1
if cliff and (cliff not in skip_cliffs):
return sub_returns cliffs.add((x + cliff, surface_y))
succeeded = False
while sum([drop_water(c) for c in cliffs]):
succeeded = True
return succeeded
def visualize(): def visualize():
vis_rows = [] vis_rows = []
for row in range(y_max): for row in range(y_max+1):
vis_rows.append(''.join([('.', '#', '~')[grid[col, row]] for col in range(x_max)])) vis_rows.append(''.join([('.', '#', '~', '|')[grid[col, row]] for col in range(x_max)]))
with open('day17-vis', 'w') as file: with open('day17-vis', 'w') as file:
file.write('\n'.join(vis_rows)) file.write('\n'.join(vis_rows))
# arr is all clay shelves import sys
sys.setrecursionlimit(10000)
# drop_water((502, 35)) while drop_water():
pass
print((grid==2).sum() + (grid==-1).sum() - y_min) # Part 1
# 14572 low print((grid==2).sum()) # Part 2
# 15414 low visualize()
# 23233 low ??????