Given a snake and ladder board, find the minimum number of dice throws required to reach the destination or last cell from the source or 1st cell. Basically, the player has total control over the outcome of the dice throw and wants to find out the minimum number of throws required to reach the last cell. If the player reaches a cell which is the base of a ladder, the player has to climb up that ladder and if reaches a cell is the mouth of the snake, and has to go down to the tail of the snake without a dice throw.
Example:
Input:
Output: 3 Explanation: Following are the steps:
First throw two dice to reach cell number 3 and then ladder to reach 22
Then throw 6 to reach 28.
Finally through 2 to reach 30.
There can be other solutions as well like (2, 2, 6), (2, 4, 4), (2, 3, 5).. etc.
[Approach - 1] Using Breadth-First Search - O(n) Time and O(n) Space
The idea is to model the Snakes and Ladders board as a graph where each cell is a node and dice throws represent edges. The thought process is to use Breadth-First Search (BFS) since we're looking for the shortest path (minimum number of moves) from start to end. An important observation is that when you land on a cell with a ladder or snake, you're teleported to a new cell, this effectively changes the destination node of that edge. BFS explores all possible dice rolls from each cell in the shortest-first manner, ensuring we reach the final cell with the least number of throws.
Steps to implement the above idea:
Create a visited array to keep track of visited cells during the BFS traversal of the board.
Initialize a queue that stores pairs of current cell index and the number of moves taken.
Begin from cell 0 with distance 0, mark it visited, and push into the queue as the starting point.
While the queue is not empty, extract the front element and get its current cell and distance.
If the current cell is the last one, return the distance as it represents minimum dice throws.
Loop through all possible next 6 cells using a dice roll and for each, check snake or ladder jump.
If the destination cell is not visited, mark it visited and enqueue it with distance incremented by 1.
C++
// C++ program to find minimum number of dice throws// in Snakes and Ladders using BFS#include<iostream>#include<vector>#include<queue>usingnamespacestd;// Function to find the minimum number of dice throwsintgetMinDiceThrows(vector<int>&move){intn=move.size();vector<bool>visited(n,false);queue<vector<int>>q;visited[0]=true;// Start from cell 0 with 0 movesq.push({0,0});while(!q.empty()){vector<int>curr=q.front();intv=curr[0];intdist=curr[1];if(v==n-1)returndist;q.pop();// Try all possible dice throws from current cellfor(intj=v+1;j<=v+6&&j<n;++j){if(!visited[j]){visited[j]=true;// Move to destination cell if // there's a ladder/snakeintdest=(move[j]!=-1)?move[j]:j;q.push({dest,dist+1});}}}return-1;}intmain(){intn=30;vector<int>moves(n,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;cout<<getMinDiceThrows(moves);return0;}
Java
// Java program to find minimum number of dice throws// in Snakes and Ladders using BFSimportjava.util.*;classGfG{// Function to find the minimum number of dice throwsstaticintgetMinDiceThrows(int[]move){intn=move.length;boolean[]visited=newboolean[n];Queue<int[]>q=newLinkedList<>();visited[0]=true;// Start from cell 0 with 0 movesq.add(newint[]{0,0});while(!q.isEmpty()){int[]curr=q.peek();intv=curr[0];intdist=curr[1];if(v==n-1)returndist;q.remove();// Try all possible dice throws from current cellfor(intj=v+1;j<=v+6&&j<n;++j){if(!visited[j]){visited[j]=true;// Move to destination cell if // there's a ladder/snakeintdest=(move[j]!=-1)?move[j]:j;q.add(newint[]{dest,dist+1});}}}return-1;}publicstaticvoidmain(String[]args){intn=30;int[]moves=newint[n];Arrays.fill(moves,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;System.out.println(getMinDiceThrows(moves));}}
Python
# Python program to find minimum number of dice throws# in Snakes and Ladders using BFSfromcollectionsimportdeque# Function to find the minimum number of dice throwsdefgetMinDiceThrows(move):n=len(move)visited=[False]*nq=deque()visited[0]=True# Start from cell 0 with 0 movesq.append([0,0])whileq:curr=q[0]v=curr[0]dist=curr[1]ifv==n-1:returndistq.popleft()# Try all possible dice throws from current cellforjinrange(v+1,min(v+7,n)):ifnotvisited[j]:visited[j]=True# Move to destination cell if # there's a ladder/snakedest=move[j]ifmove[j]!=-1elsejq.append([dest,dist+1])return-1if__name__=="__main__":n=30moves=[-1]*n# Laddersmoves[2]=21moves[4]=7moves[10]=25moves[19]=28# Snakesmoves[26]=0moves[20]=8moves[16]=3moves[18]=6print(getMinDiceThrows(moves))
C#
// C# program to find minimum number of dice throws// in Snakes and Ladders using BFSusingSystem;usingSystem.Collections.Generic;classGfG{// Function to find the minimum number of dice throwspublicstaticintgetMinDiceThrows(int[]move){intn=move.Length;bool[]visited=newbool[n];Queue<int[]>q=newQueue<int[]>();visited[0]=true;// Start from cell 0 with 0 movesq.Enqueue(newint[]{0,0});while(q.Count>0){int[]curr=q.Peek();intv=curr[0];intdist=curr[1];if(v==n-1)returndist;q.Dequeue();// Try all possible dice throws from current cellfor(intj=v+1;j<=v+6&&j<n;++j){if(!visited[j]){visited[j]=true;// Move to destination cell if // there's a ladder/snakeintdest=(move[j]!=-1)?move[j]:j;q.Enqueue(newint[]{dest,dist+1});}}}return-1;}publicstaticvoidMain(){intn=30;int[]moves=newint[n];Array.Fill(moves,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;Console.WriteLine(getMinDiceThrows(moves));}}
JavaScript
// Javascript program to find minimum number of dice throws// in Snakes and Ladders using BFS// Function to find the minimum number of dice throwsfunctiongetMinDiceThrows(move){letn=move.length;letvisited=newArray(n).fill(false);letq=[];visited[0]=true;// Start from cell 0 with 0 movesq.push([0,0]);while(q.length>0){letcurr=q[0];letv=curr[0];letdist=curr[1];if(v===n-1)returndist;q.shift();// Try all possible dice throws from current cellfor(letj=v+1;j<=v+6&&j<n;++j){if(!visited[j]){visited[j]=true;// Move to destination cell if // there's a ladder/snakeletdest=(move[j]!==-1)?move[j]:j;q.push([dest,dist+1]);}}}return-1;}// Driver Codeletn=30;letmoves=newArray(n).fill(-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;console.log(getMinDiceThrows(moves));
Output
3
[Approach - 2] Using Depth-First Search - O(n) Time and O(n) Space
The idea is to simulate all possible dice throws using Depth First Search (DFS) to explore every path from start to finish. The thought process is to move from the current position to all possible next positions (via dice throw 1–6), jumping to a new location if there's a snake or ladder. An important observation is to prune paths that are already worse than a previously found one using a visited map that tracks minimum moves at each cell. This ensures we only pursue optimal paths, and stop early when a shorter one is already found.
Steps to implement the above idea:
Define a recursive function that explores all possible paths from the current position with a move counter.
Use a map to track visited positions and the least number of moves needed to reach each of them.
Add a base case to update the minimum moves if the current path reaches the final destination.
Prune the recursion if the current path takes more moves than already recorded for the same position.
For each call, simulate all dice throws from 1 to 6 and compute the next position accordingly.
If the next cell has a ladder or snake, jump to its destination before making the recursive call.
Start the function from position 0, and return -1 if no valid path reaches the end of the board.
C++
// C++ program to find minimum number of dice throws// in Snakes and Ladders using DFS #include<iostream>#include<vector>#include<climits>#include<unordered_map>usingnamespacestd;// Recursive DFS to explore all paths from current positionvoiddfs(intcurrPos,intmovesMade,vector<int>&move,unordered_map<int,int>&visited,intn,int&res){// Prune paths that are worse than already found or visitedif(movesMade>=res||(visited.count(currPos)&&movesMade>=visited[currPos])){return;}// Reached the last cell, update resultif(currPos==n-1){res=movesMade;return;}visited[currPos]=movesMade;// Explore all dice throws (1 to 6)for(inti=1;i<=6&&currPos+i<n;++i){intnextPos=currPos+i;// Jump if ladder/snake presentintdest=(move[nextPos]!=-1)?move[nextPos]:nextPos;dfs(dest,movesMade+1,move,visited,n,res);}}// Function to find the minimum number of dice throwsintgetMinDiceThrows(vector<int>&move){intn=move.size();unordered_map<int,int>visited;intres=INT_MAX;// Start DFS from cell 0dfs(0,0,move,visited,n,res);return(res==INT_MAX)?-1:res;}intmain(){intn=30;vector<int>moves(n,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;cout<<getMinDiceThrows(moves);return0;}
Java
// Java program to find minimum number of dice throws// in Snakes and Ladders using DFS importjava.util.*;classGfG{// Recursive DFS to explore all paths from current positionstaticvoiddfs(intcurrPos,intmovesMade,int[]move,Map<Integer,Integer>visited,intn,int[]res){// Prune paths that are worse than already found or visitedif(movesMade>=res[0]||(visited.containsKey(currPos)&&movesMade>=visited.get(currPos))){return;}// Reached the last cell, update resultif(currPos==n-1){res[0]=movesMade;return;}visited.put(currPos,movesMade);// Explore all dice throws (1 to 6)for(inti=1;i<=6&&currPos+i<n;++i){intnextPos=currPos+i;// Jump if ladder/snake presentintdest=(move[nextPos]!=-1)?move[nextPos]:nextPos;dfs(dest,movesMade+1,move,visited,n,res);}}// Function to find the minimum number of dice throwsstaticintgetMinDiceThrows(int[]move){intn=move.length;Map<Integer,Integer>visited=newHashMap<>();int[]res={Integer.MAX_VALUE};// Start DFS from cell 0dfs(0,0,move,visited,n,res);return(res[0]==Integer.MAX_VALUE)?-1:res[0];}publicstaticvoidmain(String[]args){intn=30;int[]moves=newint[n];Arrays.fill(moves,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;System.out.println(getMinDiceThrows(moves));}}
Python
# Python program to find minimum number of dice throws# in Snakes and Ladders using DFS importsys# Recursive DFS to explore all paths from current positiondefdfs(currPos,movesMade,move,visited,n,res):# Prune paths that are worse than already found or visitedifmovesMade>=res[0]or(currPosinvisitedandmovesMade>=visited[currPos]):return# Reached the last cell, update resultifcurrPos==n-1:res[0]=movesMadereturnvisited[currPos]=movesMade# Explore all dice throws (1 to 6)foriinrange(1,7):ifcurrPos+i<n:nextPos=currPos+i# Jump if ladder/snake presentdest=move[nextPos]ifmove[nextPos]!=-1elsenextPosdfs(dest,movesMade+1,move,visited,n,res)# Function to find the minimum number of dice throwsdefgetMinDiceThrows(move):n=len(move)visited={}res=[sys.maxsize]# Start DFS from cell 0dfs(0,0,move,visited,n,res)return-1ifres[0]==sys.maxsizeelseres[0]if__name__=="__main__":n=30moves=[-1]*n# Laddersmoves[2]=21moves[4]=7moves[10]=25moves[19]=28# Snakesmoves[26]=0moves[20]=8moves[16]=3moves[18]=6print(getMinDiceThrows(moves))
C#
// C# program to find minimum number of dice throws// in Snakes and Ladders using DFS usingSystem;usingSystem.Collections.Generic;classGfG{// Recursive DFS to explore all paths from current positionstaticvoiddfs(intcurrPos,intmovesMade,int[]move,Dictionary<int,int>visited,intn,refintres){// Prune paths that are worse than already found or visitedif(movesMade>=res||(visited.ContainsKey(currPos)&&movesMade>=visited[currPos])){return;}// Reached the last cell, update resultif(currPos==n-1){res=movesMade;return;}visited[currPos]=movesMade;// Explore all dice throws (1 to 6)for(inti=1;i<=6&&currPos+i<n;++i){intnextPos=currPos+i;// Jump if ladder/snake presentintdest=(move[nextPos]!=-1)?move[nextPos]:nextPos;dfs(dest,movesMade+1,move,visited,n,refres);}}// Function to find the minimum number of dice throwsstaticintgetMinDiceThrows(int[]move){intn=move.Length;varvisited=newDictionary<int,int>();intres=int.MaxValue;// Start DFS from cell 0dfs(0,0,move,visited,n,refres);return(res==int.MaxValue)?-1:res;}staticvoidMain(){intn=30;int[]moves=newint[n];Array.Fill(moves,-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;Console.WriteLine(getMinDiceThrows(moves));}}
JavaScript
// JavaScript program to find minimum number of dice throws// in Snakes and Ladders using DFS // Recursive DFS to explore all paths from current positionfunctiondfs(currPos,movesMade,move,visited,n,res){// Prune paths that are worse than already found or visitedif(movesMade>=res[0]||(visited.has(currPos)&&movesMade>=visited.get(currPos))){return;}// Reached the last cell, update resultif(currPos===n-1){res[0]=movesMade;return;}visited.set(currPos,movesMade);// Explore all dice throws (1 to 6)for(leti=1;i<=6&&currPos+i<n;++i){letnextPos=currPos+i;// Jump if ladder/snake presentletdest=(move[nextPos]!==-1)?move[nextPos]:nextPos;dfs(dest,movesMade+1,move,visited,n,res);}}// Function to find the minimum number of dice throwsfunctiongetMinDiceThrows(move){letn=move.length;letvisited=newMap();letres=[Number.MAX_SAFE_INTEGER];// Start DFS from cell 0dfs(0,0,move,visited,n,res);return(res[0]===Number.MAX_SAFE_INTEGER)?-1:res[0];}// Driver Codeletn=30;letmoves=newArray(n).fill(-1);// Laddersmoves[2]=21;moves[4]=7;moves[10]=25;moves[19]=28;// Snakesmoves[26]=0;moves[20]=8;moves[16]=3;moves[18]=6;console.log(getMinDiceThrows(moves));
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.