Crossword Solver

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Autonomous University of Queretaro

Faculty of Engineering
Research and Postgraduate Division

Master of Science
in
Artificial Intelligence

Machine Learning
Assignment 1

Crossword Puzzle Solver

Student: Professor:
José Armando PhD. Marco Antonio
Lara Ramos Aceves Fernández

February 2, 2020
Contents
1 Introduction 2
1.1 Crossword Puzzle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Theoretical Framework 2
2.1 Divide and Conquer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

3 Methods and Materials 3

4 Pseudo-code and Flow Diagram 3

5 Development 4

6 Results 5
6.1 Test with crossword puzzle in English . . . . . . . . . . . . . . . . . . . . . . . . . . 5
6.2 Test with crossword puzzle in Spanish . . . . . . . . . . . . . . . . . . . . . . . . . . 7

7 Discussion 8

8 Commented Code 9

9 Conclusions 9

10 References 10

Appendices 11

A Commented Code 11

1
Crossword Puzzle Solver

1 Introduction
In this assignment a crossword puzzle solver program is design and implemented. The algorithm
approach used was divide and conquer applied through recursion. The practical implementation
was made in MATLAB R2018b ®.

1.1 Crossword Puzzle


A crossword puzzle is a word game or problem represented in a rectangular grid of white spaces
and black squares. In Figure 1 a crossword puzzle is shown. The objective is to fill the white
spaces with words, where each letter of the word should occupy one white space, no white spaces
should be left empty nor words incomplete. The words are written from left-to-right and from
top-to-bottom. The shaded squares are used to separate the words or phrases

Figure 1: Empty crossword puzzle.

The crossword puzzle used to implement and test the program is the one shown in Figure 1,
and the set of words to complete it are displayed in the Code Snippet 1.

Code Snippet 1: Set of words to be used in crossword.

1 ant, end, big, car, bus, has, had, tar, book, bugs, boot, boom, fuse, seek,
,→ have, hold, lane, look, live, year, ginger, matrix.

2 Theoretical Framework
In this section theory about the strategy used to solve puzzle is explained.

2.1 Divide and Conquer


Divide and conquer is an approach used in algorithm design which consists of two stages

ˆ Divide: A problem is divided into sub-problems which are easier of faster to solve.

Theoretical Framework 2 Armando Lara


Crossword Puzzle Solver

ˆ Conquer: The obtained sub-problem from the previous step is solved.

With based on the two previously described steps, sometimes it is needed a third step which
consists of gathering the solutions and generate the solution to the bigger problem.

2.2 Recursion
Recursion is an algorithm approach which a function, method or sequence of steps calls itself within
itself. One basic example of this notion is the Fibonacci sequence where the following number in
the sequence is the sum of the two previous numbers, this is shown in Equation 1.

f (n) = f (n − 1) + f (n − 2) (1)
Every recursion implementation is formed of two parts

ˆ Base cases: An initial case or cases which can be solved without recursion.
ˆ Recursive case: For the cases that are to be solved recursively, the recursive call must always
be to a case that makes progress toward a base case.

One of the advantages of recursion implementation is that it can simplify the solution to a
problem in an intuitive and elegant manner. However, one should be cautious in its use when
efficiency is demanded, i.e., when recursion is applied each recursive case is one step further which
consumes more memory in a stack data structure. Each solution approach with recursion can
be implemented with more efficient iterative methods, nevertheless as efficiency is not our main
concern in this work, recursion is applied.

3 Methods and Materials


The method used to solve the problem was a combination of the two approaches described in the
theoretical framework in Section 2, i.e., divide and conquer is applied in the sense that the initial
crossword will be divided into a “smaller” problem, such “smaller” is solved in a recursive step.
The idea is to try to fit a word from the word set into one of the white spaces, once one
word perfectly fits into the spaces a new crossword with one word less is generated. Then, the
same approach is applied in the new “smaller” crossword. It can be said that the new generated
crossword is smaller in the sense that one word has been already placed, therefore there are less
white spaces to fill.

4 Pseudo-code and Flow Diagram


The pseudo-code of the algorithm is shown in Code Snippet 2 and the flow diagram is displayed
in the Figure 2.

