Files
advent-of-code-2024/day16/code.py
Dmitry Fedotov c15defa16e add comment
2025-01-06 02:20:38 +03:00

111 lines
2.4 KiB
Python

import sys
sys.path.append('../aoclib')
from aoclib import Input
import heapq
sys.setrecursionlimit(15000)
L = '<'
U = '^'
R = '>'
D = 'v'
EMPTY = '.'
WALL = '#'
START = 'S'
END = 'E'
class Maze:
def __init__(self, lines: list[list[str]]):
self.grid = lines
for y in range(len(self.grid)):
for x in range(len(self.grid[0])):
if self.grid[y][x] == START:
self.s = (x, y)
elif self.grid[y][x] == END:
self.e = (x, y)
def __str__(self):
grid = [r.copy() for r in self.grid]
return '\n'.join(''.join(row) for row in grid)
def start(self) -> tuple[int, int]:
return self.s
def end(self, pos: tuple[int, int]) -> bool:
return self.e == pos
def is_wall(self, pos) -> bool:
x, y = pos
return self.grid[y][x] == WALL
def search(m: Maze) -> int:
x, y = m.start()
state = (x, y, 1, 0) # x diff is 1 (we are facing right), y diff is 0
queue = []
visited = set()
heapq.heappush(queue, (0, state))
visited.add(state)
while queue:
cost, state = heapq.heappop(queue)
x, y, xd, yd = state
if m.end((x, y)):
return cost
options = [
# move forward
(cost+1, (x+xd, y+yd, xd, yd)),
# turn
(cost+1000, (x, y, -yd, xd)),
(cost+1000, (x, y, yd, -xd)),
]
for opt in options:
cost, state = opt
x, y, _, _ = state
if m.is_wall((x, y)):
continue
if state in visited:
continue
visited.add(state)
heapq.heappush(queue, (cost, state))
return -1
def solve1(lines: list[list[str]]):
m = Maze(lines)
res = search(m)
return res
def solve2(lines: list[list[str]]):
maze = Maze(lines)
return ''
if __name__ == '__main__':
lines = Input('input_test.txt').lines_as_lists()
#part 1
print('test part 1:', solve1(lines))
#part 2
print('test part 2:', solve2(lines))
lines = Input('input_test2.txt').lines_as_lists()
#part 1
print('test 2 part 1:', solve1(lines))
#part 2
print('test 2 part 2:', solve2(lines))
lines = Input('input.txt').lines_as_lists()
#part 1
print('part 1:', solve1(lines)) # 90460
#part 2
print('part 2:', solve2(lines))