Day 16 - Advent of Code 2023
Working solutions for the day 16 puzzles.
Part One
""" day_16_01.py """
# usage: python3 day_16_01.py < input
import sys
data = sys.stdin.read()
width = data.index('\n')
height = len(data) // (width + 1)
device = [i for i in data if i != '\n']
def exited(u):
""" left device """
return not (0 <= u[0] < height and 0 <= u[1] < width)
visited = []
beams = [[(0, -1), (0, 1)]]
while beams:
add = []
delete = []
for i, (pos, heading) in enumerate(beams):
next_pos = pos[0] + heading[0], pos[1] + heading[1]
if exited(next_pos) or [next_pos, heading] in visited:
delete.append(i)
continue
visited.append([next_pos, heading])
beams[i][0] = next_pos
tile = device[next_pos[0] * width + next_pos[1]]
if tile == '|' and heading[0] == 0:
beams[i][1] = (-1, 0)
add.append([next_pos, (1, 0)])
if tile == '-' and heading[1] == 0:
beams[i][1] = (0, -1)
add.append([next_pos, (0, 1)])
if tile == '/':
beams[i][1] = -heading[1], -heading[0]
if tile == '\\':
beams[i][1] = heading[1], heading[0]
beams = [beam for i, beam in enumerate(beams) if i not in delete]
beams.extend(add)
print(len({pos for pos, _ in visited}))
Part Two
""" day_16_02.py """
# usage: python3 day_16_02.py < input
import sys
data = sys.stdin.read()
width = data.index('\n')
height = len(data) // (width + 1)
device = [i for i in data if i != '\n']
def exited(u):
""" left device """
return not (0 <= u[0] < height and 0 <= u[1] < width)
entries = [[(-1, i), (1, 0)] for i in range(width)] + \
[[(i, width), (0, -1)] for i in range(height)] + \
[[(height, i), (-1, 0)] for i in range(width)] + \
[[(i, -1), (0, 1)] for i in range(height)]
answer = 0
for entry in entries:
visited = []
beams = [entry]
while beams:
add = []
delete = []
for i, (pos, heading) in enumerate(beams):
next_pos = pos[0] + heading[0], pos[1] + heading[1]
if exited(next_pos) or [next_pos, heading] in visited:
delete.append(i)
continue
visited.append([next_pos, heading])
beams[i][0] = next_pos
tile = device[next_pos[0] * width + next_pos[1]]
if tile == '|' and heading[0] == 0:
beams[i][1] = (-1, 0)
add.append([next_pos, (1, 0)])
if tile == '-' and heading[1] == 0:
beams[i][1] = (0, -1)
add.append([next_pos, (0, 1)])
if tile == '/':
beams[i][1] = -heading[1], -heading[0]
if tile == '\\':
beams[i][1] = heading[1], heading[0]
beams = [beam for i, beam in enumerate(beams) if i not in delete]
beams.extend(add)
answer = max(answer, len({pos for pos, _ in visited}))
print(answer)