···11+import fileinput
22+from functools import cache
33+44+def bfs(start):
55+ """Returns the number of splits from `start`."""
66+ splits = 0
77+ horizon = [start]
88+ seen = set()
99+ while horizon:
1010+ p = horizon.pop()
1111+ if p in seen:
1212+ continue
1313+ if p not in BOARD:
1414+ continue
1515+1616+ seen.add(p)
1717+ x, y = p
1818+1919+ if BOARD[p] == '^':
2020+ splits += 1
2121+ horizon.append((x - 1, y))
2222+ horizon.append((x + 1, y))
2323+ else:
2424+ horizon.append((x, y + 1))
2525+2626+ return splits
2727+2828+2929+@cache
3030+def dp(pos):
3131+ """Returns the number of ways a tachyon travels from x, y"""
3232+ x, y = pos
3333+ if pos not in BOARD:
3434+ return 1
3535+3636+ if BOARD[pos] == '^':
3737+ return dp((x - 1, y)) + dp((x + 1, y))
3838+3939+ return dp((x, y + 1))
4040+4141+4242+# Parse problem input.
4343+BOARD = {}
4444+START = None
4545+for y, line in enumerate(fileinput.input()):
4646+ for x, c in enumerate(line.strip()):
4747+ BOARD[x, y] = c
4848+ if c == 'S':
4949+ START = (x, y)
5050+5151+5252+# Solve problem.
5353+print("Part 1:", bfs(START))
5454+print("Part 2:", dp(START))