94 lines
2.1 KiB
Python
94 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import pprint
|
|
import sys
|
|
|
|
input_file = sys.argv[1]
|
|
|
|
with open(input_file) as fd:
|
|
lines = [line.rstrip() for line in fd.readlines()]
|
|
|
|
height = len(lines)
|
|
width = len(lines[0])
|
|
|
|
vec = tuple[int, int]
|
|
|
|
directions = [
|
|
(-1, 0), # ^ North
|
|
(0, 1), # > East
|
|
(1, 0), # v South
|
|
(0, -1), # < West
|
|
]
|
|
|
|
directions_keys = ("^", ">", "v", "<")
|
|
|
|
min_scores: list[list[list[None | int]]] = list()
|
|
for _ in range(height):
|
|
line: list[list[None | int]] = list()
|
|
for _ in range(width):
|
|
cell: list[None | int] = [None] * len(directions)
|
|
line.append(cell)
|
|
min_scores.append(line)
|
|
|
|
start = height - 2, 1
|
|
|
|
|
|
def walk(pos: vec, dir: int, score: int, depth: int = 0) -> int | None:
|
|
i, j = pos
|
|
char = lines[i][j]
|
|
|
|
if depth > 1000:
|
|
return None
|
|
|
|
# print("-" * depth, 28, pos, char, directions_keys[dir], score)
|
|
if char == "E":
|
|
return score
|
|
elif char == "#":
|
|
return None
|
|
|
|
min_score = min_scores[i][j][dir]
|
|
for d, min_score in enumerate(min_scores[i][j]):
|
|
if min_score is None:
|
|
continue
|
|
if d == dir:
|
|
if score >= min_score:
|
|
return None
|
|
else:
|
|
if score >= min_score + 1000:
|
|
return None
|
|
min_scores[i][j][dir] = score
|
|
|
|
mscore = None
|
|
for ndir, direction in enumerate(directions):
|
|
ii, jj = i + direction[0], j + direction[1]
|
|
price = 1 if dir == ndir else 1001
|
|
nscore = walk((ii, jj), ndir, score + price, depth + 1)
|
|
if nscore is None:
|
|
continue
|
|
if mscore is None or nscore < mscore:
|
|
mscore = nscore
|
|
return mscore
|
|
|
|
|
|
sys.setrecursionlimit(3000)
|
|
tot_score = walk(start, 1, 0)
|
|
|
|
# Viz
|
|
for i in range(height):
|
|
cline = ""
|
|
for j in range(width):
|
|
char = lines[i][j]
|
|
min_score = None
|
|
for d in range(len(directions)):
|
|
score = min_scores[i][j][d]
|
|
if score is None:
|
|
continue
|
|
if min_score is None or score < min_score:
|
|
char = directions_keys[d]
|
|
min_score = score
|
|
cline += char
|
|
print(cline)
|
|
print()
|
|
|
|
print(tot_score)
|