Snake and Ladder Problem - GeeksforGeeks

23 Jul, 2021
Given a snake and ladder board, find the minimum number of dice throws required to reach the destination or last cell from source or 1st cell. Basically, the player has total control over outcome of dice throw and wants to find out minimum number of throws required to reach last cell.If the player reaches a cell which is base of a ladder, the player has to climb up that ladder and if reaches a cell is mouth of the snake, has to go down to the tail of snake without a dice throw. 
For example, consider the board shown, the minimum number of dice throws required to reach cell 30 from cell 1 is 3. Following are the steps:a) First throw two on dice to reach cell number 3 and then ladder to reach 22 b) Then throw 6 to reach 28. c) Finally through 2 to reach 30.There can be other solutions as well like (2, 2, 6), (2, 4, 4), (2, 3, 5).. etc. 
The idea is to consider the given snake and ladder board as a directed graph with number of vertices equal to the number of cells in the board. The problem reduces to finding the shortest path in a graph. Every vertex of the graph has an edge to next six vertices if next 6 vertices do not have a snake or ladder. If any of the next six vertices has a snake or ladder, then the edge from current vertex goes to the top of the ladder or tail of the snake. Since all edges are of equal weight, we can efficiently find shortest path using Breadth First Search of the graph. Following is the implementation of the above idea. The input is represented by two things, first is ‘N’ which is number of cells in the given board, second is an array ‘move[0...N-1]’ of size N. An entry move[i] is -1 if there is no snake and no ladder from i, otherwise move[i] contains index of destination cell for the snake or the ladder at i. 
C++
Java
Python3
C#
Javascript
// C++ program to find minimum number of dice throws required to// reach last cell from first cell of a given snake and ladder// board#include<iostream>#include <queue>using namespace std; // An entry in queue used in BFSstruct queueEntry{    int v;     // Vertex number    int dist;  // Distance of this vertex from source}; // This function returns minimum number of dice throws required to// Reach last cell from 0'th cell in a snake and ladder game.// move[] is an array of size N where N is no. of cells on board// If there is no snake or ladder from cell i, then move[i] is -1// Otherwise move[i] contains cell to which snake or ladder at i// takes to.int getMinDiceThrows(int move[], int N){    // The graph has N vertices. Mark all the vertices as    // not visited    bool *visited = new bool[N];    for (int i = 0; i < N; i++)        visited[i] = false;     // Create a queue for BFS    queue<queueEntry> q;     // Mark the node 0 as visited and enqueue it.    visited[0] = true;    queueEntry s = {0, 0};  // distance of 0't vertex is also 0    q.push(s);  // Enqueue 0'th vertex     // Do a BFS starting from vertex at index 0    queueEntry qe;  // A queue entry (qe)    while (!q.empty())    {        qe = q.front();        int v = qe.v; // vertex no. of queue entry         // If front vertex is the destination vertex,        // we are done        if (v == N-1)            break;         // Otherwise dequeue the front vertex and enqueue        // its adjacent vertices (or cell numbers reachable        // through a dice throw)        q.pop();        for (int j=v+1; j<=(v+6) && j<N; ++j)        {            // If this cell is already visited, then ignore            if (!visited[j])            {                // Otherwise calculate its distance and mark it                // as visited                queueEntry a;                a.dist = (qe.dist + 1);                visited[j] = true;                 // Check if there a snake or ladder at 'j'                // then tail of snake or top of ladder                // become the adjacent of 'i'                if (move[j] != -1)                    a.v = move[j];                else                    a.v = j;                q.push(a);            }        }    }     // We reach here when 'qe' has last vertex    // return the distance of vertex in 'qe'    return qe.dist;} // Driver program to test methods of graph classint main(){    // Let us construct the board given in above diagram    int N = 30;    int moves[N];    for (int i = 0; i<N; i++)        moves[i] = -1;     // Ladders    moves[2] = 21;    moves[4] = 7;    moves[10] = 25;    moves[19] = 28;     // Snakes    moves[26] = 0;    moves[20] = 8;    moves[16] = 3;    moves[18] = 6;     cout << "Min Dice throws required is " << getMinDiceThrows(moves, N);    return 0;}
// Java program to find minimum number of dice// throws required to reach last cell from first// cell of a given snake and ladder board import java.util.LinkedList;import java.util.Queue; public class SnakesLadder{    // An entry in queue used in BFS    static class qentry    {        int v;// Vertex number        int dist;// Distance of this vertex from source    }     // This function returns minimum number of dice    // throws required to Reach last cell from 0'th cell    // in a snake and ladder game. move[] is an array of    // size N where N is no. of cells on board If there    // is no snake or ladder from cell i, then move[i]    // is -1 Otherwise move[i] contains cell to which    // snake or ladder at i takes to.    static int getMinDiceThrows(int move[], int n)    {        int visited[] = new int[n];        Queue<qentry> q = new LinkedList<>();        qentry qe = new qentry();        qe.v = 0;        qe.dist = 0;         // Mark the node 0 as visited and enqueue it.        visited[0] = 1;        q.add(qe);         // Do a BFS starting from vertex at index 0        while (!q.isEmpty())        {            qe = q.remove();            int v = qe.v;             // If front vertex is the destination            // vertex, we are done            if (v == n - 1)                break;             // Otherwise dequeue the front vertex and            // enqueue its adjacent vertices (or cell            // numbers reachable through a dice throw)            for (int j = v + 1; j <= (v + 6) && j < n; ++j)            {                // If this cell is already visited, then ignore                if (visited[j] == 0)                {                    // Otherwise calculate its distance and                    // mark it as visited                    qentry a = new qentry();                    a.dist = (qe.dist + 1);                    visited[j] = 1;                     // Check if there a snake or ladder at 'j'                    // then tail of snake or top of ladder                    // become the adjacent of 'i'                    if (move[j] != -1)                        a.v = move[j];                    else                        a.v = j;                    q.add(a);                }            }        }         // We reach here when 'qe' has last vertex        // return the distance of vertex in 'qe'        return qe.dist;    }     public static void main(String[] args)    {        // Let us construct the board given in above diagram        int N = 30;        int moves[] = new int[N];        for (int i = 0; i < N; i++)            moves[i] = -1;         // Ladders        moves[2] = 21;        moves[4] = 7;        moves[10] = 25;        moves[19] = 28;         // Snakes        moves[26] = 0;        moves[20] = 8;        moves[16] = 3;        moves[18] = 6;         System.out.println("Min Dice throws required is " +                          getMinDiceThrows(moves, N));    }}
# Python3 program to find minimum number# of dice throws required to reach last# cell from first cell of a given# snake and ladder board # An entry in queue used in BFSclass QueueEntry(object):    def __init__(self, v = 0, dist = 0):        self.v = v        self.dist = dist '''This function returns minimum number ofdice throws required to. Reach last cellfrom 0'th cell in a snake and ladder game.move[] is an array of size N where N isno. of cells on board. If there is nosnake or ladder from cell i, then move[i]is -1. Otherwise move[i] contains cell towhich snake or ladder at i takes to.'''def getMinDiceThrows(move, N):         # The graph has N vertices. Mark all    # the vertices as not visited    visited = [False] * N     # Create a queue for BFS    queue = []     # Mark the node 0 as visited and enqueue it    visited[0] = True     # Distance of 0't vertex is also 0    # Enqueue 0'th vertex    queue.append(QueueEntry(0, 0))     # Do a BFS starting from vertex at index 0    qe = QueueEntry() # A queue entry (qe)    while queue:        qe = queue.pop(0)        v = qe.v # Vertex no. of queue entry         # If front vertex is the destination        # vertex, we are done        if v == N - 1:            break         # Otherwise dequeue the front vertex        # and enqueue its adjacent vertices        # (or cell numbers reachable through        # a dice throw)        j = v + 1        while j <= v + 6 and j < N:                     # If this cell is already visited,            # then ignore            if visited[j] is False:                                 # Otherwise calculate its                # distance and mark it                # as visited                a = QueueEntry()                a.dist = qe.dist + 1                visited[j] = True                 # Check if there a snake or ladder                # at 'j' then tail of snake or top                # of ladder become the adjacent of 'i'                a.v = move[j] if move[j] != -1 else j                 queue.append(a)             j += 1     # We reach here when 'qe' has last vertex    # return the distance of vertex in 'qe    return qe.dist # driver codeN = 30moves = [-1] * N # Laddersmoves[2] = 21moves[4] = 7moves[10] = 25moves[19] = 28 # Snakesmoves[26] = 0moves[20] = 8moves[16] = 3moves[18] = 6 print("Min Dice throws required is {0}".       format(getMinDiceThrows(moves, N))) # This code is contributed by Ajitesh Pathak
// C# program to find minimum// number of dice throws required// to reach last cell from first// cell of a given snake and ladder boardusing System;using System.Collections.Generic; public class SnakesLadder{    // An entry in queue used in BFS    public class qentry    {        public int v;// Vertex number        public int dist;// Distance of this vertex from source    }     // This function returns minimum number of dice    // throws required to Reach last cell from 0'th cell    // in a snake and ladder game. move[] is an array of    // size N where N is no. of cells on board If there    // is no snake or ladder from cell i, then move[i]    // is -1 Otherwise move[i] contains cell to which    // snake or ladder at i takes to.    static int getMinDiceThrows(int []move, int n)    {        int []visited = new int[n];        Queue<qentry> q = new Queue<qentry>();        qentry qe = new qentry();        qe.v = 0;        qe.dist = 0;         // Mark the node 0 as visited and enqueue it.        visited[0] = 1;        q.Enqueue(qe);         // Do a BFS starting from vertex at index 0        while (q.Count != 0)        {            qe = q.Dequeue();            int v = qe.v;             // If front vertex is the destination            // vertex, we are done            if (v == n - 1)                break;             // Otherwise dequeue the front vertex and            // enqueue its adjacent vertices (or cell            // numbers reachable through a dice throw)            for (int j = v + 1; j <= (v + 6) && j < n; ++j)            {                // If this cell is already visited, then ignore                if (visited[j] == 0)                {                    // Otherwise calculate its distance and                    // mark it as visited                    qentry a = new qentry();                    a.dist = (qe.dist + 1);                    visited[j] = 1;                     // Check if there a snake or ladder at 'j'                    // then tail of snake or top of ladder                    // become the adjacent of 'i'                    if (move[j] != -1)                        a.v = move[j];                    else                        a.v = j;                    q.Enqueue(a);                }            }        }         // We reach here when 'qe' has last vertex        // return the distance of vertex in 'qe'        return qe.dist;    }     // Driver code    public static void Main(String[] args)    {        // Let us construct the board        // given in above diagram        int N = 30;        int []moves = new int[N];        for (int i = 0; i < N; i++)            moves[i] = -1;         // Ladders        moves[2] = 21;        moves[4] = 7;        moves[10] = 25;        moves[19] = 28;         // Snakes        moves[26] = 0;        moves[20] = 8;        moves[16] = 3;        moves[18] = 6;         Console.WriteLine("Min Dice throws required is " +                        getMinDiceThrows(moves, N));    }} // This code has been contributed by 29AjayKumar
<script>// Javascript program to find minimum number of dice// throws required to reach last cell from first// cell of a given snake and ladder board class qentry{    constructor()    {        this.v = 0;        this.dist = 0;    }} // This function returns minimum number of dice    // throws required to Reach last cell from 0'th cell    // in a snake and ladder game. move[] is an array of    // size N where N is no. of cells on board If there    // is no snake or ladder from cell i, then move[i]    // is -1 Otherwise move[i] contains cell to which    // snake or ladder at i takes to.function getMinDiceThrows(move,n){    let visited = new Array(n);    for(let i = 0; i < n; i++)        visited[i] = false;        let q = [];        let qe = new qentry();        qe.v = 0;        qe.dist = 0;           // Mark the node 0 as visited and enqueue it.        visited[0] = 1;        q.push(qe);           // Do a BFS starting from vertex at index 0        while (q.length != 0)        {            qe = q.shift();            let v = qe.v;               // If front vertex is the destination            // vertex, we are done            if (v == n - 1)                break;               // Otherwise dequeue the front vertex and            // enqueue its adjacent vertices (or cell            // numbers reachable through a dice throw)            for (let j = v + 1; j <= (v + 6) && j < n; ++j)            {                // If this cell is already visited, then ignore                if (visited[j] == 0)                {                    // Otherwise calculate its distance and                    // mark it as visited                    let a = new qentry();                    a.dist = (qe.dist + 1);                    visited[j] = 1;                       // Check if there a snake or ladder at 'j'                    // then tail of snake or top of ladder                    // become the adjacent of 'i'                    if (move[j] != -1)                        a.v = move[j];                    else                        a.v = j;                    q.push(a);                }            }        }           // We reach here when 'qe' has last vertex        // return the distance of vertex in 'qe'        return qe.dist;} // Let us construct the board given in above diagramlet N = 30;let moves = new Array(N);for (let i = 0; i < N; i++)    moves[i] = -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; document.write("Min Dice throws required is " +                   getMinDiceThrows(moves, N)); // This code is contributed by avanitrachhadiya2155</script>
Output: 
Min Dice throws required is 3
Time complexity of the above solution is O(N) as every cell is added and removed only once from queue. And a typical enqueue or dequeue operation takes O(1) time.  
YouTubeGeeksforGeeks507K subscribersSnake and Ladder Problem (Graphs) | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 9:22•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=1pMNYQmtVVg" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
This article is contributed by Siddharth. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
29AjayKumar
avanitrachhadiya2155
Amazon
Belzabar
BFS
DFS
Flipkart
MAQ Software
Shortest Path
Graph
Flipkart
Amazon
MAQ Software
Belzabar
DFS
Graph
Shortest Path
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Bellman–Ford Algorithm | DP-23
Floyd Warshall Algorithm | DP-16
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Ford-Fulkerson Algorithm for Maximum Flow Problem
Disjoint Set (Or Union-Find) | Set 1 (Detect Cycle in an Undirected Graph)
Strongly Connected Components
Detect cycle in an undirected graph
Traveling Salesman Problem (TSP) Implementation
Dijkstra’s Algorithm for Adjacency List Representation | Greedy Algo-8
Find the number of islands | Set 1 (Using DFS)