Day 14 - Advent of Code 2022
Working solutions for the day 14 puzzles.
Part One
""" day_14_01.py """
# usage: python3 day_14_01.py < input
import sys
def parse(data):
""" calculate scan from input data """
paths = [path.split(' -> ') for path in data.splitlines()]
paths = [[list(map(int, pt.split(','))) for pt in path]
for path in paths]
output = {}
for path in paths:
for index, _ in enumerate(path[:-1]):
x1, y1 = path[index]
x2, y2 = path[index + 1]
dx, dy = (x2 > x1) - (x2 < x1), (y2 > y1) - (y2 < y1)
output[x1, y1] = '#'
while (x1, y1) != (x2, y2):
x1, y1 = x1 + dx, y1 + dy
output[x1, y1] = '#'
return output
def drop_sand(start, data):
""" drop unit of sand from start in scan data """
def check(pos, delta):
""" get object at pos + delta """
x, y = pos
dx, dy = delta
return data.get((x + dx, y + dy), '.')
x, y = start
while True:
if y == data['limit']:
return None
if check((x, y), (0, 1)) == '.':
y = y + 1
elif check((x, y), (-1, 1)) == '.':
x, y = x - 1, y + 1
elif check((x, y), (1, 1)) == '.':
x, y = x + 1, y + 1
else:
return x, y
scan = parse(sys.stdin.read())
scan['limit'] = max([y for _, y in scan])
units = 0
while (rest := drop_sand((500, 0), scan)) is not None:
scan[rest] = 'O'
units += 1
print(units)
Part Two
""" day_14_02.py """
# usage: python3 day_14_02.py < input
import sys
def parse(data):
""" calculate scan from input data """
paths = [path.split(' -> ') for path in data.splitlines()]
paths = [[list(map(int, pt.split(','))) for pt in path]
for path in paths]
output = {}
for path in paths:
for index, _ in enumerate(path[:-1]):
x1, y1 = path[index]
x2, y2 = path[index + 1]
dx, dy = (x2 > x1) - (x2 < x1), (y2 > y1) - (y2 < y1)
output[x1, y1] = '#'
while (x1, y1) != (x2, y2):
x1, y1 = x1 + dx, y1 + dy
output[x1, y1] = '#'
return output
def drop_sand(start, data):
""" drop unit of sand from start in scan data """
def check(pos, delta):
""" get object at pos + delta """
x, y = pos
dx, dy = delta
if y + dy == data['limit'] + 2:
return '#'
return data.get((x + dx, y + dy), '.')
x, y = start
while True:
if check((x, y), (0, 1)) == '.':
y = y + 1
elif check((x, y), (-1, 1)) == '.':
x, y = x - 1, y + 1
elif check((x, y), (1, 1)) == '.':
x, y = x + 1, y + 1
else:
return x, y
scan = parse(sys.stdin.read())
scan['limit'] = max([y for _, y in scan])
units = 1
while (rest := drop_sand((500, 0), scan)) != (500, 0):
scan[rest] = 'O'
units += 1
print(units)