Python Arena
Step 6 of 6

A sudoku solver

In a sudoku, some cells of a 9 × 9 grid hold digits from the start, and you fill in the rest. Each row, each column and each of the nine 3 × 3 boxes must end up with all the digits from 1 to 9, none of them twice. A person looks for a cell where only one digit can go. A program can get away with far less thought: it guesses, and takes the guess back when it leads nowhere. One call of the solver does this:

  1. Look for an empty cell. When there's none left, every cell holds a digit, and the puzzle is solved.
  2. Collect the digits that are allowed in that cell: the ones its row, its column and its box don't have yet.
  3. For each of them in turn, write it in the cell (choose) and call the solver on the grid as it is now (explore). If that call solves the puzzle, stop and report success.
  4. Otherwise rub the digit out (un-choose) before trying the next one. If none of the digits leads to a solution, report failure (False) at once: some digit written earlier, in another cell, was wrong, and the call that wrote it goes on to its next digit.

Here is the whole recipe on a 4 × 4 sudoku, with the digits 1 to 4 and 2 × 2 boxes. The grid is a list of lists, with 0 for an empty cell:

def allowed(grid, row, col):
    used = set(grid[row])                          # the row
    used.update(grid[r][col] for r in range(4))    # the column
    top = row // 2 * 2
    left = col // 2 * 2
    for r in range(top, top + 2):                  # the box
        used.update(grid[r][left:left + 2])
    return [d for d in range(1, 5) if d not in used]


def solve(grid):
    for row in range(4):
        for col in range(4):
            if grid[row][col] == 0:
                for digit in allowed(grid, row, col):
                    grid[row][col] = digit         # choose
                    if solve(grid):                # explore
                        return True
                    grid[row][col] = 0             # un-choose
                return False                       # nothing fits here
    return True                                    # no empty cell: solved


grid = [[0, 0, 0, 0],
        [0, 1, 4, 0],
        [3, 0, 0, 2],
        [0, 0, 0, 0]]
print(solve(grid))
for line in grid:
    print(*line)
Output
True
4 3 2 1
2 1 4 3
3 4 1 2
1 2 3 4

Only 4 digits are given, so the solver guesses a lot: it writes a digit 26 times and hits a dead end 14 times before every cell fits.

How it works

allowed collects the digits in the cell's row, column and box in a set. used.update(...) adds every item it's given to the set, as add does for one item. The 0s of the empty cells go in too, which does no harm: 0 is never a digit to try. The box of a cell starts at row row // 2 * 2 and column col // 2 * 2: // rounds down, so the rows 0 and 1 give 0, and the rows 2 and 3 give 2. On a 9 × 9 board the boxes are 3 × 3, so it's // 3 * 3, and cell (7, 4), in the eighth row and the fifth column, is in the box that starts at (6, 3):

In the Python interpreter
>>> [row // 3 * 3 for row in range(9)]
[0, 0, 0, 3, 3, 3, 6, 6, 6]
>>> row, col = 7, 4
>>> row // 3 * 3, col // 3 * 3
(6, 3)

Two lines of solve are easy to get wrong:

  • return False stands right after the loop over the digits, inside the if. Leave it out, and when nothing fits a cell, the loops go on to the next empty cell, and the return True at the end reports a grid with holes in it as solved.
  • grid[row][col] = 0 is the un-choose. Leave it out, and a failed digit stays in its cell, so the search treats that cell as filled from then on.

Which empty cell first?

The recipe fills the empty cells in reading order, which can be a very bad order. A smarter solver first looks at every empty cell and takes the one with the fewest allowed digits. A cell with one allowed digit is a forced move, with no guessing. A cell with none means this branch is already dead, and the solver backs up at once, where the reading order might find out only millions of placements later. On a typical 9 × 9 puzzle with 56 empty cells, the reading order writes a digit 6,649 times; fewest-first writes 56, one per cell, with no wrong guess at all. On some puzzles the reading order needs tens of millions of placements, minutes of Python, and fewest-first still needs about 60.

What it costs

Checking a digit looks at the 27 cells of a row, a column and a box: on a 9 × 9 board that's O(1). What can explode is the number of placements: in the worst case, the search tries every digit in every empty cell, exponential in the number of empty cells. The givens and good choices prune nearly all of it. The recursion goes one call deeper per filled cell, at most 81, far from Python's limit.

Your task

Challenge 1 of 3

Write solve(grid) for a 9 × 9 sudoku: a list of 9 lists of 9 numbers, with 0 for an empty cell. Fill the grid in place, and return True, or False when the puzzle has no solution. Try the empty cells in reading order and the digits from 1 to 9. The tests write a puzzle as a string of its 9 rows and turn it into a grid. For example, this program:

puzzle = "000654001 103000050 000020000 200871000 540200170 000009000 305000090 010008060 008000007"
grid = [[int(ch) for ch in line] for line in puzzle.split()]
print(solve(grid))
for line in grid:
    print("".join(str(d) for d in line))

prints:

True
987654321
123987456
654123789
236871945
549236178
871549632
365712894
712498563
498365217

Challenge 2

Whoever makes a new sudoku has to check that it has exactly one solution: with two, a player couldn't tell which one is meant. Counting every solution could take forever (an empty grid has about 6.7 × 10²¹ of them), but the puzzle maker only needs to know whether there are none, one or more. Write count_solutions(grid, limit): the number of solutions of the puzzle, or limit when it has limit or more. It never returns more than limit, and it stops searching as soon as it has found that many.

Search like the solver, but when the grid is full, count 1 and go on with the next digit instead of stopping. A deeper call should look for only as many solutions as this call still wants, and the loop over the digits stops once the count reaches limit. Write 0 back after each digit, so the grid ends up as it was.

For example, this program (the second grid is empty, so it has far more than 3 solutions):

puzzle = "980000001 020708540 000000900 015020000 860500073 000000000 658410700 100009000 000800000"
grid = [[int(ch) for ch in line] for line in puzzle.split()]
print(count_solutions(grid, 2))
print(count_solutions([[0] * 9 for i in range(9)], 3))

prints:

1
3

Challenge 3

Write solve_fast(grid): a solver that fills first the empty cell with the fewest allowed digits, as the lesson describes. It takes and returns the same as solve. Before each choice, look at every empty cell, keep the one with the shortest list of allowed digits, and try its digits. If that list is empty, return False at once. Two of the hidden tests are puzzles on which the reading order needs tens of millions of placements.

For example, this program:

puzzle = "080604021 000000780 000000054 018090000 340007006 600200007 509060000 000108000 030000000"
grid = [[int(ch) for ch in line] for line in puzzle.split()]
print(solve_fast(grid))
for line in grid:
    print("".join(str(d) for d in line))

prints:

True
987654321
456321789
123789654
718596243
342817596
695243817
579462138
264138975
831975462