-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathword_search_model.py
231 lines (198 loc) · 9.78 KB
/
word_search_model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
def match_horizontal(word, row, column, grid):
"""Horizontally match a word's characters with those in the word search.
Args:
word: A string representing the word to match.
row: An integer representing the row containing some subset of
characters in word.
column: An integer representing the column currently being pointed
to.
Returns:
A boolean representing whether or not a complete match has been
made beginning at the row and column passed as arguments.
"""
word_index = 0 # Indexes the current word
match_success = True
# Begin left to right match:
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column < len(grid[0]) and character_to_match == grid[row][column]:
word_index += 1
column += 1
else:
match_success = False
# Begin right to left match:
if match_success == False:
column -= word_index # Decrement column to equal initial value when match_horizontal was called
word_index = 0
match_success = True
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column >= 0 and character_to_match == grid[row][column]:
word_index += 1
column -= 1
else:
match_success = False
return match_success
def match_vertical(word, row, column, grid):
"""Vertically match a word's characters with those in the word search.
Args:
word: A string representing the word to match.
row: An integer representing the row containing some subset of
characters in word.
column: An integer representing the column currently being pointed
to.
Returns:
A boolean representing whether or not a complete match has been
made beginning at the row and column passed as arguments.
"""
word_index = 0 # Indexes the current word
match_success = True
# Begin top to bottom match:
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if row < len(grid) and character_to_match == grid[row][column]:
word_index += 1
row += 1
else:
match_success = False
# Begin bottom to top match:
if match_success == False:
row -= word_index # Decrement row to equal initial value when match_vertical was called
word_index = 0
match_success = True
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if row >= 0 and character_to_match == grid[row][column]:
word_index += 1
row -= 1
else:
match_success = False
return match_success
def match_diagonal_left_right(word, row, column, grid):
"""Diagonally match a word's characters with those in the word search.
Diagonally match a word's characters with those in the word search going
from top-left to bottom-right or bottom-right to top-left.
Args:
word: A string representing the word to match.
row: An integer representing the row containing some subset of
characters in word.
column: An integer representing the column currently being pointed
to.
Returns:
A boolean representing whether or not a complete match has been
made beginning at the row and column passed as arguments.
"""
word_index = 0 # Indexes the current word
match_success = True
# Begin top-left to bottom-right match:
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column < len(grid[0]) and row < len(grid) and character_to_match == grid[row][column]:
word_index += 1
column += 1
row += 1
else:
match_success = False
# Begin bottom-right to top-left match:
if match_success == False:
column -= word_index # Decrement column to equal initial value when match_diagonal was called
row -= word_index # Decrement row to equal initial value when match_diagonal was called
word_index = 0
match_success = True
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column >= 0 and row >= 0 and character_to_match == grid[row][column]:
word_index += 1
column -= 1
row -= 1
else:
match_success = False
return match_success
def match_diagonal_right_left(word, row, column, grid):
"""Diagonally match a word's characters with those in the word search.
Diagonally match a word's characters with those in the word search going
from top-right to bottom-left or bottom-left to top-right.
Args:
word: A string representing the word to match.
row: An integer representing the row containing some subset of
characters in word.
column: An integer representing the column currently being pointed
to.
Returns:
A boolean representing whether or not a complete match has been
made beginning at the row and column passed as arguments.
"""
word_index = 0 # Indexes the current word
match_success = True
# Begin top-right to bottom-left match:
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column >= 0 and row < len(grid) and character_to_match == grid[row][column]:
word_index += 1
column -= 1
row += 1
else:
match_success = False
# Begin bottom-left to top-right match:
if match_success == False:
column += word_index # Decrement column to equal initial value when match_diagonal was called
row -= word_index # Decrement row to equal initial value when match_diagonal was called
word_index = 0
match_success = True
while word_index < len(word) and match_success == True:
character_to_match = word[word_index]
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
if column < len(grid[0]) and row >= 0 and character_to_match == grid[row][column]:
word_index += 1
column += 1
row -= 1
else:
match_success = False
return match_success
match_algorithms = [match_horizontal, match_vertical, match_diagonal_left_right, match_diagonal_right_left]
def solve(grid, words_to_find):
"""Solve word search.
Solve word search by producing the location of the first letter for each
word in the word search grid.
Args:
grid: A list of lists representing a word search grid.
words_to_find: A dictionary with the key representing the word to
be found in grid and value representing location of beginning
of word in grid.
Returns:
A dictionary with the key representing the word to be found in
grid and value representing location of beginning of word in
grid.
"""
for word in words_to_find: # Go through each word in the list of words to match
row = 0 # Points to row in grid when searching
column = 0 # Points to column in grid when searching
is_matched = False
while row < len(grid) and is_matched == False:
character_to_match = word[0] # Assign first character of current word
# Move to start of next row if at end of current row:
if column >= len(grid[0]):
column = 0
row += 1
continue
# If the character being pointed to in the grid matches the character being pointed to in the word to match:
elif character_to_match == grid[row][column]:
for algorithm in match_algorithms:
is_matched = algorithm(word, row, column, grid)
if is_matched == True:
words_to_find[word] = (row, column)
break
column += 1
return words_to_find
if __name__ == "__main__":
# The test grid here is a list of strings rather than a list of lists as described in the doc string.
grid = ["ttowarddvbnay", "eadhbvreeyows", "ooeohawestrka", "ksyawedisetor", "wanyenabvahib", "wgkhsaroeagad", "ashtrdbbohcro", "cweuearotkito", "wawovwuawelnv", "wwbseaoawewsd", "gahprwrlfrrbb", "sywwudyterods", "tsaedaehabofr"]
words_to_find = {"above": False, "ahead": False, "away": False, "backward": False, "behind": False, "below": False, "down": False, "east": False, "forward": False, "left": False, "north": False, "reverse": False, "right": False, "sideways": False, "skyward": False, "south": False, "toward": False, "up": False, "west": False}
print(solve(grid, words_to_find))