Pseudo-code and Flow Diagram 3 Armando Lara


Crossword Puzzle Solver

Code Snippet 2: Label map file contents.

1 start with first word from set of words


2 if crossword is not complete
3 try to fit the word vertically or horizontally
4 if word fits somewhere
5 call this same function with the word placed and move on
,→ to next word
6 else
7 call this same function but move on to next word
8 else
9 print solved crossword

Figure 2: Algorithm flowchart.

5 Development
The implementation of the algorithm was made in MATLAB®code. It consists of four functions:

ˆ One function to try to fit a word horizontally into the crossword in a certain position x, y.
ˆ One function to try to fit a word vertically into the crossword in a certain position x, y.

Development 4 Armando Lara


Crossword Puzzle Solver

ˆ One function to check if the crossword is already solved and one recursive function to solve
the puzzle starting from a certain word in the set of words.

The representation of the crossword grid and the set of words that can be used are shown as
code in the Code Snippet 3 and Figure 3.

Code Snippet 3: Crossword and dictionary representation in code.

1 % crossword configuration
2 % an asterisk represents a black square
3 % a question mark represents a white square
4 crossword = ['?' '*' '?' '*' '*'; '?' '*' '?' '*' '*'; '?' '?' '?' '?' '*';
,→ '?' '*' '?' '*' '*'; '*' '*' '?' '?' '?'; '*' '*' '?' '*' '*'];
5

6 % set of words
7 dictionary = ["ant" "end" "big" "car" "bus" "has" "had" "tar" "book" "bugs"
,→ "boot" "boom" "fuse" "seek" "have" "hold" "lane" "look" "live" "year"
,→ "ginger" "matrix"];

Figure 3: Crossword printed in MATLAB®.

Notice that the search method implemented in this program is very similar to that the depth-
first-search algorithm when going through binary trees, such search method is represented in
Figure 4. In other words, in this implementation, every word which is fitted into white spaces and
a recursive function called is analogous to progress a depth level in the depth-first-search.

6 Results
6.1 Test with crossword puzzle in English
The crossword puzzle solver program worked correctly and returned in console a unique found
solution. The solution is shown in Figure 5.
As the search method is similar to a depth-first-search approach, during debugging there were
visible several attempts of the program to complete the crossword although not completely reaching
the objective. After this attempts the search continued through other words (or children). In

Results 5 Armando Lara


Crossword Puzzle Solver

Figure 4: Depth-first-search method.

Figure 5: Crossword completed.

Figure 6 are shown several unsuccessful search paths derived from placing first the word “ant” in
the crossword.

Figure 6: Iterative path which led to no solution.

Results 6 Armando Lara


Crossword Puzzle Solver

In Figure 7 some states of the crossword during search within the “end” are shown, the cross-
words on the top are result of unsuccessful sub-searches, but the crosswords on the bottom are the
path followed when the solution was found.

Figure 7: Iterative path which led to solution.

6.2 Test with crossword puzzle in Spanish


A crossword puzzle in Spanish was also created in order to test the program. This new crossword
puzzle was made with several correct solutions in order to challenge the program to find all possible
solutions. The crossword in Spanish is shown in Figure 8. The set of words in Spanish which have
to be used to complete the crossword are shown in Code Snippet 4.

Figure 8: Crossword puzzle in Spanish.

Results 7 Armando Lara


Crossword Puzzle Solver

The set of words in Spanish which have to be used to complete the crossword are shown in
Code Snippet 4.

Code Snippet 4: Set of words to be used in crossword.

1 perro, cono, gato, raton, mono, tigre, leon, buho, peon, cerdo.

In order to run this test, the corresponding variables crossword and dictionary for the
crossword in Spanish in the code in Appendix A in Code Snippet 5 were uncommented, were as
the same variables for the crossword in English.
There were found 8 different correct solutions to the crossword which are shown in Figure 9.
The program successfully returned all possible solutions.

Figure 9: All solutions of crossword puzzle in Spanish.

