Skip to content

Commit afce564

Browse files
kadambari25KadambariSureshpre-commit-ci[bot]cclauss
authored
Add get_word_path function to word_search.py (#14511)
* Added get_word_path function * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updating DIRECTORY.md * Implement board and word validation function Added a new validation function to check the board and word parameters, ensuring proper input types and values. Updated existing function docstrings for clarity and consistency. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Improve readability of validate_board_and_word call Refactor the validate_board_and_word function call for better readability. --------- Co-authored-by: Kadambari <kadambari179@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: cclauss <cclauss@users.noreply.github.com>
1 parent 5bb1027 commit afce564

1 file changed

Lines changed: 118 additions & 31 deletions

File tree

backtracking/word_search.py

Lines changed: 118 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
Result:
2626
True
2727
28-
Implementation notes: Use backtracking approach.
28+
Implementation notes: Use a backtracking approach.
2929
At each point, check all neighbors to try to find the next letter of the word.
3030
3131
leetcode: https://leetcode.com/problems/word-search/
@@ -53,7 +53,7 @@ def exits_word(
5353
visited_points_set: set[int],
5454
) -> bool:
5555
"""
56-
Return True if it's possible to search the word suffix
56+
Return True if it's possible to search for the word suffix
5757
starting from the word_index.
5858
5959
>>> exits_word([["A"]], "B", 0, 0, 0, set())
@@ -88,13 +88,122 @@ def exits_word(
8888
return False
8989

9090

91+
def validate_board_and_word(board: list[list[str]], word: str) -> None:
92+
"""
93+
>>> board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]]
94+
>>> validate_board_and_word(board, "ABCCED")
95+
>>> validate_board_and_word(board, "SEE")
96+
>>> validate_board_and_word(board, "ABCB")
97+
>>> validate_board_and_word([["A"]], "A")
98+
>>> validate_board_and_word(
99+
... [["B", "A", "A"], ["A", "A", "A"], ["A", "B", "A"]], "ABB"
100+
... )
101+
>>> validate_board_and_word([["A"]], 123)
102+
Traceback (most recent call last):
103+
...
104+
ValueError: The word parameter should be a string of length greater than 0.
105+
>>> validate_board_and_word([["A"]], "")
106+
Traceback (most recent call last):
107+
...
108+
ValueError: The word parameter should be a string of length greater than 0.
109+
>>> validate_board_and_word([[]], "AB")
110+
Traceback (most recent call last):
111+
...
112+
ValueError: The board should be a non-empty matrix of single-character strings.
113+
>>> validate_board_and_word([], "AB")
114+
Traceback (most recent call last):
115+
...
116+
ValueError: The board should be a non-empty matrix of single-character strings.
117+
>>> validate_board_and_word([["A"], [21]], "AB")
118+
Traceback (most recent call last):
119+
...
120+
ValueError: The board should be a non-empty matrix of single-character strings.
121+
"""
122+
123+
# Validate board
124+
msg = "The board should be a non-empty matrix of single-character strings."
125+
if not board or not isinstance(board, list):
126+
raise ValueError(msg)
127+
128+
for row in board:
129+
if not row or not isinstance(row, list):
130+
raise ValueError(msg)
131+
132+
for item in row:
133+
if not item or not isinstance(item, str):
134+
raise ValueError(msg)
135+
136+
# Validate word
137+
if not isinstance(word, str) or len(word) == 0:
138+
msg = "The word parameter should be a string of length greater than 0."
139+
raise ValueError(msg)
140+
141+
142+
def get_word_path(board: list[list[str]], word: str) -> list[tuple[int, int]] | None:
143+
"""
144+
Return the path of the word in the board if it exists; otherwise, return None.
145+
146+
>>> board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]]
147+
>>> get_word_path(board, "ABCCED")
148+
[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (2, 1)]
149+
>>> get_word_path(board, "SEE")
150+
[(1, 3), (2, 3), (2, 2)]
151+
>>> get_word_path(board, "ABCB") is None
152+
True
153+
>>> get_word_path([["A"]], 123)
154+
Traceback (most recent call last):
155+
...
156+
ValueError: The word parameter should be a string of length greater than 0.
157+
"""
158+
validate_board_and_word(board, word)
159+
rows, cols = len(board), len(board[0])
160+
161+
def backtrack(
162+
r: int,
163+
c: int,
164+
index: int,
165+
path: list[tuple[int, int]],
166+
visited: set[tuple[int, int]],
167+
) -> list[tuple[int, int]] | None:
168+
if board[r][c] != word[index]:
169+
return None
170+
171+
path.append((r, c))
172+
visited.add((r, c))
173+
174+
if index == len(word) - 1:
175+
return path.copy()
176+
177+
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
178+
179+
for dr, dc in directions:
180+
nr, nc = r + dr, c + dc
181+
if 0 <= nr < rows and 0 <= nc < cols and (nr, nc) not in visited:
182+
result = backtrack(nr, nc, index + 1, path, visited)
183+
if result:
184+
return result
185+
186+
path.pop()
187+
visited.remove((r, c))
188+
return None
189+
190+
for i in range(rows):
191+
for j in range(cols):
192+
result = backtrack(i, j, 0, [], set())
193+
if result:
194+
return result
195+
196+
return None
197+
198+
91199
def word_exists(board: list[list[str]], word: str) -> bool:
92200
"""
93-
>>> word_exists([["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], "ABCCED")
201+
>>> board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]]
202+
>>> word_exists(board, "ABCCED")
94203
True
95-
>>> word_exists([["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], "SEE")
204+
>>> word_exists(board, "SEE")
96205
True
97-
>>> word_exists([["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], "ABCB")
206+
>>> word_exists(board, "ABCB")
98207
False
99208
>>> word_exists([["A"]], "A")
100209
True
@@ -111,40 +220,18 @@ def word_exists(board: list[list[str]], word: str) -> bool:
111220
>>> word_exists([[]], "AB")
112221
Traceback (most recent call last):
113222
...
114-
ValueError: The board should be a non empty matrix of single chars strings.
223+
ValueError: The board should be a non-empty matrix of single-character strings.
115224
>>> word_exists([], "AB")
116225
Traceback (most recent call last):
117226
...
118-
ValueError: The board should be a non empty matrix of single chars strings.
227+
ValueError: The board should be a non-empty matrix of single-character strings.
119228
>>> word_exists([["A"], [21]], "AB")
120229
Traceback (most recent call last):
121230
...
122-
ValueError: The board should be a non empty matrix of single chars strings.
231+
ValueError: The board should be a non-empty matrix of single-character strings.
123232
"""
124-
125-
# Validate board
126-
board_error_message = (
127-
"The board should be a non empty matrix of single chars strings."
128-
)
129-
233+
validate_board_and_word(board, word)
130234
len_board = len(board)
131-
if not isinstance(board, list) or len(board) == 0:
132-
raise ValueError(board_error_message)
133-
134-
for row in board:
135-
if not isinstance(row, list) or len(row) == 0:
136-
raise ValueError(board_error_message)
137-
138-
for item in row:
139-
if not isinstance(item, str) or len(item) != 1:
140-
raise ValueError(board_error_message)
141-
142-
# Validate word
143-
if not isinstance(word, str) or len(word) == 0:
144-
raise ValueError(
145-
"The word parameter should be a string of length greater than 0."
146-
)
147-
148235
len_board_column = len(board[0])
149236
for i in range(len_board):
150237
for j in range(len_board_column):

0 commit comments

Comments
 (0)