|
|
@@ -0,0 +1,44 @@ |
|
|
|
def loop(p, drx): |
|
|
|
p += drx |
|
|
|
if p not in grid: |
|
|
|
p -= drx * (H if drx.imag else W) |
|
|
|
return p |
|
|
|
|
|
|
|
|
|
|
|
def blizzards(n, cache={}, valid={'>': 1, '<': -1, '^': -1j, 'v': 1j}): |
|
|
|
if n not in cache: |
|
|
|
if n == 0: |
|
|
|
cache[n] = [(p, valid[c]) for p, c in grid.items() if c != '.'] |
|
|
|
else: |
|
|
|
cache[n] = [(loop(p, drx), drx) for p, drx in blizzards(n - 1)] |
|
|
|
return cache[n] |
|
|
|
|
|
|
|
|
|
|
|
def bfs(starts, ends, tt=0, dir5=[0, 1, -1j, -1, 1j]): |
|
|
|
edge = starts |
|
|
|
while not ends & edge: |
|
|
|
tt += 1 |
|
|
|
blizz = {p for p, _ in blizzards(tt)} |
|
|
|
edge = {p + dp for p in edge for dp in dir5} & set(grid) - blizz |
|
|
|
return tt |
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
global grid, W, H |
|
|
|
|
|
|
|
rows = open(0).read().splitlines() |
|
|
|
grid = {complex(x, y): c for y, r in enumerate(rows) |
|
|
|
for x, c in enumerate(r) if c != '#'} |
|
|
|
|
|
|
|
H, W = len(rows) - 2, len(rows[1]) - 2 |
|
|
|
start, *_, end = sorted(grid, key=lambda p: (p.imag, p.real)) |
|
|
|
|
|
|
|
t1 = bfs({start}, {end}) |
|
|
|
print(t1) |
|
|
|
|
|
|
|
t2 = bfs({end}, {start}, t1) |
|
|
|
t3 = bfs({start}, {end}, t2) |
|
|
|
print(t3) |
|
|
|
|
|
|
|
|
|
|
|
main() |