Find all possible paths in a Matrix












1












$begingroup$


I'm looking for algorithms to find all paths in a 4 x 4 matrix.

The rules are as follows




  • You can move in any direction (up, down, left, right, and diagonally)

  • The next square in the path must be a neighbour to the current square

  • Each square can only be used once

  • Each square in the path must be in the bounds of the matrix

  • No squares are restricted

  • Start squares don't matter

  • End squares don't matter


Here is an example of a valid path



  _ _ _ _ 
| |6| |8|
|-|-|-|-|
|5| |7|9|
|-|-|-|-|
|3|4|0| |
|-|-|-|-|
|2|1| | |
|-|-|-|-|









share|cite|improve this question











$endgroup$












  • $begingroup$
    Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
    $endgroup$
    – DanielV
    Feb 13 '14 at 18:44










  • $begingroup$
    @DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:51












  • $begingroup$
    @DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:57








  • 3




    $begingroup$
    Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
    $endgroup$
    – Ross Millikan
    Feb 13 '14 at 19:05










  • $begingroup$
    Also load your dictionary into a trie and filter while you enumerate paths instead of after.
    $endgroup$
    – DanielV
    Feb 13 '14 at 19:39
















1












$begingroup$


I'm looking for algorithms to find all paths in a 4 x 4 matrix.

The rules are as follows




  • You can move in any direction (up, down, left, right, and diagonally)

  • The next square in the path must be a neighbour to the current square

  • Each square can only be used once

  • Each square in the path must be in the bounds of the matrix

  • No squares are restricted

  • Start squares don't matter

  • End squares don't matter


Here is an example of a valid path



  _ _ _ _ 
| |6| |8|
|-|-|-|-|
|5| |7|9|
|-|-|-|-|
|3|4|0| |
|-|-|-|-|
|2|1| | |
|-|-|-|-|









share|cite|improve this question











$endgroup$












  • $begingroup$
    Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
    $endgroup$
    – DanielV
    Feb 13 '14 at 18:44










  • $begingroup$
    @DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:51












  • $begingroup$
    @DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:57








  • 3




    $begingroup$
    Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
    $endgroup$
    – Ross Millikan
    Feb 13 '14 at 19:05










  • $begingroup$
    Also load your dictionary into a trie and filter while you enumerate paths instead of after.
    $endgroup$
    – DanielV
    Feb 13 '14 at 19:39














1












1








1


1



$begingroup$


I'm looking for algorithms to find all paths in a 4 x 4 matrix.

The rules are as follows




  • You can move in any direction (up, down, left, right, and diagonally)

  • The next square in the path must be a neighbour to the current square

  • Each square can only be used once

  • Each square in the path must be in the bounds of the matrix

  • No squares are restricted

  • Start squares don't matter

  • End squares don't matter


Here is an example of a valid path



  _ _ _ _ 
| |6| |8|
|-|-|-|-|
|5| |7|9|
|-|-|-|-|
|3|4|0| |
|-|-|-|-|
|2|1| | |
|-|-|-|-|









share|cite|improve this question











$endgroup$




I'm looking for algorithms to find all paths in a 4 x 4 matrix.

The rules are as follows




  • You can move in any direction (up, down, left, right, and diagonally)

  • The next square in the path must be a neighbour to the current square

  • Each square can only be used once

  • Each square in the path must be in the bounds of the matrix

  • No squares are restricted

  • Start squares don't matter

  • End squares don't matter


Here is an example of a valid path



  _ _ _ _ 
| |6| |8|
|-|-|-|-|
|5| |7|9|
|-|-|-|-|
|3|4|0| |
|-|-|-|-|
|2|1| | |
|-|-|-|-|






matrices algorithms recursive-algorithms






share|cite|improve this question















share|cite|improve this question













share|cite|improve this question




share|cite|improve this question








edited Feb 13 '14 at 19:01







TheLukeMcCarthy

















asked Feb 13 '14 at 18:41









TheLukeMcCarthyTheLukeMcCarthy

1063




