import lib EXAMPLE = r""" .|...\.... |.-.\..... .....|-... ........|. .......... .........\ ..../.\\.. .-.-/..|.. .|....-|.\ ..//.|.... """ NEW = { '.': { 'w': (0, -1, 'w'), 'e': (0, 1, 'e'), 's': (1, 0, 's'), 'n': (-1, 0, 'n'), }, '|': { 'w': [(1, 0, 's'), (-1, 0, 'n')], 'e': [(1, 0, 's'), (-1, 0, 'n')], 's': (1, 0, 's'), 'n': (-1, 0, 'n'), }, '-': { 's': [(0, -1, 'w'), (0, 1, 'e')], 'n': [(0, -1, 'w'), (0, 1, 'e')], 'e': (0, 1, 'e'), 'w': (0, -1, 'w'), }, '/': { 's': (0, -1, 'w'), 'n': (0, 1, 'e'), 'e': (-1, 0, 'n'), 'w': (1, 0, 's'), }, '\\': { 's': (0, 1, 'e'), 'n': (0, -1, 'w'), 'e': (1, 0, 's'), 'w': (-1, 0, 'n'), }, } def solve(lines: list[str], second=False): res = 0 g = list(map(list, lines)) rows = len(g) cols = len(g[0]) if not second: starts = [(0, 0, 'e')] else: starts = [(r, 0, 'e') for r in range(rows)] starts += [(r, cols - 1, 'w') for r in range(rows)] starts += [(0, c, 's') for c in range(cols)] starts += [(rows - 1, c, 'n') for c in range(cols)] for start in starts: visited = set() beams = [start] while beams: b = beams.pop() row, col, d = b visited.add((row, col, d)) f = g[row][col] new = NEW[f][d] if isinstance(new, tuple): r, c, nd = new nr = row + r nc = col + c if nr >= 0 and nc >= 0 and nr < rows and nc < cols: if not (nr, nc, nd) in visited: beams.append((nr, nc, nd)) else: for r, c, nd in new: nr = row + r nc = col + c if nr >= 0 and nc >= 0 and nr < rows and nc < cols: if not (nr, nc, nd) in visited: beams.append((nr, nc, nd)) v = set([(r, c) for (r, c, _) in list(visited)]) res = max(res, len(v)) return res def main(): lines = lib.str_to_lines_no_empty(EXAMPLE) print("Example 1:", solve(lines)) lines = lib.str_to_lines_no_empty(open("i16.txt").read()) print("Solution 1:", solve(lines)) lines = lib.str_to_lines_no_empty(EXAMPLE) print("Example 2:", solve(lines, True)) lines = lib.str_to_lines_no_empty(open("i16.txt").read()) print("Solution 2:", solve(lines, True)) if __name__ == "__main__": main()