Refactor code for API (#3)
Co-authored-by: Mikael CAPELLE <mikael.capelle@thalesaleniaspace.com> Co-authored-by: Mikaël Capelle <capelle.mikael@gmail.com> Reviewed-on: #3
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import heapq
|
||||
import sys
|
||||
from typing import Callable, Iterator, TypeVar
|
||||
from typing import Any, Callable, Iterator, TypeVar
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
Node = TypeVar("Node")
|
||||
|
||||
@@ -68,30 +69,6 @@ def make_path(parents: dict[Node, Node], start: Node, end: Node) -> list[Node] |
|
||||
return list(reversed(path))
|
||||
|
||||
|
||||
def print_path(path: list[tuple[int, int]], n_rows: int, n_cols: int) -> None:
|
||||
end = path[-1]
|
||||
|
||||
graph = [["." for _c in range(n_cols)] for _r in range(n_rows)]
|
||||
graph[end[0]][end[1]] = "E"
|
||||
|
||||
for i in range(0, len(path) - 1):
|
||||
cr, cc = path[i]
|
||||
nr, nc = path[i + 1]
|
||||
|
||||
if cr == nr and nc == cc - 1:
|
||||
graph[cr][cc] = "<"
|
||||
elif cr == nr and nc == cc + 1:
|
||||
graph[cr][cc] = ">"
|
||||
elif cr == nr - 1 and nc == cc:
|
||||
graph[cr][cc] = "v"
|
||||
elif cr == nr + 1 and nc == cc:
|
||||
graph[cr][cc] = "^"
|
||||
else:
|
||||
assert False, "{} -> {} infeasible".format(path[i], path[i + 1])
|
||||
|
||||
print("\n".join("".join(row) for row in graph))
|
||||
|
||||
|
||||
def neighbors(
|
||||
grid: list[list[int]], node: tuple[int, int], up: bool
|
||||
) -> Iterator[tuple[int, int]]:
|
||||
@@ -118,46 +95,74 @@ def neighbors(
|
||||
|
||||
# === main code ===
|
||||
|
||||
lines = sys.stdin.read().splitlines()
|
||||
|
||||
grid = [[ord(cell) - ord("a") for cell in line] for line in lines]
|
||||
class Solver(BaseSolver):
|
||||
def print_path(self, path: list[tuple[int, int]], n_rows: int, n_cols: int) -> None:
|
||||
end = path[-1]
|
||||
|
||||
start: tuple[int, int] | None = None
|
||||
end: tuple[int, int] | None = None
|
||||
graph = [["." for _c in range(n_cols)] for _r in range(n_rows)]
|
||||
graph[end[0]][end[1]] = "E"
|
||||
|
||||
# for part 2
|
||||
start_s: list[tuple[int, int]] = []
|
||||
for i in range(0, len(path) - 1):
|
||||
cr, cc = path[i]
|
||||
nr, nc = path[i + 1]
|
||||
|
||||
for i_row, row in enumerate(grid):
|
||||
for i_col, col in enumerate(row):
|
||||
if chr(col + ord("a")) == "S":
|
||||
start = (i_row, i_col)
|
||||
start_s.append(start)
|
||||
elif chr(col + ord("a")) == "E":
|
||||
end = (i_row, i_col)
|
||||
elif col == 0:
|
||||
start_s.append((i_row, i_col))
|
||||
if cr == nr and nc == cc - 1:
|
||||
graph[cr][cc] = "<"
|
||||
elif cr == nr and nc == cc + 1:
|
||||
graph[cr][cc] = ">"
|
||||
elif cr == nr - 1 and nc == cc:
|
||||
graph[cr][cc] = "v"
|
||||
elif cr == nr + 1 and nc == cc:
|
||||
graph[cr][cc] = "^"
|
||||
else:
|
||||
assert False, "{} -> {} infeasible".format(path[i], path[i + 1])
|
||||
|
||||
assert start is not None
|
||||
assert end is not None
|
||||
for row in graph:
|
||||
self.logger.info("".join(row))
|
||||
|
||||
# fix values
|
||||
grid[start[0]][start[1]] = 0
|
||||
grid[end[0]][end[1]] = ord("z") - ord("a")
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
lines = input.splitlines()
|
||||
|
||||
grid = [[ord(cell) - ord("a") for cell in line] for line in lines]
|
||||
|
||||
lengths_1, parents_1 = dijkstra(
|
||||
start=start, neighbors=lambda n: neighbors(grid, n, True), cost=lambda lhs, rhs: 1
|
||||
)
|
||||
path_1 = make_path(parents_1, start, end)
|
||||
assert path_1 is not None
|
||||
start: tuple[int, int] | None = None
|
||||
end: tuple[int, int] | None = None
|
||||
|
||||
print_path(path_1, n_rows=len(grid), n_cols=len(grid[0]))
|
||||
# for part 2
|
||||
start_s: list[tuple[int, int]] = []
|
||||
|
||||
print(f"answer 1 is {lengths_1[end] - 1}")
|
||||
for i_row, row in enumerate(grid):
|
||||
for i_col, col in enumerate(row):
|
||||
if chr(col + ord("a")) == "S":
|
||||
start = (i_row, i_col)
|
||||
start_s.append(start)
|
||||
elif chr(col + ord("a")) == "E":
|
||||
end = (i_row, i_col)
|
||||
elif col == 0:
|
||||
start_s.append((i_row, i_col))
|
||||
|
||||
lengths_2, parents_2 = dijkstra(
|
||||
start=end, neighbors=lambda n: neighbors(grid, n, False), cost=lambda lhs, rhs: 1
|
||||
)
|
||||
answer_2 = min(lengths_2.get(start, float("inf")) for start in start_s)
|
||||
print(f"answer 2 is {answer_2}")
|
||||
assert start is not None
|
||||
assert end is not None
|
||||
|
||||
# fix values
|
||||
grid[start[0]][start[1]] = 0
|
||||
grid[end[0]][end[1]] = ord("z") - ord("a")
|
||||
|
||||
lengths_1, parents_1 = dijkstra(
|
||||
start=start,
|
||||
neighbors=lambda n: neighbors(grid, n, True),
|
||||
cost=lambda lhs, rhs: 1,
|
||||
)
|
||||
path_1 = make_path(parents_1, start, end)
|
||||
assert path_1 is not None
|
||||
|
||||
self.print_path(path_1, n_rows=len(grid), n_cols=len(grid[0]))
|
||||
yield lengths_1[end] - 1
|
||||
|
||||
lengths_2, _ = dijkstra(
|
||||
start=end,
|
||||
neighbors=lambda n: neighbors(grid, n, False),
|
||||
cost=lambda lhs, rhs: 1,
|
||||
)
|
||||
yield min(lengths_2.get(start, float("inf")) for start in start_s)
|
||||
|
Reference in New Issue
Block a user