# Solving Classic Sudoku Problems with Z3 Theorem Prover

Sudoku is simple yet attractive game. It is played on a 9x9 grid (variants available), divided into nine 3x3 subgrids. The goal is to fill in the empty cells with digits from 1 to 9, in such a way that each digit appears once in every row, every column, and every subgrid.

Z3 is an open-source high-performance theorem prover (satisfiability modulo theories - SAT solver) developed by Microsoft Research. It provides a powerful and efficient tool for solving complex logical formulas and equations.

Procedure is simple:

1. Create a Z3 Solver:

``solver = Solver()``
2. Generate variables for each cell:

``X = [[Int("cell_%s_%s" % (i+1, j+1)) for j in range(9)] for i in range(9)]``
3. Generate digit constraints:

``````for i in range(9):
for j in range(9):
solver.add(And(1 <= X[i][j], X[i][j] <= 9))``````
4. Generate row constraints:

``````for i in range(9):
5. Generate column constrains:

``````for i in range(9):
6. Generate subsquare constraints:

``````for i in range(3):
for j in range(3):
solver.add(Distinct([X[i*3+k][j*3+l] for k in range(3) for l in range(3)]))``````

I create a couple helper functions for reading a 81-length string as a sudoku problem and display them pretty in console. You can see them in full code.

7. Now we can solve some classic sudoku problems with Z3:

``````Problem:
. . . | . . 6 | . . .
. 5 9 | . . . | . . 8
2 . . | . . 8 | . . .
- - - + - - - + - - -
. 4 5 | . . . | . . .
. . 3 | . . . | . . .
. . 6 | . . 3 | . 5 4
- - - + - - - + - - -
. . . | 3 2 5 | . . 6
. . . | . . . | . . .
. . . | . . . | . . .

Solution:
4 3 8 | 2 5 6 | 9 7 1
6 5 9 | 7 1 4 | 2 3 8
2 1 7 | 9 3 8 | 4 6 5
- - - + - - - + - - -
1 4 5 | 6 9 2 | 7 8 3
8 7 3 | 5 4 1 | 6 2 9
9 2 6 | 8 7 3 | 1 5 4
- - - + - - - + - - -
7 9 4 | 3 2 5 | 8 1 6
3 8 2 | 1 6 9 | 5 4 7
5 6 1 | 4 8 7 | 3 9 2``````

Full code is available at: https://github.com/mrtkp9993/notebooks-blog-posts/blob/main/00_z3_sudoku.ipynb