Solve 2018 day 17

This commit is contained in:
felixm 2024-07-14 15:28:50 -04:00
parent ab2e6f4ddb
commit b88326a7d1
2 changed files with 138 additions and 1 deletions

136
2018/d17.py Normal file
View File

@ -0,0 +1,136 @@
from lib import get_data, str_to_ints, add2
def above(p):
return add2(p, (0, -1))
def below(p):
return add2(p, (0, 1))
def right(p):
return add2(p, (1, 0))
def left(p):
return add2(p, (-1, 0))
def print2d(xs, ys=[], zs=[], cs=".#~|"):
xs, ys, zs = set(xs), set(ys), set(zs)
all = xs | ys | zs
x_min, x_max, y_min, y_max = 10**9, 0, 10**9, 0
for x, y in all:
x_min = min(x_min, x)
y_min = min(y_min, y)
x_max = max(x_max, x)
y_max = max(y_max, y)
for y in range(y_min, y_max + 1):
row = ""
for x in range(x_min, x_max + 1):
if (x, y) in xs:
row += cs[1]
elif (x, y) in ys:
row += cs[2]
elif (x, y) in zs:
row += cs[3]
else:
row += cs[0]
print(row)
def part_1(data):
sand = []
max_y = 0
min_y = 10**9
for line in data.splitlines():
line = line.strip()
a, b, c = str_to_ints(line)
if line.startswith("x"):
x = a
for y in range(b, c + 1):
max_y = max(max_y, y)
min_y = min(min_y, y)
sand.append((x, y))
elif line.startswith("y"):
y = a
max_y = max(max_y, y)
min_y = min(min_y, y)
for x in range(b, c + 1):
sand.append((x, y))
else:
assert False
# TODO: probably should use 2D array for better perf
sources = [(500, 0)]
water = set()
sand = set(sand)
water_rest = set()
while sources:
source = sources.pop()
current = below(source)
while current[1] <= max_y:
if current[1] < min_y:
current = below(current)
elif current in water_rest:
break
elif below(current) in sand or below(current) in water_rest:
water.add(current)
c = current
to_water_rest = [current]
left_sand, right_sand = False, False
while True:
c = right(c)
if c in sand:
right_sand = True
break
elif below(c) in sand or below(c) in water_rest:
water.add(c)
to_water_rest.append(c)
else:
# it's empty underneath
water.add(c)
sources.append(c)
break
c = current
while True:
c = left(c)
if c in sand:
left_sand = True
break
elif below(c) in sand or below(c) in water_rest:
water.add(c)
to_water_rest.append(c)
else:
# it's empty underneath
water.add(c)
sources.append(c)
break
if left_sand and right_sand:
sources.append(above(above(current)))
for w in to_water_rest:
water_rest.add(w)
break
else:
water.add(current)
current = below(current)
# print2d(sand, water_rest, water)
# print(sources)
# input()
current_water = len(water_rest | water)
print(current_water)
print(len(water_rest))
def main():
data = get_data(__file__)
part_1(data)
if __name__ == "__main__":
main()

View File

@ -105,7 +105,8 @@ written in Python.
- Day 14: 20:48 - Day 14: 20:48
- Day 15: 185:11 - Day 15: 185:11
- Day 16: 36:10 - Day 16: 36:10
- Day 17: 180:00
- Day 18:
# 2022 # 2022