1063












  • $begingroup$
    Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
    $endgroup$
    – DanielV
    Feb 13 '14 at 18:44










  • $begingroup$
    @DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:51












  • $begingroup$
    @DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:57








  • 3




    $begingroup$
    Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
    $endgroup$
    – Ross Millikan
    Feb 13 '14 at 19:05










  • $begingroup$
    Also load your dictionary into a trie and filter while you enumerate paths instead of after.
    $endgroup$
    – DanielV
    Feb 13 '14 at 19:39


















  • $begingroup$
    Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
    $endgroup$
    – DanielV
    Feb 13 '14 at 18:44










  • $begingroup$
    @DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:51












  • $begingroup$
    @DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
    $endgroup$
    – TheLukeMcCarthy
    Feb 13 '14 at 18:57








  • 3




    $begingroup$
    Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
    $endgroup$
    – Ross Millikan
    Feb 13 '14 at 19:05










  • $begingroup$
    Also load your dictionary into a trie and filter while you enumerate paths instead of after.
    $endgroup$
    – DanielV
    Feb 13 '14 at 19:39
















$begingroup$
Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
$endgroup$
– DanielV
Feb 13 '14 at 18:44




$begingroup$
Are you trying to count the number of paths? Are you trying to enumerate each path? Are any squares restricted? Is this homework? Do the start and end squares matter? Is this homework?
$endgroup$
– DanielV
Feb 13 '14 at 18:44












$begingroup$
@DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
$endgroup$
– TheLukeMcCarthy
Feb 13 '14 at 18:51






$begingroup$
@DanielV No this is not homework. I'm working on a creating a coding kata to help people think about and improve the performance of their code. This is going to be used in a word game like Boggle and I want to find all possible words / paths. The solution I have now runs fast for paths of length 6 (about .5 of a second) but takes 36 minutes when getting paths of length 7. The start and end squares don't matter as I was thinking of starting from each square in turn to get all paths from each square.
$endgroup$
– TheLukeMcCarthy
Feb 13 '14 at 18:51














$begingroup$
@DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
$endgroup$
– TheLukeMcCarthy
Feb 13 '14 at 18:57






$begingroup$
@DanielV also as long as square is within the bounds of the matrix it can be in the path, I have updated the question to make it clearer.
$endgroup$
– TheLukeMcCarthy
Feb 13 '14 at 18:57






3




3




$begingroup$
Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
$endgroup$
– Ross Millikan
Feb 13 '14 at 19:05




$begingroup$
Given a path of length $6$, there are at most $7$ paths of length $7$ that start with it. It seems strange that the increase in time is so large-just find the squares you can extend a path of length $6$ into, then check if that square has been used.
$endgroup$
– Ross Millikan
Feb 13 '14 at 19:05












$begingroup$
Also load your dictionary into a trie and filter while you enumerate paths instead of after.
$endgroup$
– DanielV
Feb 13 '14 at 19:39




$begingroup$
Also load your dictionary into a trie and filter while you enumerate paths instead of after.
$endgroup$
– DanielV
Feb 13 '14 at 19:39










1 Answer
1






active

oldest

votes


















0












$begingroup$

EDIT - after writing this answer, I realised that I had forgotten that the question was not specifically about Boggle, but in the comments it turned out that the OP and I were talking about Boggle specifically.



EDIT 2 - I have posted a code solution of this in Ruby on Code Review: https://codereview.stackexchange.com/q/203292/22855



I figured out an algorithm on my own, because it was a lot of fun.



Not being well-versed in algorithms, I would love to know if this algorithm has a name. (Let me know in the comments or edit this answer if you know it, please).



