The Puzzle
A standard Sudoku fills a 9×9 grid with digits. A Suirodoku fills the same grid with digits and colors — every cell contains both a number (1–9) and one of nine distinct colors.
Four rules define the game:
- R1–R3 — Each row, column, and 3×3 block contains every digit exactly once and every color exactly once. Equivalent to two independent Sudoku on the same grid.
- R4 — All 81 digit-color pairs are distinct. Since 9 × 9 = 81 cells and 9 × 9 = 81 possible pairs, the mapping from cells to pairs is a bijection.
Rule R4 is the Graeco-Latin square orthogonality condition. This single global constraint is what makes Suirodoku fundamentally different from two overlaid Sudoku.
The name comes from "Sudoku" with "iro" (色, Japanese for "color") inserted. The puzzle draws from Euler's 1782 work on Graeco-Latin squares and the 1960 proof by Bose, Shrikhande, and Parker that they exist for all orders ≥ 3 except 2 and 6.
The CSP Model — 243 Variables, 136 Constraints
A Suirodoku maps directly to a constraint satisfaction problem. The model uses three families of integer variables:
| Variable | Count | Domain |
|---|---|---|
digit[r][c] | 81 | {0, …, 8} |
color[r][c] | 81 | {0, …, 8} |
pair[r][c] | 81 | {0, …, 80} |
And the constraint structure is remarkably clean — 55 AllDifferent constraints plus 81 linear encoding constraints:
| Constraint | Count |
|---|---|
| AllDifferent(digits): rows + columns + blocks | 27 |
| AllDifferent(colors): rows + columns + blocks | 27 |
| AllDifferent(pairs): global, 81 variables | 1 |
Linear: pair = digit × 9 + color | 81 |
The Encoding Trick — From 3,240 Constraints to One
The third variable family (pair) encodes each (digit, color) combination as a single integer:
k = digit × 9 + color
This maps the 81 possible pairs to {0, …, 80}. The global orthogonality condition — which would naively require 3,240 pairwise inequality constraints — reduces to one AddAllDifferent call on 81 variables.
CP-SAT handles AllDifferent natively with matching-based domain propagation. One AllDifferent on 81 variables propagates far more efficiently than 3,240 individual not-equal constraints. The solver prunes domains earlier and reaches solutions faster.
digit × 9 + color turns a quadratic explosion into a single native constraint. Clean, efficient, elegant.
The Code — Under 40 Lines of Python
The complete model for generating a Suirodoku 9×9 grid:
Three Design Choices Worth Noting
Symmetry breaking
The constraint digit[0][c] = c fixes the first row of digits to (0, 1, 2, …, 8). Any Suirodoku can be relabeled to satisfy this, so no solutions are lost — but 9! = 362,880 equivalent search branches are eliminated.
Parallel search
With num_workers=8, CP-SAT runs multiple search strategies simultaneously using different heuristics. Combined with a random seed per attempt, this produces diverse solutions across repeated calls.
Timeout
60 seconds per attempt. If the solver doesn't find a solution, a new attempt starts with a fresh seed. Most successful solves complete in under 10 seconds.
What happens when this model runs at scale: exact enumeration, grid generation, and a surprising result about why most Sudoku can never become a Suirodoku.
Try the puzzle this solver generates.
Play Suirodoku free.
Frequently Asked Questions
pip install ortools), copy the code, and run it. The source is also available on GitHub.References: suirodoku.com · Zenodo: 10.5281/zenodo.18820236 · GitHub