···11+import fileinput
22+from utils import Point, DIRS, N, E, S, W
33+44+55+# Parse problem input.
66+GRID = {}
77+for y, line in enumerate(fileinput.input()):
88+ for x, c in enumerate(line.strip()):
99+ GRID[Point(x, y)] = c
1010+1111+MAX_X = x
1212+MAX_Y = y
1313+1414+1515+def simulate_light(grid, start, initial_d):
1616+ photons = [(start, initial_d)]
1717+ seen = set()
1818+ while photons:
1919+ photon, d = photons.pop()
2020+2121+ if photon not in grid:
2222+ continue
2323+2424+ if (photon, d) in seen:
2525+ continue
2626+2727+ seen.add((photon, d))
2828+2929+ if grid[photon] == '.':
3030+ photons.append((photon + d, d))
3131+ elif grid[photon] == '/':
3232+ nd = [W, E, S, N][[N, S, E, W].index(d)]
3333+ photons.append((photon + nd, nd))
3434+ elif grid[photon] == '\\':
3535+ nd = [E, W, N, S][[N, S, E, W].index(d)]
3636+ photons.append((photon + nd, nd))
3737+ elif grid[photon] == '|':
3838+ if d in (N, S):
3939+ photons.append((photon + d, d))
4040+ else:
4141+ photons.append((photon + N, N))
4242+ photons.append((photon + S, S))
4343+ elif grid[photon] == '-':
4444+ if d in (E, W):
4545+ photons.append((photon + d, d))
4646+ else:
4747+ photons.append((photon + E, E))
4848+ photons.append((photon + W, W))
4949+5050+ return len(set(p for p, d in seen))
5151+5252+5353+def part_2_starts(grid):
5454+ for x in range(MAX_X):
5555+ yield Point(x, 0), N
5656+ yield Point(x, MAX_Y - 1), S
5757+5858+ for y in range(MAX_Y):
5959+ yield Point(0, y), E
6060+ yield Point(MAX_X - 1, y), W
6161+6262+6363+print("Part 1:", simulate_light(GRID, Point(0, 0), E))
6464+print("Part 2:", max(simulate_light(GRID, p, d) for p, d in part_2_starts(GRID)))