Find all possible paths in a Matrix
$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| | |
|-|-|-|-|
matrices algorithms recursive-algorithms
$endgroup$
|
show 13 more comments
$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| | |
|-|-|-|-|
matrices algorithms recursive-algorithms
$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
|
show 13 more comments
$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| | |
|-|-|-|-|
matrices algorithms recursive-algorithms
$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
matrices algorithms recursive-algorithms
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
|
show 13 more comments
$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
|
show 13 more comments
1 Answer
1
active
oldest
votes
$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.
$endgroup$
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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.
$endgroup$
add a comment |
$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.
$endgroup$
add a comment |
$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.
$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.
edited Sep 7 '18 at 10:43
answered Sep 7 '18 at 10:14
mydoghaswormsmydoghasworms
10816
10816
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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