This commit is contained in:
parent
24580fdfd8
commit
954ef1e6ce
@ -1,7 +1,81 @@
|
|||||||
from typing import Any, Iterator
|
import heapq
|
||||||
|
from typing import Any, Iterator, TypeAlias, cast
|
||||||
|
|
||||||
from ..base import BaseSolver
|
from ..base import BaseSolver
|
||||||
|
|
||||||
|
Node: TypeAlias = tuple[int, int]
|
||||||
|
|
||||||
|
|
||||||
|
def dijkstra(
|
||||||
|
grid: list[Node],
|
||||||
|
n_rows: int,
|
||||||
|
n_cols: int,
|
||||||
|
start: Node = (0, 0),
|
||||||
|
target: Node | None = None,
|
||||||
|
) -> tuple[Node, ...] | None:
|
||||||
|
corrupted = set(grid)
|
||||||
|
target = target or (n_rows - 1, n_cols - 1)
|
||||||
|
|
||||||
|
queue: list[tuple[int, Node, tuple[Node, ...]]] = [(0, start, (start,))]
|
||||||
|
preds: dict[Node, tuple[Node, ...]] = {}
|
||||||
|
|
||||||
|
while queue:
|
||||||
|
dis, node, path = heapq.heappop(queue)
|
||||||
|
|
||||||
|
if node in preds:
|
||||||
|
continue
|
||||||
|
|
||||||
|
preds[node] = path
|
||||||
|
|
||||||
|
if node == target:
|
||||||
|
break
|
||||||
|
|
||||||
|
row, col = node
|
||||||
|
for dr, dc in ((-1, 0), (0, 1), (1, 0), (0, -1)):
|
||||||
|
row_n, col_n = row + dr, col + dc
|
||||||
|
|
||||||
|
if (
|
||||||
|
0 <= row_n < n_rows
|
||||||
|
and 0 <= col_n < n_cols
|
||||||
|
and (row_n, col_n) not in corrupted
|
||||||
|
and (row_n, col_n) not in preds
|
||||||
|
):
|
||||||
|
heapq.heappush(
|
||||||
|
queue, (dis + 1, (row_n, col_n), path + ((row_n, col_n),))
|
||||||
|
)
|
||||||
|
|
||||||
|
return preds.get(target, None)
|
||||||
|
|
||||||
|
|
||||||
class Solver(BaseSolver):
|
class Solver(BaseSolver):
|
||||||
def solve(self, input: str) -> Iterator[Any]: ...
|
def print_grid(self, grid: list[tuple[int, int]], n_rows: int, n_cols: int):
|
||||||
|
values = set(grid)
|
||||||
|
for row in range(n_rows):
|
||||||
|
self.logger.info(
|
||||||
|
"".join("#" if (row, col) in values else "." for col in range(n_cols))
|
||||||
|
)
|
||||||
|
|
||||||
|
def solve(self, input: str) -> Iterator[Any]:
|
||||||
|
values = [
|
||||||
|
cast(tuple[int, int], tuple(map(int, row.split(","))))
|
||||||
|
for row in input.splitlines()
|
||||||
|
]
|
||||||
|
|
||||||
|
n_rows, n_cols = (7, 7) if len(values) < 100 else (71, 71)
|
||||||
|
|
||||||
|
n_bytes_p1 = 12 if len(values) < 100 else 1024
|
||||||
|
bytes_p1 = values[:n_bytes_p1]
|
||||||
|
self.print_grid(bytes_p1, n_rows, n_cols)
|
||||||
|
|
||||||
|
path_p1 = dijkstra(bytes_p1, n_rows, n_cols)
|
||||||
|
assert path_p1 is not None
|
||||||
|
yield len(path_p1) - 1
|
||||||
|
|
||||||
|
path = path_p1
|
||||||
|
for b in range(n_bytes_p1, len(values)):
|
||||||
|
if values[b] not in path:
|
||||||
|
continue
|
||||||
|
path = dijkstra(values[: b + 1], n_rows, n_cols)
|
||||||
|
if path is None:
|
||||||
|
yield ",".join(map(str, values[b]))
|
||||||
|
break
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,25 @@
|
|||||||
|
5,4
|
||||||
|
4,2
|
||||||
|
4,5
|
||||||
|
3,0
|
||||||
|
2,1
|
||||||
|
6,3
|
||||||
|
2,4
|
||||||
|
1,5
|
||||||
|
0,6
|
||||||
|
3,3
|
||||||
|
2,6
|
||||||
|
5,1
|
||||||
|
1,2
|
||||||
|
5,5
|
||||||
|
2,5
|
||||||
|
6,5
|
||||||
|
1,4
|
||||||
|
0,4
|
||||||
|
6,4
|
||||||
|
1,1
|
||||||
|
6,1
|
||||||
|
1,0
|
||||||
|
0,5
|
||||||
|
1,6
|
||||||
|
2,0
|
Loading…
Reference in New Issue
Block a user