Before I write something about the problem, I need to let you know:
Problem:
Given: a wordlist and a "grid", for example:
grid (X means any letter):
X X
XXXX
X X
XXXX
wordlist:
ccaa
baca
baaa
bbbb
You have to find example "solution" - is it possible to fit words from wordlist into a given grid? If there is at least one solution, print one (whichever correct). If no - print message, that there is no possible solution. For given example, there is a solution:
b c
baca
b a
baaa
It's hard for me to write everything that I've already tried (because English is not my native language and I also have a lot of papers with wrong ideas).
My naive algorithm works something like this:
First word needs just proper length, so find any (first?) word with proper length (I'm going to use given example grid and wordlist to demonstrate what I think):
c X
cXXX
a X
aXXX
For first common letter (on the crossing of 2 words) find any (first) word, that fit the grid (so, have proper length and common letter on proper position). If there is no such words, go back to (1) and take another first word. In the orginal example there is no word which starts with "c", so we go back to (1) and select next words (this step repeats few times until we have "bbbb" for 1st word). Now we have:
b X
bXXX
b X
bXXX
And we're looking for a word(s) which starts with "b", for example:
b X
baca
b X
bXXX
General process: try to find pairs of words which fit to the given grid. If there is no such words, go back to previous step and use another combination - if there is no such - there is no solution.
Everything above is chaotic, I hope that you understand at least problem description. I wrote a draft of an algorithm, but I'm not sure if that works and how to properly code this (in my case: c++). Moreover, there are cases (even in example above) that we need to find a word that depends on 2 or more other words.
Maybe I just can't see something obvious, maybe I'm too stupid, maybe... Well, I really tried to solve this problem. I don't know English well enough to precisely describe what I think about this problem, so I can't put here all my notes (I tried to describe one idea and it was hard). Believe or not, I've spend many long hours trying to figure out solution and I have almost nothing...
If you can describe a solution, or give a hint how to solve this problem, I would really appreciate this.
The corssword problem is NP-Complete, so your best shot is brute force: just try all possibilities, and stop when a possibility is a valid. Return failure when you exhausted all possible solutions.
reduction that prove that this problem is NP-Complete can be found in this article section 3.3
Brute force solution using backtracking could be: [pseudo code]:
solve(words,grid):
if words is empty:
if grid.isValudSol():
return grid
else:
return None
for each word in words:
possibleSol <- grid.fillFirst(word)
ret <- solve(words\{word},possibleSol)
if (ret != None):
return ret
return None
in here we assume fillFirst()
is a function that fills the first space which was not already filled [first can actually be any consistent ordering of the empty spaces, but it should be consistent!] , and isValid()
is returning a boolean indicating if the given grid is a valid solution.
I wrote a progam this morning. Here is a slightly more efficient version in pseudocode:
#pseudo-code
solve ( words , grid ) : solve ( words , grid , None )
solve ( words , grid , filledPositions ) :
if words is empty :
if grid is solved :
return grid
else :
raise ( no solution )
for ( current position ) as the first possible word position in grid
that is not of filledPositions :
# note : a word position must have no letters before the word
# 'before the word' means, eg, to the left of a horizontal word
# no letters may be placed over a ' '
# no letters may be placed off the grid
# note : a location may have two 'positions' : one across , one down
for each word in words :
make a copy of grid
try :
fill grid copy, with the current word, at the current position
except ( cannot fill position ) :
break
try :
return solve ( words\{word} , grid copy ,
filledPositions+{current position} )
except ( no solution ) :
break
raise ( no solution )
Here is my code for fitting a word horizontally in the grid : http://codepad.org/4UXoLcjR
Here are some things I used from the STL:
http://www.cplusplus.com/reference/algorithm/remove_copy/
http://www.cplusplus.com/reference/stl/vector/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With