7 Discussion
In this work a program which solves a crossword puzzle given a set of words was implemented. The
approach taken was to search the solution by trying to fit each word iterating thorough the set
of given words through recursion. It was observed that although the recursive approach considers
several combinations, the program will provide all the solutions. One of the main challenges to
make such feature possible. Another challenge was to make the program find the possible solutions
despite there could be some word within the set of words which will not be used in the crossword,
i.e., to find a way to detect when a word is unuseful and then pass it. Finally, the most difficult
part was to figure out a way to keep in memory the progress made when one word has been fit

Discussion 8 Armando Lara


Crossword Puzzle Solver

in the crossword and then the rest are left, recursion eases this task by elegantly and internally
keeping the local variables saved in a stack data structure so that they could be available when
returning to the calling context.

8 Commented Code
The complete commented code of this program is included in Appendix A in Code Snippet 5.

9 Conclusions
It is important to try to solve games or problems by using traditional data structures or algorithms.
Gaining experience by understanding and solving the problem with these tools could provide come
insights when trying to solve the problem with more advanced or suited techniques. It will be
interesting to revisit this assigment after finalizing the course in order to know which technique
could be applied to the resolution and compare aspects among approaches and solutions.
Barroso, Clidaras, and Hölzle (2013) (Data Center Handbook , 2014) (Alger, 2012)

Conclusions 9 Armando Lara


Crossword Puzzle Solver

10 References
Alger, D. (2012). The art of the data center: A look inside the world’s most innovative and
compelling computing environments (1st ed.). USA: Prentice Hall Press.
Barroso, L. A., Clidaras, J., & Hölzle, U. (2013). The datacenter as a computer: An in-
troduction to the design of warehouse-scale machines, second edition. Synthesis Lec-
tures on Computer Architecture, 8 (3), 1-154. Retrieved from https://doi.org/10.2200/
S00516ED2V01Y201306CAC024 doi: 10.2200/S00516ED2V01Y201306CAC024
Data center handbook. (2014). John Wiley & Sons, Ltd. Retrieved from https://onlinelibrary
.wiley.com/doi/abs/10.1002/9781118937563.fmatter doi: 10.1002/9781118937563
.fmatter

References 10 Armando Lara


Crossword Puzzle Solver

Appendices
A Commented Code
Code Snippet 5: Commented MATLAB code.

1 clc
2 clear
3

4 % crossword configuration
5 % an asterisk represents a black square
6 % a question mark represents a white square
7 % crossword in English
8 crossword = ['?' '*' '?' '*' '*'; '?' '*' '?' '*' '*'; '?' '?' '?' '?' '*';
,→ '?' '*' '?' '*' '*'; '*' '*' '?' '?' '?'; '*' '*' '?' '*' '*'];
9 % crossword in Spanish
10 %crossword = ['' '*' '*' '*' ''; '' '*' '*' '*' ''; '' '' '' '' ''; '' '*'
,→ '' '*' ''; '' '*' '' '*' '*'; '*' '*' '' '*' '*'; '*' '' '' '' '?'];
11

12 % set of words
13 % dictionary in English
14 dictionary = ["ant" "end" "big" "car" "bus" "has" "had" "tar" "book" "bugs"
,→ "boot" "boom" "fuse" "seek" "have" "hold" "lane" "look" "live" "year"
,→ "ginger" "matrix"];
15 % dictionary in Spanish
16 %dictionary = ["perro" "oso" "gato" "raton" "mono" "tigre" "leon" "buho"
,→ "vaca" "cerdo"];
17 print_crossword(crossword);
18 % solving crossword starting from first word
19 solve_crossword(crossword, dictionary, 1);
20

21 % functions which prints the complete crossword


22 function print_crossword(crossword)
23 % iterating through 2D crossword to print each element
24 for i = 1:size(crossword, 1)
25 for j = 1:size(crossword, 2)
26 fprintf('%c',crossword(i,j))
27 fprintf('%c',' ')
28 end
29 fprintf('\n');
30 end
31 % printing new line for a new row

Commented Code 11 Armando Lara


Crossword Puzzle Solver

32 fprintf('\n');
33 end
34

35 % function to try to fix a word horizontally into a position


