Fastest path on a snakes and ladders boardShortest pathway across a snakes and ladders board (Update)Optimizing puzzle game involving sequence numbers10-faced dice-rolling gameSuper2048 (Google apac Test Problem)Number of unique sequences of 3 digits, given a length is equal to sumUnicode Chess PvP with Move ValidationGame of Quarto in Python — Barebones editionBattleship homework'Snakes and Ladders' gameCalculate knight movesRazzle Dazzle simulator

Approach sick days in feedback meeting

How do I become a better writer when I hate reading?

Can a 40amp breaker be used safely and without issue with a 40amp device on 6AWG wire?

How can I detect if I'm in a subshell?

Are soroban (Japanese abacus) classes worth doing?

Why is gun control associated with the socially liberal Democratic party?

Can an open source licence be revoked if it violates employer's IP?

Why not make one big CPU core?

The title "Mord mit Aussicht" explained

Boss making me feel guilty for leaving the company at the end of my internship

Is there a risk to write an invitation letter for a stranger to obtain a Czech (Schengen) visa?

...and then she held the gun

Looking for an iPhone app for working out chess problems

Does WiFi affect the quality of images downloaded from the internet?

My players want to use called-shots on Strahd

Leveling up and Getting Items!

Can artificial satellite positions affect tides?

Do items with curse of vanishing disappear from shulker boxes?

What is the difference between state-based effects and effects on the stack?

100-doors puzzle

Background for black and white chart

How would Japanese people react to someone refusing to say “itadakimasu” for religious reasons?

Arcane Tradition and Cost Efficiency: Learn spells on level-up, or learn them from scrolls/spellbooks?

Sakkāya-Ditthi and Self-View



Fastest path on a snakes and ladders board


Shortest pathway across a snakes and ladders board (Update)Optimizing puzzle game involving sequence numbers10-faced dice-rolling gameSuper2048 (Google apac Test Problem)Number of unique sequences of 3 digits, given a length is equal to sumUnicode Chess PvP with Move ValidationGame of Quarto in Python — Barebones editionBattleship homework'Snakes and Ladders' gameCalculate knight movesRazzle Dazzle simulator






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3












$begingroup$


I am not looking for a detailed review of this code as I am aware it is very inefficient. The main reason for posting this is to see if there is a better way to achieve my goal (I am certain there must be)



I have created code to find the fewest number of dice rolls that would permit someone to move from the first to last square on a snakes and ladders board. The player wins if they land on or go beyond the final square on the board. They start off the board at position -1.



My approach uses recursion so is OK for small boards. The moment the board reaches a size of 30+ it takes far too long to generate the solution.



Is there a better way to solve this problem



"""Module works out fastest way to traverse a snakes and ladders board"""
def roll_dice(position, roll_number, number_squares, snakes, ladders, list_moves=[]):
"""Roll the dice and then work out if the player can climb a ladder / has won"""
if position in ladders:
position = ladders[position]
if position >= number_squares - 1:
list_moves.append(roll_number)
return
for i in range(1, 7): #For each position roll the dice 6 times
if position + i in snakes:
continue # Forbid a dice-roll that lands on a snake
roll_dice(position + i, roll_number + 1, number_squares, snakes, ladders)
return list_moves

def minimum_moves(number_squares, snakes=, ladders=):
"""Returns the minimum number of moves starting from position 0 for a board of size n
snakes and ladders are both dictionaries containing the starting point as the key
and end point as the value"""
# Initialise board
# The player starts off the board at position -1
list_moves = roll_dice(-1, 0, number_squares, snakes, ladders)
print(f"Board is traversable in min(list_moves) moves")


if __name__ == "__main__":
NUMBER_SQUARES = 25
SNAKES = 21:0, 19:9, 14: 2, 18:5
LADDERS = 2: 21, 4:9, 10:20, 17:23
minimum_moves(NUMBER_SQUARES, SNAKES, LADDERS)










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    Follow-up question
    $endgroup$
    – 200_success
    1 hour ago

















3












$begingroup$


I am not looking for a detailed review of this code as I am aware it is very inefficient. The main reason for posting this is to see if there is a better way to achieve my goal (I am certain there must be)



I have created code to find the fewest number of dice rolls that would permit someone to move from the first to last square on a snakes and ladders board. The player wins if they land on or go beyond the final square on the board. They start off the board at position -1.



