Skip to content
dsa450for five year olds

Graph · 25 of 43

Snake and Ladders Problem

Find the fewest dice throws that get you from the first square of a snakes and ladders board to the last, if you could choose every roll.

Simple way
time O(6^N)
room O(N)
Clever way
time O(N)
room O(N)

The problem, simply

A snakes and ladders board has N squares, numbered 0 to N - 1. You start on square 0 and want to reach square N - 1. Each throw of the die moves you 1 to 6 squares forward. If you land at the bottom of a ladder you climb to its top. If you land on a snake's head you slide down to its tail.

You get to pick every roll. Give back the smallest number of throws to reach the last square, or -1 if you never can. You may not move past the last square.

A story to remember it

Picture it

gridboard
24252627282923222120191812131415161711109876012345

The board winds up like a real one: row 0 runs left to right at the bottom, the next row runs right to left, and so on. Green squares are ladder bottoms, red squares are snake heads. Arrows show where each one takes you.

  • looking now
  • done
  • answer
  • rejected

Examples

The board above

In
N = 30, ladders 2>21, 4>7, 10>25, 19>28, snakes 26>0, 20>8, 16>3, 18>6
Out
3

Roll 2 and climb to 21. Roll 2 to reach 23. Roll 6 to reach 29.

No snakes, no ladders

In
N = 30, nothing
Out
5

You need to cover 29 squares, 6 at most per throw. Four throws cover only 24, so you need 5.

A ladder at the start

In
N = 12, ladder 1>11
Out
1

Roll a 1 and climb straight to the last square.

Trapped

In
N = 12, snakes 1>0, 2>0, 3>0, 4>0, 5>0, 6>0
Out
-1

Every roll from square 0 lands on a snake that sends you back to 0. You can never leave.

Way 1: the simple way

Try every sequence of rolls, like playing every possible game at once.

  1. From the current square, try each roll from 1 to 6. Follow any ladder or snake.
  2. Do not revisit a square already on this game's path, or a snake could loop forever.
  3. When you reach the last square, keep the smallest number of throws.
  4. Stop a game early when it has already used as many throws as the best so far.
java
class SnakesBrute {
    static int best;

    public static int minThrows(int n, int[] jump) {   // jump[i] = where square i sends you, or -1
        best = Integer.MAX_VALUE;
        play(0, n, jump, 0, new boolean[n]);
        return best == Integer.MAX_VALUE ? -1 : best;
    }

    static void play(int at, int n, int[] jump, int rolls, boolean[] onPath) {
        if (at == n - 1) { best = Math.min(best, rolls); return; }
        if (rolls + 1 >= best) return;                 // cannot beat the best game any more
        onPath[at] = true;
        for (int die = 1; die <= 6 && at + die < n; die++) {
            int next = at + die;
            int dest = jump[next] != -1 ? jump[next] : next;   // climb or slide
            if (!onPath[dest]) play(dest, n, jump, rolls + 1, onPath);
        }
        onPath[at] = false;
    }
}

How long it takes: up to 6 choices at every throw, and a game can wander over many squares, so it can take about O(6^N). Extra room: the path marks and the recursion, O(N).

Way 2: the clever way

Paint the board round by round. Every throw costs the same, so this is breadth first search: the first time a square is painted, it was reached with the fewest throws.

  1. Put square 0 in a waiting line (a queue) with 0 throws, and mark it seen.
  2. Take a square from the front. Try rolls 1 to 6. Follow any ladder or snake to find where you really end up.
  3. If that is the last square, the answer is this square's throws plus 1.
  4. Otherwise, if it is not seen yet, mark it and put it at the back of the line with one more throw.
  5. If the line runs empty, the last square cannot be reached.

The waiting line paints the board one throw at a time

01 / 08

gridboard
24252627282923222120191812131415161711109876012345
queuewaiting line
outin0front

Start on square 0 with 0 throws. It is the only square in the waiting line.

throws
0
  • looking now
  • seen
  • answer
  • rejected
  • path
  • just added
java
class SnakesBFS {
    public static int minThrows(int n, int[] jump) {  // jump[i] = where square i sends you, or -1
        if (n == 1) return 0;
        boolean[] seen = new boolean[n];
        int[] throwsTo = new int[n];
        Queue<Integer> line = new ArrayDeque<>();
        line.add(0);
        seen[0] = true;
        while (!line.isEmpty()) {
            int at = line.poll();
            for (int die = 1; die <= 6 && at + die < n; die++) {
                int next = at + die;
                int dest = jump[next] != -1 ? jump[next] : next;   // climb or slide
                if (dest == n - 1) return throwsTo[at] + 1;
                if (!seen[dest]) {
                    seen[dest] = true;                 // painted once, with the fewest throws
                    throwsTo[dest] = throwsTo[at] + 1;
                    line.add(dest);
                }
            }
        }
        return -1;                                     // the last square is never painted
    }
}

How long it takes: each square joins the line at most once and tries 6 rolls, O(6N), which is O(N). Extra room: the seen marks, the throw counts and the line, O(N).

Watch out for

  • Snakes make loops. Without a seen mark, the search can go round and round forever.
  • Rolls past the last square are not allowed. Stop the dice loop at n - 1.
  • A ladder or snake that ends exactly on the last square still counts as reaching it. Check dest, not next.
  • If the start square has a ladder on it, the usual rule is that you do not climb it before your first roll.

What interviewers ask next

  • LeetCode 909 gives the board as an n by n grid numbered in the winding order, with -1 for plain squares. Turn a square number into a row and column first: the row from the bottom is (s - 1) / n, and every other row runs right to left.
  • Print the actual rolls. Store the square you came from for every painted square, then walk back from the end.
  • What is the expected number of throws with a real random die? Then it is a Markov chain. Solve a system of equations, or do value iteration, instead of BFS.
  • Two players take turns. Who wins with perfect play? That becomes a game search with memo over both positions.

Remember this

Grown-up words: squares are nodes, a roll is an edge, the rounds of painting are BFS levels, the waiting line is a queue, and the number painted on the last square is the shortest path length.