Sudoku
Python
Sudoku Solver
Algorithm
Code Optimization

Shortest Sudoku Solver in Python - How does it work?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Sudoku solvers in Python often look surprisingly short because the core algorithm is simple: find an empty cell, try valid digits, recurse, and backtrack when a choice fails. The code can be compressed into a small number of lines, but the underlying idea is still a full search algorithm with constraints.

So when people ask how a "shortest Sudoku solver" works, the real answer is usually: compact Python syntax wrapped around recursive backtracking.

The Backtracking Idea

Sudoku requires every row, column, and 3x3 box to contain digits 1 through 9 exactly once. A solver uses those constraints to test possible moves.

The general strategy is:

  1. Find an empty cell.
  2. Try digits 1 through 9.
  3. Keep only digits that do not violate Sudoku rules.
  4. Recurse to solve the rest of the board.
  5. If no digit works later, backtrack and try another choice.

This is a depth-first search over the space of valid partial boards.

A Clear Python Solver

Here is a compact but readable implementation:

python
1def find_empty(board):
2    for row in range(9):
3        for col in range(9):
4            if board[row][col] == 0:
5                return row, col
6    return None
7
8
9def is_valid(board, row, col, value):
10    if value in board[row]:
11        return False
12
13    if value in (board[r][col] for r in range(9)):
14        return False
15
16    box_row = (row // 3) * 3
17    box_col = (col // 3) * 3
18
19    for r in range(box_row, box_row + 3):
20        for c in range(box_col, box_col + 3):
21            if board[r][c] == value:
22                return False
23
24    return True
25
26
27def solve(board):
28    empty = find_empty(board)
29    if empty is None:
30        return True
31
32    row, col = empty
33
34    for value in range(1, 10):
35        if is_valid(board, row, col, value):
36            board[row][col] = value
37
38            if solve(board):
39                return True
40
41            board[row][col] = 0
42
43    return False

This code is short because the puzzle rules are local and recursion handles the search tree naturally.

Why Short Solvers Look Clever

Many "shortest" Sudoku solvers remove helper functions, inline checks, and compress loops into expressions. That makes the code look magical, but the algorithm is still the same.

The shortness usually comes from:

  • using next(...) to find the first empty cell
  • using all(...) or set logic for validity checks
  • mutating the board in place
  • relying on recursion rather than explicit stacks

A shorter version is not fundamentally more advanced. It is simply more condensed.

Walking Through One Recursive Step

Suppose the solver finds an empty cell at row 0, column 2. It then tests digits:

  • '1 may conflict with the row'
  • '2 may fit temporarily'
  • the solver places 2
  • recursion tries to solve the next empty cell

If the later branch fails, the solver resets the cell to 0 and continues with 3, 4, and so on.

That reset is the key to backtracking. The algorithm does not need to copy the whole board each time. It mutates one cell, explores, and undoes the move if necessary.

Running the Solver

Here is a complete example with a puzzle:

python
1board = [
2    [5, 3, 0, 0, 7, 0, 0, 0, 0],
3    [6, 0, 0, 1, 9, 5, 0, 0, 0],
4    [0, 9, 8, 0, 0, 0, 0, 6, 0],
5    [8, 0, 0, 0, 6, 0, 0, 0, 3],
6    [4, 0, 0, 8, 0, 3, 0, 0, 1],
7    [7, 0, 0, 0, 2, 0, 0, 0, 6],
8    [0, 6, 0, 0, 0, 0, 2, 8, 0],
9    [0, 0, 0, 4, 1, 9, 0, 0, 5],
10    [0, 0, 0, 0, 8, 0, 0, 7, 9],
11]
12
13if solve(board):
14    for row in board:
15        print(row)
16else:
17    print("No solution found")

This solver is fully runnable and works for standard Sudoku boards represented with 0 as the empty marker.

Why It Is Fast Enough

Backtracking sounds expensive, and in the worst case it is. But Sudoku constraints prune many invalid moves immediately. That is why a simple solver can still be effective for many puzzles.

Shorter high-performance solvers often add a heuristic such as choosing the empty cell with the fewest legal candidates. That reduces branching dramatically, but it also makes the code longer and less minimal.

So there is a tradeoff:

  • shortest code favors compactness
  • fastest code often favors stronger heuristics

Common Pitfalls

The biggest pitfall is misunderstanding recursion and thinking the solver "guesses randomly." It does not. It systematically explores legal moves and undoes them when necessary.

Another issue is forgetting to reset the cell during backtracking. Without that step, failed guesses contaminate later branches.

Some implementations also skip board validation and assume the starting puzzle is valid. If the input already contains contradictions, the solver may behave unpredictably or search pointlessly.

Finally, very short code can become hard to read or debug. A compact solver is impressive, but a slightly longer readable solver is often more useful for learning and maintenance.

Summary

  • Short Sudoku solvers work by recursive backtracking, not by magic.
  • They find an empty cell, try valid digits, recurse, and undo failed moves.
  • Compact Python syntax can hide the algorithm, but it does not change it.
  • Backtracking works well because Sudoku rules eliminate many bad branches early.
  • The shortest solver is not always the easiest one to understand or extend.

Course illustration
Course illustration

All Rights Reserved.