My approach uses recursion so is OK for small boards. The moment the board reaches a size of 30+ it takes far too long to generate the solution.



Is there a better way to solve this problem



"""Module works out fastest way to traverse a snakes and ladders board"""
def roll_dice(position, roll_number, number_squares, snakes, ladders, list_moves=[]):
"""Roll the dice and then work out if the player can climb a ladder / has won"""
if position in ladders:
position = ladders[position]
if position >= number_squares - 1:
list_moves.append(roll_number)
return
for i in range(1, 7): #For each position roll the dice 6 times
if position + i in snakes:
continue # Forbid a dice-roll that lands on a snake
roll_dice(position + i, roll_number + 1, number_squares, snakes, ladders)
return list_moves

def minimum_moves(number_squares, snakes=, ladders=):
"""Returns the minimum number of moves starting from position 0 for a board of size n
snakes and ladders are both dictionaries containing the starting point as the key
and end point as the value"""
# Initialise board
# The player starts off the board at position -1
list_moves = roll_dice(-1, 0, number_squares, snakes, ladders)
print(f"Board is traversable in min(list_moves) moves")


if __name__ == "__main__":
NUMBER_SQUARES = 25
SNAKES = 21:0, 19:9, 14: 2, 18:5
LADDERS = 2: 21, 4:9, 10:20, 17:23
minimum_moves(NUMBER_SQUARES, SNAKES, LADDERS)










share|improve this question











$endgroup$







  • 1




    $begingroup$
    Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    Follow-up question
    $endgroup$
    – 200_success
    1 hour ago













3












3








3


1



$begingroup$


I am not looking for a detailed review of this code as I am aware it is very inefficient. The main reason for posting this is to see if there is a better way to achieve my goal (I am certain there must be)



I have created code to find the fewest number of dice rolls that would permit someone to move from the first to last square on a snakes and ladders board. The player wins if they land on or go beyond the final square on the board. They start off the board at position -1.



My approach uses recursion so is OK for small boards. The moment the board reaches a size of 30+ it takes far too long to generate the solution.



Is there a better way to solve this problem



"""Module works out fastest way to traverse a snakes and ladders board"""
def roll_dice(position, roll_number, number_squares, snakes, ladders, list_moves=[]):
"""Roll the dice and then work out if the player can climb a ladder / has won"""
if position in ladders:
position = ladders[position]
if position >= number_squares - 1:
list_moves.append(roll_number)
return
for i in range(1, 7): #For each position roll the dice 6 times
if position + i in snakes:
continue # Forbid a dice-roll that lands on a snake
roll_dice(position + i, roll_number + 1, number_squares, snakes, ladders)
return list_moves

def minimum_moves(number_squares, snakes=, ladders=):
"""Returns the minimum number of moves starting from position 0 for a board of size n
snakes and ladders are both dictionaries containing the starting point as the key
and end point as the value"""
# Initialise board
# The player starts off the board at position -1
list_moves = roll_dice(-1, 0, number_squares, snakes, ladders)
print(f"Board is traversable in min(list_moves) moves")


if __name__ == "__main__":
NUMBER_SQUARES = 25
SNAKES = 21:0, 19:9, 14: 2, 18:5
LADDERS = 2: 21, 4:9, 10:20, 17:23
minimum_moves(NUMBER_SQUARES, SNAKES, LADDERS)










share|improve this question











$endgroup$




I am not looking for a detailed review of this code as I am aware it is very inefficient. The main reason for posting this is to see if there is a better way to achieve my goal (I am certain there must be)



I have created code to find the fewest number of dice rolls that would permit someone to move from the first to last square on a snakes and ladders board. The player wins if they land on or go beyond the final square on the board. They start off the board at position -1.



My approach uses recursion so is OK for small boards. The moment the board reaches a size of 30+ it takes far too long to generate the solution.



Is there a better way to solve this problem



"""Module works out fastest way to traverse a snakes and ladders board"""
def roll_dice(position, roll_number, number_squares, snakes, ladders, list_moves=[]):
"""Roll the dice and then work out if the player can climb a ladder / has won"""
if position in ladders:
position = ladders[position]
if position >= number_squares - 1:
list_moves.append(roll_number)
return
for i in range(1, 7): #For each position roll the dice 6 times
if position + i in snakes:
continue # Forbid a dice-roll that lands on a snake
roll_dice(position + i, roll_number + 1, number_squares, snakes, ladders)
return list_moves

def minimum_moves(number_squares, snakes=, ladders=):
"""Returns the minimum number of moves starting from position 0 for a board of size n
snakes and ladders are both dictionaries containing the starting point as the key
and end point as the value"""
# Initialise board
# The player starts off the board at position -1
list_moves = roll_dice(-1, 0, number_squares, snakes, ladders)
print(f"Board is traversable in min(list_moves) moves")


if __name__ == "__main__":
NUMBER_SQUARES = 25
SNAKES = 21:0, 19:9, 14: 2, 18:5
LADDERS = 2: 21, 4:9, 10:20, 17:23
minimum_moves(NUMBER_SQUARES, SNAKES, LADDERS)







python algorithm time-limit-exceeded pathfinding






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









200_success

133k20166438




133k20166438










asked 8 hours ago









EMLEML

61011




61011







  • 1




    $begingroup$
    Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    Follow-up question
    $endgroup$
    – 200_success
    1 hour ago












  • 1




    $begingroup$
    Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
    $endgroup$
    – Justin
    6 hours ago










  • $begingroup$
    Follow-up question
    $endgroup$
    – 200_success
    1 hour ago







1




1




$begingroup$
Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
$endgroup$
– Justin
6 hours ago




$begingroup$
Here is my solution if need be - repl.it/repls/StainedMonthlyOutput. (By the way, nice question!)
$endgroup$
– Justin
6 hours ago












$begingroup$
It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
$endgroup$
– Justin
6 hours ago




$begingroup$
It's okay. I have provided a link to my first solution above if need be. I'm glad it helped you!
$endgroup$
– Justin
6 hours ago












$begingroup$
Follow-up question
$endgroup$
– 200_success
1 hour ago




$begingroup$
Follow-up question
$endgroup$
– 200_success
1 hour ago










2 Answers
2






active

oldest

votes


















5












$begingroup$

Don't use mutable default arguments. If you need to default to a list then default to None and then change to an empty list.



Take the following example code:



>>> def example_list_builder(value, list_=[]):
list_.append(value)
return list_

>>> example_list_builder(1)
[1]
>>> example_list_builder(2)
[1, 2]


This makes list_ a really poorly defined singleton variable, that can't be accessed globally.




Your code looks like it's something like $O(6^n)$ where $n$ is the size of the board.



You can instead make it $O(l^2)$ where $l$ is LADDERS and SNAKES.



To improve you code you should remove the simulation, and instead only work with the LADDERS and SNAKES variables.



For each snake and ladder you should traverse it, and then traverse the snake or ladder after this. You should note the distance, there are two ways to do this:



  1. Least tiles visited.

  2. Least turns taken.

For the latter you'll have to check for collisions with other snakes and ladders.



You should take into account snakes as the fastest path for the following is 4 turns:



NUMBER_SQUARES = 1000
LADDERS = 1: 502, 501: 999
SNAKES = 503: 500





share|improve this answer











$endgroup$








  • 1




    $begingroup$
    Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
    $endgroup$
    – EML
    7 hours ago










  • $begingroup$
    How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
    $endgroup$
    – EML
    6 hours ago






  • 1




    $begingroup$
    @EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
    $endgroup$
    – Peilonrayz
    6 hours ago










  • $begingroup$
    After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
    $endgroup$
    – EML
    6 hours ago



















3












$begingroup$


 continue # Forbid a dice-roll that lands on a snake



This may prevent finding the shortest path - it's possible to imagine a board with two long ladders, where the first ladder passes the bottom of the second ladder, but a snake descends from after the top of the first ladder to before the bottom of the second ladder. Be careful: if you do follow snakes, you'll need some logic to get you out of loops.





 if position >= number_squares - 1:



That could be simplified to



 if position > number_squares:




if __name__ == "__main__":



This is great - good work!




What you probably want to do is to convert the board to a directed graph whose edges are straight runs of board and whose nodes are the destinations of the snakes and ladders.



It might be possible to work with a map of the board, with all the squares containing the number of moves until the end:



  • Initially, all squares contain None.

  • Now work backwards from the end position, marking how many die throws are necessary to reach the end from there (the first few squares will be 1, for example). But don't write anything at the top of a snake or bottom of a ladder.

  • Whenever you reach a square that's already marked, check to see if it's already the same or less than you're about to write to it; if so, then stop exploring that branch.

  • If you reach the top of a ladder, you can mark the bottom square with the same number as the top square.

  • If you reach the bottom of a snake, the converse applies - mark the top of it with the same number as the bottom.

  • When you've completed exploring all branches, the number in the beginning square will be the minimum number of turns needed to reach the top.

It should become obvious that the distinction between snakes and ladders is unimportant here - they just have beginnings and ends, so can be combined into a single list, or just be properties of their beginning and end squares.






share|improve this answer











$endgroup$












  • $begingroup$
    Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
    $endgroup$
    – EML
    2 hours ago










  • $begingroup$
    Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
    $endgroup$
    – EML
    2 hours ago






  • 1




    $begingroup$
    To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
    $endgroup$
    – Toby Speight
    2 hours ago










  • $begingroup$
    Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
    $endgroup$
    – EML
    1 hour ago











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222228%2ffastest-path-on-a-snakes-and-ladders-board%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









5












$begingroup$

Don't use mutable default arguments. If you need to default to a list then default to None and then change to an empty list.



Take the following example code:



>>> def example_list_builder(value, list_=[]):
list_.append(value)
return list_

>>> example_list_builder(1)
[1]
>>> example_list_builder(2)
[1, 2]


This makes list_ a really poorly defined singleton variable, that can't be accessed globally.




Your code looks like it's something like $O(6^n)$ where $n$ is the size of the board.



You can instead make it $O(l^2)$ where $l$ is LADDERS and SNAKES.



To improve you code you should remove the simulation, and instead only work with the LADDERS and SNAKES variables.



For each snake and ladder you should traverse it, and then traverse the snake or ladder after this. You should note the distance, there are two ways to do this:



  1. Least tiles visited.

  2. Least turns taken.

For the latter you'll have to check for collisions with other snakes and ladders.



You should take into account snakes as the fastest path for the following is 4 turns:



NUMBER_SQUARES = 1000
LADDERS = 1: 502, 501: 999
SNAKES = 503: 500





share|improve this answer











$endgroup$








  • 1




    $begingroup$
    Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
    $endgroup$
    – EML
    7 hours ago










  • $begingroup$
    How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
    $endgroup$
    – EML
    6 hours ago






  • 1




    $begingroup$
    @EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
    $endgroup$
    – Peilonrayz
    6 hours ago










  • $begingroup$
    After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
    $endgroup$
    – EML
    6 hours ago
















5












$begingroup$

Don't use mutable default arguments. If you need to default to a list then default to None and then change to an empty list.



Take the following example code:



>>> def example_list_builder(value, list_=[]):
list_.append(value)
return list_

>>> example_list_builder(1)
[1]
>>> example_list_builder(2)
[1, 2]


This makes list_ a really poorly defined singleton variable, that can't be accessed globally.




Your code looks like it's something like $O(6^n)$ where $n$ is the size of the board.



You can instead make it $O(l^2)$ where $l$ is LADDERS and SNAKES.



To improve you code you should remove the simulation, and instead only work with the LADDERS and SNAKES variables.



For each snake and ladder you should traverse it, and then traverse the snake or ladder after this. You should note the distance, there are two ways to do this:



  1. Least tiles visited.

  2. Least turns taken.

For the latter you'll have to check for collisions with other snakes and ladders.



You should take into account snakes as the fastest path for the following is 4 turns:



NUMBER_SQUARES = 1000
LADDERS = 1: 502, 501: 999
SNAKES = 503: 500





share|improve this answer











$endgroup$








  • 1




    $begingroup$
    Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
    $endgroup$
    – EML
    7 hours ago










  • $begingroup$
    How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
    $endgroup$
    – EML
    6 hours ago






  • 1




    $begingroup$
    @EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
    $endgroup$
    – Peilonrayz
    6 hours ago










  • $begingroup$
    After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
    $endgroup$
    – EML
    6 hours ago














5












5








5





$begingroup$

Don't use mutable default arguments. If you need to default to a list then default to None and then change to an empty list.



Take the following example code:



>>> def example_list_builder(value, list_=[]):
list_.append(value)
return list_

>>> example_list_builder(1)
[1]
>>> example_list_builder(2)
[1, 2]


This makes list_ a really poorly defined singleton variable, that can't be accessed globally.




Your code looks like it's something like $O(6^n)$ where $n$ is the size of the board.



You can instead make it $O(l^2)$ where $l$ is LADDERS and SNAKES.



To improve you code you should remove the simulation, and instead only work with the LADDERS and SNAKES variables.



For each snake and ladder you should traverse it, and then traverse the snake or ladder after this. You should note the distance, there are two ways to do this:



  1. Least tiles visited.

  2. Least turns taken.

For the latter you'll have to check for collisions with other snakes and ladders.



You should take into account snakes as the fastest path for the following is 4 turns:



NUMBER_SQUARES = 1000
LADDERS = 1: 502, 501: 999
SNAKES = 503: 500





share|improve this answer











$endgroup$



Don't use mutable default arguments. If you need to default to a list then default to None and then change to an empty list.



Take the following example code:



>>> def example_list_builder(value, list_=[]):
list_.append(value)
return list_

>>> example_list_builder(1)
[1]
>>> example_list_builder(2)
[1, 2]


This makes list_ a really poorly defined singleton variable, that can't be accessed globally.




Your code looks like it's something like $O(6^n)$ where $n$ is the size of the board.



You can instead make it $O(l^2)$ where $l$ is LADDERS and SNAKES.



To improve you code you should remove the simulation, and instead only work with the LADDERS and SNAKES variables.



For each snake and ladder you should traverse it, and then traverse the snake or ladder after this. You should note the distance, there are two ways to do this:



  1. Least tiles visited.

  2. Least turns taken.

For the latter you'll have to check for collisions with other snakes and ladders.



You should take into account snakes as the fastest path for the following is 4 turns:



NUMBER_SQUARES = 1000
LADDERS = 1: 502, 501: 999
SNAKES = 503: 500






share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago

























answered 7 hours ago









PeilonrayzPeilonrayz

28.9k344118




28.9k344118







  • 1




    $begingroup$
    Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
    $endgroup$
    – EML
    7 hours ago










  • $begingroup$
    How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
    $endgroup$
    – EML
    6 hours ago






  • 1




    $begingroup$
    @EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
    $endgroup$
    – Peilonrayz
    6 hours ago










  • $begingroup$
    After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
    $endgroup$
    – EML
    6 hours ago













  • 1




    $begingroup$
    Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
    $endgroup$
    – EML
    7 hours ago










  • $begingroup$
    How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
    $endgroup$
    – EML
    6 hours ago






  • 1




    $begingroup$
    @EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
    $endgroup$
    – Peilonrayz
    6 hours ago










  • $begingroup$
    After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
    $endgroup$
    – EML
    6 hours ago








1




1




$begingroup$
Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
$endgroup$
– EML
7 hours ago




$begingroup$
Thanks for the suggestions. I will see if I can come up with a faster solution using these ideas.
$endgroup$
– EML
7 hours ago












$begingroup$
How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
$endgroup$
– EML
6 hours ago




$begingroup$
How would you code the list_moves then so it isn't mutable but still returns all the values to the minimum_moves function? Thanks
$endgroup$
– EML
6 hours ago




1




1




$begingroup$
@EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
$endgroup$
– Peilonrayz
6 hours ago




$begingroup$
@EML def fn(value=None): if value is None: value = []; ... or def fn(value=None): value = value or []; ....
$endgroup$
– Peilonrayz
6 hours ago












$begingroup$
After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
$endgroup$
– EML
6 hours ago





$begingroup$
After implementing this, I got ValueError: min() arg is an empty sequence. I pass the list_moves between stacks
$endgroup$
– EML
6 hours ago














3












$begingroup$


 continue # Forbid a dice-roll that lands on a snake



This may prevent finding the shortest path - it's possible to imagine a board with two long ladders, where the first ladder passes the bottom of the second ladder, but a snake descends from after the top of the first ladder to before the bottom of the second ladder. Be careful: if you do follow snakes, you'll need some logic to get you out of loops.





 if position >= number_squares - 1:



That could be simplified to



 if position > number_squares:




if __name__ == "__main__":



