Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[flake8]
max-line-length = 88
# max-complexity should be 10
max-complexity = 19
max-complexity = 17
extend-ignore =
# Formatting style for `black`
# E203 is whitespace before ':'
Expand Down
110 changes: 58 additions & 52 deletions backtracking/word_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,59 @@
"""


# Returns the hash key of matrix indexes.
def get_point_key(len_board: int, len_board_column: int, row: int, column: int) -> int:
"""
>>> get_point_key(10, 20, 1, 0)
200
"""

return len_board * len_board_column * row + column


# Return True if it's possible to search the word suffix
# starting from the word_index.
def exits_word(
board: list[list[str]],
word: str,
row: int,
column: int,
word_index: int,
visited_points_set: set[int],
) -> bool:
"""
>>> exits_word([["A"]], "B", 0, 0, 0, set())
False
"""

if board[row][column] != word[word_index]:
return False

if word_index == len(word) - 1:
return True

traverts_directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
len_board = len(board)
len_board_column = len(board[0])
for direction in traverts_directions:
next_i = row + direction[0]
next_j = column + direction[1]
if not (0 <= next_i < len_board and 0 <= next_j < len_board_column):
continue

key = get_point_key(len_board, len_board_column, next_i, next_j)
if key in visited_points_set:
continue

visited_points_set.add(key)
if exits_word(board, word, next_i, next_j, word_index + 1, visited_points_set):
return True

visited_points_set.remove(key)

return False


def word_exists(board: list[list[str]], word: str) -> bool:
"""
>>> word_exists([["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], "ABCCED")
Expand Down Expand Up @@ -77,6 +130,8 @@ def word_exists(board: list[list[str]], word: str) -> bool:
board_error_message = (
"The board should be a non empty matrix of single chars strings."
)

len_board = len(board)
if not isinstance(board, list) or len(board) == 0:
raise ValueError(board_error_message)

Expand All @@ -94,61 +149,12 @@ def word_exists(board: list[list[str]], word: str) -> bool:
"The word parameter should be a string of length greater than 0."
)

traverts_directions = [(0, 1), (0, -1), (-1, 0), (1, 0)]
len_word = len(word)
len_board = len(board)
len_board_column = len(board[0])

# Returns the hash key of matrix indexes.
def get_point_key(row: int, column: int) -> int:
"""
>>> len_board=10
>>> len_board_column=20
>>> get_point_key(0, 0)
200
"""

return len_board * len_board_column * row + column

# Return True if it's possible to search the word suffix
# starting from the word_index.
def exits_word(
row: int, column: int, word_index: int, visited_points_set: set[int]
) -> bool:
"""
>>> board=[["A"]]
>>> word="B"
>>> exits_word(0, 0, 0, set())
False
"""

if board[row][column] != word[word_index]:
return False

if word_index == len_word - 1:
return True

for direction in traverts_directions:
next_i = row + direction[0]
next_j = column + direction[1]
if not (0 <= next_i < len_board and 0 <= next_j < len_board_column):
continue

key = get_point_key(next_i, next_j)
if key in visited_points_set:
continue

visited_points_set.add(key)
if exits_word(next_i, next_j, word_index + 1, visited_points_set):
return True

visited_points_set.remove(key)

return False

for i in range(len_board):
for j in range(len_board_column):
if exits_word(i, j, 0, {get_point_key(i, j)}):
if exits_word(
board, word, i, j, 0, {get_point_key(len_board, len_board_column, i, j)}
):
return True

return False
Expand Down