36 function crossword = fit_word_horizontally(crossword, word, x, y)
37 word_length = strlength(word);
38 % trying to fit the word letter by letter into the x,y position
39 % if it does not fit, a mark N is placed in the return crossword
40 for i = 0:word_length-1
41 if crossword(x, y+i) == '?' || crossword(x, y+i) == word(i+1)
42 crossword(x, y+i) = word(i+1);
43 else
44 crossword(1,1) = 'N';
45 return;
46 end
47 end
48 % checking if word fits perfectly
49 % checking if position before the beginning of the word is empty
50 if y ~= 1
51 if crossword(x, y-1) ~= '*'
52 crossword(1,1) = 'N';
53 return;
54 end
55 end
56 % checking if position after ending of the word is empty
57 if y+word_length <= size(crossword, 2)
58 if crossword(x, y+word_length) ~= '*'
59 crossword(1,1) = 'N';
60 return;
61 end
62 end
63 end
64

65 % function to try to fit a word vertically into a position


66 function crossword = fit_word_vertically(crossword, word, x, y)
67 word_length = strlength(word);
68 % trying to fit the word letter by letter into the x,y position
69 % if it does not fit, a mark N is placed in the return crossword
70 for i = 0:word_length-1
71 if crossword(x+i, y) == '?' || crossword(x+i, y) == word(i+1)
72 crossword(x+i, y) = word(i+1);
73 else
74 crossword(1,1) = 'N';

Commented Code 12 Armando Lara


Crossword Puzzle Solver

75 return;
76 end
77 end
78 % checking if word fits perfectly
79 % checking if position before the beginning of the word is empty
80 if x ~= 1
81 if crossword(x-1, y) ~= '*'
82 crossword(1,1) = 'N';
83 return;
84 end
85 end
86 % checking if position after ending of the word is empty
87 if x+word_length <= size(crossword, 1)
88 if crossword(x+word_length, y) ~= '*'
89 crossword(1,1) = 'N';
90 return;
91 end
92 end
93 end
94

95 % function to verify if crossword has been completed


96 function is_complete = is_crossword_complete(crossword)
97 is_complete = true;
98 % checking through all squares if a question mark is still contained
99 for i = 1:size(crossword, 1)
100 for j = 1:size(crossword, 2)
101 if crossword(i,j) == '?'
102 is_complete = false;
103 return;
104 end
105 end
106 end
107 end
108

109 % recursive function to try to solve the crossword


110 function crossword = solve_crossword(crossword, dictionary, word_index)
111 % checking if crossword has been completed
112 if is_crossword_complete(crossword)
113 print_crossword(crossword);
114 % checking if there are still words to be tested in dictionary
115 elseif word_index <= size(dictionary, 2)
116 word_string = dictionary(word_index);
117 word = convertStringsToChars(word_string);

Commented Code 13 Armando Lara


Crossword Puzzle Solver

118 % iterating thourgh crossword to check if word fits horizontally


,→ somewhere
119 for i = 1:size(crossword, 1)
120 for j = 1:size(crossword, 2)-strlength(word)+1
121 temp_crossword = fit_word_horizontally(crossword, word, i,
,→ j);
122 % if the word fits somewhere, call recursive function to
,→ solve new crossword
123 if temp_crossword(1,1) ~= 'N'
124 solve_crossword(temp_crossword, dictionary,
,→ word_index+1);
125 end
126 end
127 end
128 % iterating thourgh crossword to check if word fits vertically
,→ somewhere
129 for i = 1:size(crossword, 1)-strlength(word)+1
130 for j = 1:size(crossword, 2)
131 temp_crossword = fit_word_vertically(crossword, word, i, j);
132 % if the word fits somewhere, call recursive function to
,→ solve new crossword
133 if temp_crossword(1,1) ~= 'N'
134 solve_crossword(temp_crossword, dictionary,
,→ word_index+1);
135 end
136 end
137 end
138 % if the word didn not fit anywhere in crossword, move on to next
,→ word and call recursive function
139 if word_index+1 <= size(dictionary, 2)
140 solve_crossword(crossword, dictionary, word_index+1);
141 end
142 end
143 end

Commented Code 14 Armando Lara

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy