Skip to content

Commit d741235

Browse files
author
Alexander Tometzki
committed
Improve word search so words can be backwords and overlapping.
1 parent ec6b220 commit d741235

File tree

1 file changed

+21
-17
lines changed

1 file changed

+21
-17
lines changed

Chapter3/word_search.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
16-
from typing import NamedTuple, List, Dict, Optional
16+
from typing import NamedTuple, List, Dict, Optional, Tuple
1717
from random import choice
1818
from string import ascii_uppercase
1919
from csp import CSP, Constraint
@@ -30,14 +30,16 @@ def generate_grid(rows: int, columns: int) -> Grid:
3030
# initialize grid with random letters
3131
return [[choice(ascii_uppercase) for c in range(columns)] for r in range(rows)]
3232

33+
def reverse_string(string: str) -> str:
34+
return string[::-1]
3335

3436
def display_grid(grid: Grid) -> None:
3537
for row in grid:
3638
print(" ".join(row))
3739

3840

39-
def generate_domain(word: str, grid: Grid) -> List[List[GridLocation]]:
40-
domain: List[List[GridLocation]] = []
41+
def generate_domain(word: str, grid: Grid) -> List[List[Tuple[str, GridLocation]]]:
42+
domain: List[List[Tuple[str, GridLocation]]] = []
4143
height: int = len(grid)
4244
width: int = len(grid[0])
4345
length: int = len(word)
@@ -47,16 +49,19 @@ def generate_domain(word: str, grid: Grid) -> List[List[GridLocation]]:
4749
rows: range = range(row, row + length)
4850
if col + length <= width:
4951
# left to right
50-
domain.append([GridLocation(row, c) for c in columns])
52+
domain.append([(l, GridLocation(row, c)) for l, c in zip(word, columns)])
53+
domain.append([(l, GridLocation(row, c)) for l, c in zip(reverse_string(word), columns)])
5154
# diagonal towards bottom right
5255
if row + length <= height:
53-
domain.append([GridLocation(r, col + (r - row)) for r in rows])
56+
domain.append([(l, GridLocation(r, col + (r - row))) for l, r in zip(word, rows)])
57+
domain.append([(l, GridLocation(r, col + (r - row))) for l, r in zip(word, rows)])
5458
if row + length <= height:
5559
# top to bottom
56-
domain.append([GridLocation(r, col) for r in rows])
60+
domain.append([(l, GridLocation(r, col)) for l, r in zip(word, rows)])
5761
# diagonal towards bottom left
5862
if col - length >= 0:
59-
domain.append([GridLocation(r, col - (r - row)) for r in rows])
63+
domain.append([(l, GridLocation(r, col - (r - row))) for l, r in zip(reverse_string(word), rows)])
64+
6065
return domain
6166

6267

@@ -65,33 +70,32 @@ def __init__(self, words: List[str]) -> None:
6570
super().__init__(words)
6671
self.words: List[str] = words
6772

68-
def satisfied(self, assignment: Dict[str, List[GridLocation]]) -> bool:
73+
def satisfied(self, assignment: Dict[str, List[Tuple[str, GridLocation]]]) -> bool:
6974
all_locations: set = set()
7075
all_lettered_locations: set = set()
71-
for word, locs in assignment.items():
72-
for letter, loc in zip(word, locs):
76+
for locs in assignment.values():
77+
for letter, loc in locs:
7378
if loc in all_locations:
7479
if (letter, loc) not in all_lettered_locations:
7580
return False
76-
7781
all_locations.add(loc)
7882
all_lettered_locations.add((letter, loc))
7983
return True
8084

8185
if __name__ == "__main__":
8286
grid: Grid = generate_grid(9, 9)
8387
words: List[str] = ["MATTHEW", "JOE", "MARY", "SARAH", "SALLY"]
84-
locations: Dict[str, List[List[GridLocation]]] = {}
88+
locations: Dict[str, List[List[Tuple[str, GridLocation]]]] = {}
8589
for word in words:
8690
locations[word] = generate_domain(word, grid)
87-
csp: CSP[str, List[GridLocation]] = CSP(words, locations)
91+
csp: CSP[str, List[Tuple[str, GridLocation]]] = CSP(words, locations)
8892
csp.add_constraint(WordSearchConstraint(words))
89-
solution: Optional[Dict[str, List[GridLocation]]] = csp.backtracking_search()
93+
solution: Optional[Dict[str, List[Tuple[str, GridLocation]]]] = csp.backtracking_search()
9094
if solution is None:
9195
print("No solution found!")
9296
else:
93-
for word, grid_locations in solution.items():
94-
for index, letter in enumerate(word):
95-
(row, col) = (grid_locations[index].row, grid_locations[index].column)
97+
for grid_locations in solution.values():
98+
for letter, location in grid_locations:
99+
(row, col) = (location.row, location.column)
96100
grid[row][col] = letter
97101
display_grid(grid)

0 commit comments

Comments
 (0)