Trying jump game again

This commit is contained in:
Dan Buch 2023-10-24 19:46:01 -04:00
parent 8cc2e18965
commit 54a7a2340c
Signed by: meatballhat
GPG Key ID: A12F782281063434
2 changed files with 113 additions and 0 deletions

View File

@ -286,3 +286,71 @@ def binary_tree_from_preorder_inorder(
split_pos = inorder.index(preorder[0])
return subtree(inorder[:split_pos], inorder[split_pos + 1 :])
class JumpSpace(typing.NamedTuple):
pos: int
val: int
moves: list["JumpSpace"]
@classmethod
def from_board(
cls, pos: int = 0, board: typing.Iterable[int] = ()
) -> typing.Optional["JumpSpace"]:
board = list(board)
if len(board) == 0:
return None
space = cls(pos, board[pos], [])
space.collect(board)
return space
def collect(self, board: list[int]) -> None:
del self.moves[:]
if self.pos > len(board) or len(board) == 0:
return
for n in range(self.pos + 1, self.pos + self.val + 1):
if n >= len(board):
break
self.moves.append(typing.cast(JumpSpace, JumpSpace.from_board(n, board)))
def jump_paths(self) -> list[list[int]]:
ret: list[list[int]] = [[self.pos]]
for next_space in self.moves:
for path in next_space.jump_paths():
ret.append([self.pos] + path)
return ret
def count_min_jumps_from_board(board: list[int]) -> int:
if len(board) == 1:
return 0
complete_paths = collect_complete_jump_paths_from_board(board)
if len(complete_paths) == 0:
return -1
return min([len(p) - 1 for p in complete_paths])
def collect_complete_jump_paths_from_board(board: list[int]) -> list[list[int]]:
return [
p
for p in collect_jump_paths_from_board(board)
if len(p) > 0 and p[-1] >= len(board) - 1
]
def collect_jump_paths_from_board(board: list[int]) -> list[list[int]]:
space = JumpSpace.from_board(0, board)
if space is None:
return []
return space.jump_paths()

View File

@ -249,3 +249,48 @@ def test_binary_tree_from_preorder_inorder(
preorder: list[int], inorder: list[int], expected: stdlib.BinaryTreeNode
):
assert stuff.binary_tree_from_preorder_inorder(preorder, inorder) == expected
@pytest.mark.parametrize(
("board", "expected"),
[
(
[2, 3, 1, 1, 4],
[
[0, 1, 2, 3, 4],
[0, 1, 3, 4],
[0, 1, 4],
[0, 2, 3, 4],
],
),
],
)
def test_collect_complete_jump_paths_from_board(
board: list[int], expected: list[list[int]]
):
assert list(sorted(stuff.collect_complete_jump_paths_from_board(board))) == expected
@pytest.mark.parametrize(
("board", "expected"),
[
(
[2, 3, 1, 1, 4],
2,
),
(
[2, 3, 0, 1, 4],
2,
),
(
[1],
0,
),
(
[1, 2],
1,
),
],
)
def test_count_min_jumps_from_board(board: list[int], expected: int):
assert stuff.count_min_jumps_from_board(board) == expected