-2

I am looking for an efficient word search algorithm. If you can help me come up with it it would be even better

a h c k 
x r j i
b v t l
c y q s

and I want to find 'arts' . If 'stra' was also a valid word I want that to be found as well. (vertical, horizontal, diagonal and reverse). I came up with a few algorithms but thy don't seem efficient and consume long coding. First one included using find() to get the first letter and look at that column or rows.

Arijoon
  • 1,709
  • 2
  • 19
  • 28
  • 2
    Show what you have tried so far. – Hanady Dec 13 '13 at 12:30
  • 3
    This is an university assignment, right? Two of your colleagues have been here before. First read [here](http://stackoverflow.com/questions/20406257/does-matlab-have-a-function-similar-to-strfind/20406898#20406898), then [here](http://stackoverflow.com/questions/20380587/is-it-possible-to-rotate-a-matrix-by-45-degrees-in-matlab/20381889#20381889) and finally [here](http://stackoverflow.com/questions/20334461/wordsearch-algorithm-in-matlab). If you still have questions, tell us exactly where you got stuck. – thewaywewalk Dec 13 '13 at 12:50
  • I am not stuck on horizontal or vertical search. I am stuck on diagonal as I said on my problem example. I was wondering if I have to extract the whole diagonal and use strfind or is there a more efficient way. – Arijoon Dec 13 '13 at 12:57
  • 1
    First show those few algorithms that you have and how much time they consume, otherwise it will be hard to indicate improvements. Keep in mind that there are only (N+M-1)*2 diagonals that need to be evaluated in both directions. I can't imagine them being that hard to extract. – Dennis Jaheruddin Dec 13 '13 at 13:18
  • possible duplicate of [Using strfind in Matlab for different diagonal directions in a Matrix](http://stackoverflow.com/questions/20551661/using-strfind-in-matlab-for-different-diagonal-directions-in-a-matrix) – Daniel Dec 13 '13 at 16:11
  • possible duplicate of [Searching for a word in a grid](http://stackoverflow.com/questions/20530946/searching-for-a-word-in-a-grid) – chappjc Dec 13 '13 at 18:03

1 Answers1

4

Here's one way:

%// Example word grid
C = [
    'a' 'h' 'c' 'k' 'r'
    'x' 'r' 'j' 'i' 'p'
    'b' 'v' 't' 'l' 'q'
    'a' 'y' 'q' 's' 'o'];

%// Your search term
target = 'arts';

%// Optionally, do some obvious checks here. 
%//  - length of the search string may exceeds the grid's dimensions
%//  - there are no matches for the first letter
%//  - and similar

%// Form single cellstring containing all search directions
allDirections = [
    %{
    // horizontal, horizontal-reversed
    %}
    cellstr([C ; C(:,end:-1:1)])
    %{
    // vertical, vertical-reversed
    %}
    cellstr([C'; C(:,end:-1:1)']) 
    %{
    // Diagonal, top-left to bottom-right, and reversed
    %}
    arrayfun(@(ii){diag(C,ii)'}, -size(C,1)+2:size(C,2)-2)';
    arrayfun(@(ii){diag(C(end:-1:1,end:-1:1),ii)'}, -size(C,1)+2:size(C,2)-2)';
    %{
    // Diagonal, top-right to bottom-left, and reversed
    %}
    arrayfun(@(ii){diag(C(:,end:-1:1),ii)'}, -size(C,1)+2:size(C,2)-2)';
    arrayfun(@(ii){diag(C(end:-1:1,:),ii)'}, -size(C,1)+2:size(C,2)-2)';
];

%// And now just find the string
strfind(allDirections , target)

Of course, you could to improve (memory) efficiency by

  • doing the strfind on all the directions separately
  • doing 2 × strfind on the same direction, but with the target inverted
  • etc.

But aside from these relatively minor optimizations, I don't think you can do much better in MATLAB in practice.

A theoretically more efficient recursive, branch-and-bound type search roughly goes like this:

  • find all occurrences of the first letter
  • eliminate all of those occurrences that cannot satisfy the length of the target based on the dimensions of the grid
  • Search the neighborhoods of all hits for occurrences of the second letter
  • Eliminate occurrences based on length, etc.

(Don't forget to filter on direction after the second letter, as the hits for the second letter fixes the search directions)

As far as I can see, this would need a lot less reads and comparisons than my version. However, my guess would be that using canned routines (as I did) is going to be faster and less complicated than using (nested) loops. But I could be wrong.

Try. Profile. Learn. Smile. Correct me :)

Rody Oldenhuis
  • 36,880
  • 7
  • 47
  • 94
  • nice approach! but it's probably hard to tell where exactly the word started in the initial matrix, isn't it? And as far as I know from the similar questions, it's possible that one word appears several times. And also, as you just concatenate everything what happens if there is a "invalid" word over two lines like: C = [ a r ; t s]; it would get detetected by your algorithm, but is incorrect. Am I right? – thewaywewalk Dec 13 '13 at 13:36
  • @thewaywewalk: (a) that's true, although it's fairly easy to derive where the hit(s) occurred, since you have knowledge of which row in `allDirections` corresponds to which row/col/direction. (b) No. I'm concatenating whole rows of characters, not individual characters. Just print the `allDirections` to see what I mean. Each entry in that `cell` is a valid string abiding to the OP's rules. – Rody Oldenhuis Dec 13 '13 at 13:41