This is great - good work!




What you probably want to do is to convert the board to a directed graph whose edges are straight runs of board and whose nodes are the destinations of the snakes and ladders.



It might be possible to work with a map of the board, with all the squares containing the number of moves until the end:



  • Initially, all squares contain None.

  • Now work backwards from the end position, marking how many die throws are necessary to reach the end from there (the first few squares will be 1, for example). But don't write anything at the top of a snake or bottom of a ladder.

  • Whenever you reach a square that's already marked, check to see if it's already the same or less than you're about to write to it; if so, then stop exploring that branch.

  • If you reach the top of a ladder, you can mark the bottom square with the same number as the top square.

  • If you reach the bottom of a snake, the converse applies - mark the top of it with the same number as the bottom.

  • When you've completed exploring all branches, the number in the beginning square will be the minimum number of turns needed to reach the top.

It should become obvious that the distinction between snakes and ladders is unimportant here - they just have beginnings and ends, so can be combined into a single list, or just be properties of their beginning and end squares.






share|improve this answer











$endgroup$












  • $begingroup$
    Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
    $endgroup$
    – EML
    2 hours ago










  • $begingroup$
    Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
    $endgroup$
    – EML
    2 hours ago






  • 1




    $begingroup$
    To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
    $endgroup$
    – Toby Speight
    2 hours ago










  • $begingroup$
    Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
    $endgroup$
    – EML
    1 hour ago















3












$begingroup$


 continue # Forbid a dice-roll that lands on a snake



This may prevent finding the shortest path - it's possible to imagine a board with two long ladders, where the first ladder passes the bottom of the second ladder, but a snake descends from after the top of the first ladder to before the bottom of the second ladder. Be careful: if you do follow snakes, you'll need some logic to get you out of loops.





 if position >= number_squares - 1:



That could be simplified to



 if position > number_squares:




if __name__ == "__main__":



This is great - good work!




What you probably want to do is to convert the board to a directed graph whose edges are straight runs of board and whose nodes are the destinations of the snakes and ladders.



It might be possible to work with a map of the board, with all the squares containing the number of moves until the end:



  • Initially, all squares contain None.

  • Now work backwards from the end position, marking how many die throws are necessary to reach the end from there (the first few squares will be 1, for example). But don't write anything at the top of a snake or bottom of a ladder.

  • Whenever you reach a square that's already marked, check to see if it's already the same or less than you're about to write to it; if so, then stop exploring that branch.

  • If you reach the top of a ladder, you can mark the bottom square with the same number as the top square.

  • If you reach the bottom of a snake, the converse applies - mark the top of it with the same number as the bottom.

  • When you've completed exploring all branches, the number in the beginning square will be the minimum number of turns needed to reach the top.

It should become obvious that the distinction between snakes and ladders is unimportant here - they just have beginnings and ends, so can be combined into a single list, or just be properties of their beginning and end squares.






share|improve this answer











$endgroup$












  • $begingroup$
    Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
    $endgroup$
    – EML
    2 hours ago










  • $begingroup$
    Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
    $endgroup$
    – EML
    2 hours ago






  • 1




    $begingroup$
    To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
    $endgroup$
    – Toby Speight
    2 hours ago










  • $begingroup$
    Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
    $endgroup$
    – EML
    1 hour ago













3












3








3





$begingroup$


 continue # Forbid a dice-roll that lands on a snake



This may prevent finding the shortest path - it's possible to imagine a board with two long ladders, where the first ladder passes the bottom of the second ladder, but a snake descends from after the top of the first ladder to before the bottom of the second ladder. Be careful: if you do follow snakes, you'll need some logic to get you out of loops.





 if position >= number_squares - 1:



That could be simplified to



 if position > number_squares:




if __name__ == "__main__":



This is great - good work!




What you probably want to do is to convert the board to a directed graph whose edges are straight runs of board and whose nodes are the destinations of the snakes and ladders.



It might be possible to work with a map of the board, with all the squares containing the number of moves until the end:



  • Initially, all squares contain None.

  • Now work backwards from the end position, marking how many die throws are necessary to reach the end from there (the first few squares will be 1, for example). But don't write anything at the top of a snake or bottom of a ladder.

  • Whenever you reach a square that's already marked, check to see if it's already the same or less than you're about to write to it; if so, then stop exploring that branch.

  • If you reach the top of a ladder, you can mark the bottom square with the same number as the top square.

  • If you reach the bottom of a snake, the converse applies - mark the top of it with the same number as the bottom.

  • When you've completed exploring all branches, the number in the beginning square will be the minimum number of turns needed to reach the top.