(Note that we have a list of valid words - a dictionary - from which to look up chains of letters).




  • Start at a given position on the board

  • Put the position on a stack. The stack of positions represents a chain of letters (every position on the board has a letter, remember)

  • Once the stack has two or more positions, check whether there are any words starting with those letters. If there are none, pop the stack and return (i.e. abandon the current search path - there is no point going down it further if it won't result in a valid word)

  • Once the stack has three or more positions, check the letters (from the positions in the stack) against the dictionary and, if the word exists, add it to a set of words collected.

  • Cycle through all the possible next positions in turn (N, NE, E, SE, S, SW, W, NW)

  • If the next position is out of bounds (off the board) or is already somewhere in the stack, skip that position

  • For a valid next position, the routine calls itself (i.e. starts at second point above) with the new position

  • Before ending and returning to the previous call, the position is popped off the stack


The whole process is repeated for every position on the board as a starting position, but during processing, paths are aborted, as mentioned, to avoid looking through every possible path for a word that doesn't exist.



Also, in my implementation, my input board has "Q" as a single letter, but I have special handling for "Qu" by pushing a "U" after the "Q" on to the stack and checking to pop a "Q" in addition. ("Qu" counts as two letters in Boggle, but takes up a single side of a cube). That's just specific to my implementation, but it could probably be handled in other ways.






share|cite|improve this answer











$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "69"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    noCode: true, onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f675389%2ffind-all-possible-paths-in-a-matrix%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0












    $begingroup$

    EDIT - after writing this answer, I realised that I had forgotten that the question was not specifically about Boggle, but in the comments it turned out that the OP and I were talking about Boggle specifically.



    EDIT 2 - I have posted a code solution of this in Ruby on Code Review: https://codereview.stackexchange.com/q/203292/22855



    I figured out an algorithm on my own, because it was a lot of fun.



    Not being well-versed in algorithms, I would love to know if this algorithm has a name. (Let me know in the comments or edit this answer if you know it, please).



    (Note that we have a list of valid words - a dictionary - from which to look up chains of letters).




    • Start at a given position on the board

    • Put the position on a stack. The stack of positions represents a chain of letters (every position on the board has a letter, remember)

    • Once the stack has two or more positions, check whether there are any words starting with those letters. If there are none, pop the stack and return (i.e. abandon the current search path - there is no point going down it further if it won't result in a valid word)

    • Once the stack has three or more positions, check the letters (from the positions in the stack) against the dictionary and, if the word exists, add it to a set of words collected.

    • Cycle through all the possible next positions in turn (N, NE, E, SE, S, SW, W, NW)

    • If the next position is out of bounds (off the board) or is already somewhere in the stack, skip that position

    • For a valid next position, the routine calls itself (i.e. starts at second point above) with the new position

    • Before ending and returning to the previous call, the position is popped off the stack


    The whole process is repeated for every position on the board as a starting position, but during processing, paths are aborted, as mentioned, to avoid looking through every possible path for a word that doesn't exist.



    Also, in my implementation, my input board has "Q" as a single letter, but I have special handling for "Qu" by pushing a "U" after the "Q" on to the stack and checking to pop a "Q" in addition. ("Qu" counts as two letters in Boggle, but takes up a single side of a cube). That's just specific to my implementation, but it could probably be handled in other ways.






    share|cite|improve this answer











    $endgroup$


















      0












      $begingroup$

      EDIT - after writing this answer, I realised that I had forgotten that the question was not specifically about Boggle, but in the comments it turned out that the OP and I were talking about Boggle specifically.



      EDIT 2 - I have posted a code solution of this in Ruby on Code Review: https://codereview.stackexchange.com/q/203292/22855



      I figured out an algorithm on my own, because it was a lot of fun.



      Not being well-versed in algorithms, I would love to know if this algorithm has a name. (Let me know in the comments or edit this answer if you know it, please).



      (Note that we have a list of valid words - a dictionary - from which to look up chains of letters).




      • Start at a given position on the board

      • Put the position on a stack. The stack of positions represents a chain of letters (every position on the board has a letter, remember)

      • Once the stack has two or more positions, check whether there are any words starting with those letters. If there are none, pop the stack and return (i.e. abandon the current search path - there is no point going down it further if it won't result in a valid word)

      • Once the stack has three or more positions, check the letters (from the positions in the stack) against the dictionary and, if the word exists, add it to a set of words collected.

      • Cycle through all the possible next positions in turn (N, NE, E, SE, S, SW, W, NW)

      • If the next position is out of bounds (off the board) or is already somewhere in the stack, skip that position

      • For a valid next position, the routine calls itself (i.e. starts at second point above) with the new position

      • Before ending and returning to the previous call, the position is popped off the stack


      The whole process is repeated for every position on the board as a starting position, but during processing, paths are aborted, as mentioned, to avoid looking through every possible path for a word that doesn't exist.



      Also, in my implementation, my input board has "Q" as a single letter, but I have special handling for "Qu" by pushing a "U" after the "Q" on to the stack and checking to pop a "Q" in addition. ("Qu" counts as two letters in Boggle, but takes up a single side of a cube). That's just specific to my implementation, but it could probably be handled in other ways.






      share|cite|improve this answer











      $endgroup$
















        0












        0








        0





        $begingroup$

        EDIT - after writing this answer, I realised that I had forgotten that the question was not specifically about Boggle, but in the comments it turned out that the OP and I were talking about Boggle specifically.



        EDIT 2 - I have posted a code solution of this in Ruby on Code Review: https://codereview.stackexchange.com/q/203292/22855



        I figured out an algorithm on my own, because it was a lot of fun.



        Not being well-versed in algorithms, I would love to know if this algorithm has a name. (Let me know in the comments or edit this answer if you know it, please).



        (Note that we have a list of valid words - a dictionary - from which to look up chains of letters).




        • Start at a given position on the board

        • Put the position on a stack. The stack of positions represents a chain of letters (every position on the board has a letter, remember)

        • Once the stack has two or more positions, check whether there are any words starting with those letters. If there are none, pop the stack and return (i.e. abandon the current search path - there is no point going down it further if it won't result in a valid word)

        • Once the stack has three or more positions, check the letters (from the positions in the stack) against the dictionary and, if the word exists, add it to a set of words collected.

        • Cycle through all the possible next positions in turn (N, NE, E, SE, S, SW, W, NW)

        • If the next position is out of bounds (off the board) or is already somewhere in the stack, skip that position

        • For a valid next position, the routine calls itself (i.e. starts at second point above) with the new position

        • Before ending and returning to the previous call, the position is popped off the stack


        The whole process is repeated for every position on the board as a starting position, but during processing, paths are aborted, as mentioned, to avoid looking through every possible path for a word that doesn't exist.



        Also, in my implementation, my input board has "Q" as a single letter, but I have special handling for "Qu" by pushing a "U" after the "Q" on to the stack and checking to pop a "Q" in addition. ("Qu" counts as two letters in Boggle, but takes up a single side of a cube). That's just specific to my implementation, but it could probably be handled in other ways.






        share|cite|improve this answer











        $endgroup$



        EDIT - after writing this answer, I realised that I had forgotten that the question was not specifically about Boggle, but in the comments it turned out that the OP and I were talking about Boggle specifically.



        EDIT 2 - I have posted a code solution of this in Ruby on Code Review: https://codereview.stackexchange.com/q/203292/22855



        I figured out an algorithm on my own, because it was a lot of fun.



        Not being well-versed in algorithms, I would love to know if this algorithm has a name. (Let me know in the comments or edit this answer if you know it, please).



        (Note that we have a list of valid words - a dictionary - from which to look up chains of letters).




        • Start at a given position on the board

        • Put the position on a stack. The stack of positions represents a chain of letters (every position on the board has a letter, remember)

        • Once the stack has two or more positions, check whether there are any words starting with those letters. If there are none, pop the stack and return (i.e. abandon the current search path - there is no point going down it further if it won't result in a valid word)

        • Once the stack has three or more positions, check the letters (from the positions in the stack) against the dictionary and, if the word exists, add it to a set of words collected.

        • Cycle through all the possible next positions in turn (N, NE, E, SE, S, SW, W, NW)

        • If the next position is out of bounds (off the board) or is already somewhere in the stack, skip that position

        • For a valid next position, the routine calls itself (i.e. starts at second point above) with the new position

        • Before ending and returning to the previous call, the position is popped off the stack


        The whole process is repeated for every position on the board as a starting position, but during processing, paths are aborted, as mentioned, to avoid looking through every possible path for a word that doesn't exist.



        Also, in my implementation, my input board has "Q" as a single letter, but I have special handling for "Qu" by pushing a "U" after the "Q" on to the stack and checking to pop a "Q" in addition. ("Qu" counts as two letters in Boggle, but takes up a single side of a cube). That's just specific to my implementation, but it could probably be handled in other ways.







        share|cite|improve this answer














        share|cite|improve this answer



        share|cite|improve this answer








        edited Sep 7 '18 at 10:43

























        answered Sep 7 '18 at 10:14









        mydoghaswormsmydoghasworms

        10816




        10816






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Mathematics Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f675389%2ffind-all-possible-paths-in-a-matrix%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Plaza Victoria

            In PowerPoint, is there a keyboard shortcut for bulleted / numbered list?

            How to put 3 figures in Latex with 2 figures side by side and 1 below these side by side images but in...