13
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
14
# See the License for the specific language governing permissions and
15
15
# limitations under the License.
16
- from typing import NamedTuple , List , Dict , Optional
16
+ from typing import NamedTuple , List , Dict , Optional , Tuple
17
17
from random import choice
18
18
from string import ascii_uppercase
19
19
from csp import CSP , Constraint
@@ -30,14 +30,16 @@ def generate_grid(rows: int, columns: int) -> Grid:
30
30
# initialize grid with random letters
31
31
return [[choice (ascii_uppercase ) for c in range (columns )] for r in range (rows )]
32
32
33
+ def reverse_string (string : str ) -> str :
34
+ return string [::- 1 ]
33
35
34
36
def display_grid (grid : Grid ) -> None :
35
37
for row in grid :
36
38
print (" " .join (row ))
37
39
38
40
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 ] ]] = []
41
43
height : int = len (grid )
42
44
width : int = len (grid [0 ])
43
45
length : int = len (word )
@@ -47,16 +49,19 @@ def generate_domain(word: str, grid: Grid) -> List[List[GridLocation]]:
47
49
rows : range = range (row , row + length )
48
50
if col + length <= width :
49
51
# 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 )])
51
54
# diagonal towards bottom right
52
55
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 )])
54
58
if row + length <= height :
55
59
# 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 ) ])
57
61
# diagonal towards bottom left
58
62
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
+
60
65
return domain
61
66
62
67
@@ -65,33 +70,32 @@ def __init__(self, words: List[str]) -> None:
65
70
super ().__init__ (words )
66
71
self .words : List [str ] = words
67
72
68
- def satisfied (self , assignment : Dict [str , List [GridLocation ]]) -> bool :
73
+ def satisfied (self , assignment : Dict [str , List [Tuple [ str , GridLocation ] ]]) -> bool :
69
74
all_locations : set = set ()
70
75
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 :
73
78
if loc in all_locations :
74
79
if (letter , loc ) not in all_lettered_locations :
75
80
return False
76
-
77
81
all_locations .add (loc )
78
82
all_lettered_locations .add ((letter , loc ))
79
83
return True
80
84
81
85
if __name__ == "__main__" :
82
86
grid : Grid = generate_grid (9 , 9 )
83
87
words : List [str ] = ["MATTHEW" , "JOE" , "MARY" , "SARAH" , "SALLY" ]
84
- locations : Dict [str , List [List [GridLocation ]]] = {}
88
+ locations : Dict [str , List [List [Tuple [ str , GridLocation ] ]]] = {}
85
89
for word in words :
86
90
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 )
88
92
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 ()
90
94
if solution is None :
91
95
print ("No solution found!" )
92
96
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 )
96
100
grid [row ][col ] = letter
97
101
display_grid (grid )
0 commit comments