It should become obvious that the distinction between snakes and ladders is unimportant here - they just have beginnings and ends, so can be combined into a single list, or just be properties of their beginning and end squares.






share|improve this answer











$endgroup$




 continue # Forbid a dice-roll that lands on a snake



This may prevent finding the shortest path - it's possible to imagine a board with two long ladders, where the first ladder passes the bottom of the second ladder, but a snake descends from after the top of the first ladder to before the bottom of the second ladder. Be careful: if you do follow snakes, you'll need some logic to get you out of loops.





 if position >= number_squares - 1:



That could be simplified to



 if position > number_squares:




if __name__ == "__main__":



This is great - good work!




What you probably want to do is to convert the board to a directed graph whose edges are straight runs of board and whose nodes are the destinations of the snakes and ladders.



It might be possible to work with a map of the board, with all the squares containing the number of moves until the end:



  • Initially, all squares contain None.

  • Now work backwards from the end position, marking how many die throws are necessary to reach the end from there (the first few squares will be 1, for example). But don't write anything at the top of a snake or bottom of a ladder.

  • Whenever you reach a square that's already marked, check to see if it's already the same or less than you're about to write to it; if so, then stop exploring that branch.

  • If you reach the top of a ladder, you can mark the bottom square with the same number as the top square.

  • If you reach the bottom of a snake, the converse applies - mark the top of it with the same number as the bottom.

  • When you've completed exploring all branches, the number in the beginning square will be the minimum number of turns needed to reach the top.

It should become obvious that the distinction between snakes and ladders is unimportant here - they just have beginnings and ends, so can be combined into a single list, or just be properties of their beginning and end squares.







share|improve this answer














share|improve this answer



share|improve this answer








edited 2 hours ago

























answered 2 hours ago









Toby SpeightToby Speight

29.2k743124




29.2k743124











  • $begingroup$
    Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
    $endgroup$
    – EML
    2 hours ago










  • $begingroup$
    Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
    $endgroup$
    – EML
    2 hours ago






  • 1




    $begingroup$
    To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
    $endgroup$
    – Toby Speight
    2 hours ago










  • $begingroup$
    Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
    $endgroup$
    – EML
    1 hour ago
















  • $begingroup$
    Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
    $endgroup$
    – EML
    2 hours ago










  • $begingroup$
    Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
    $endgroup$
    – EML
    2 hours ago






  • 1




    $begingroup$
    To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
    $endgroup$
    – Toby Speight
    2 hours ago










  • $begingroup$
    Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
    $endgroup$
    – EML
    1 hour ago















$begingroup$
Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
$endgroup$
– EML
2 hours ago




$begingroup$
Thanks. Yes that was one of the reasons I avoided snakes all together. I could imagine an infinite loop developing and had no idea how I would avoid this
$endgroup$
– EML
2 hours ago












$begingroup$
Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
$endgroup$
– EML
2 hours ago




$begingroup$
Having said this, I think the above method is very bad. I agree that a directed graph is actually a really smart idea and I have, in fact, been trying to build one as I realised this would be a really smart way to solve the problem. Thanks for suggesting this too as it supports my hypothesis
$endgroup$
– EML
2 hours ago




1




1




$begingroup$
To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
$endgroup$
– Toby Speight
2 hours ago




$begingroup$
To be honest, I mentioned the directed graph and then realised that just labelling the squares is going to be easier, given that we need to deal with moves that skip over the starts of shortcuts. I'd go with the latter option.
$endgroup$
– Toby Speight
2 hours ago












$begingroup$
Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
$endgroup$
– EML
1 hour ago




$begingroup$
Thanks for this. I had basically finished my directed graph code and as this is actually something I am not used to writing, I think getting feedback on this would be most helpful
$endgroup$
– EML
1 hour ago

















draft saved

draft discarded
















































Thanks for contributing an answer to Code Review 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%2fcodereview.stackexchange.com%2fquestions%2f222228%2ffastest-path-on-a-snakes-and-ladders-board%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

Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480