Skip to content
advent of code 2023

day 16

the floor will be lava

approach

move uses a match statement to say which direction(s) a beam leaves a tile in: mirrors turn it clockwise or counter-clockwise depending on the mirror and the axis, and splitters hit side-on return two directions. beams follows beams with a stack and records, for each cell, the directions it has been crossed in, so a beam that repeats a cell and direction stops.

part 1 is the number of cells reached from the top-left heading right. part 2 tries every edge cell heading inward and takes the maximum.

the trick

remember (cell, direction) pairs so looping beams stop on their own.

python
while s:
    r, c, dr, dc = s.pop()
    for ndr, ndc in  move(dr, dc, grid[r][c]):
        if not 0 <= (nr := r + ndr) < len(grid):
            continue
        if not 0 <= (nc := c + ndc) < len(grid[0]):
            continue
        if (nr, nc) in d and (ndr, ndc) in d[(nr, nc)]:
            continue
        s.append((nr, nc, ndr, ndc))
        d[(nr, nc)].append((ndr, ndc))