Chapter 4
Kakurasu
Kakurasu is a shading puzzle dressed as a Kakuro. The grid is a rectangle of cells, each of which is to be declared either shaded or unshaded. Down the right-hand edge sits a column of integers, one per row; along the bottom sits a row of integers, one per column. The right-edge integer is the sum of the column indices of the shaded cells in its row; the bottom-edge integer is the sum of the row indices of the shaded cells in its column. The weights are labelled along the top and left edges: column indices increase from at the left, and row indices increase from at the top.
The puzzle looks, at first glance, like a Kakuro cousin. The arithmetic is the same shape: a sum over selected cells. What changes is the alphabet. In Kakuro each white cell takes a digit from to ; in Kakurasu each cell takes a value from , and the weights in the sum come not from the cells themselves but from their position along the run. That small shift, from digits-as-values to position-as-weight, moves the puzzle out of the constraint-programming register into something cleaner still: a pure binary integer program with only linear constraints and no all-different in sight.
This chapter models the puzzle in / variables, solves a instance in roughly milliseconds, and notes the single observation that makes the formulation water-tight: every row and every column’s clue uniquely decodes the binary pattern of that row or column, in the same way that the positional notation for an integer uniquely decodes its digits.
Rules and a small instance
A Kakurasu puzzle is an grid of cells. Each cell , with , is either shaded or unshaded. Write for its state, with for shaded. Two families of clues govern the shading.
For each row , the sum equals a given integer . That is: shaded cells in row , weighted by their column indices, total .
For each column , the sum equals a given integer . Shaded cells in column , weighted by their row indices, total .
Figure 4.1 gives a Kakurasu with every row- and column-clue populated; each is a demand on the corresponding run. No pre-shaded cells: the solver fills the entire -bit array from the clues alone.
The programming model
Let for . The puzzle is the system of linear equalities
This is a / integer linear program with variables and equality constraints. No all-different, no reified booleans, no auxiliary variables: everything the puzzle says is a linear combination of indicator variables equal to a constant.
Why the clues decode uniquely
A single row, in isolation, looks like this: given , find with . The answer is not always unique in isolation: is both and . What makes the full puzzle uniquely solvable, when it is, is the interlocking of the row and column clues: the binary pattern of row must simultaneously satisfy its own row equation and contribute consistently to all nine column equations. For the specific in Figure 4.1, enumeration confirms one admissible matrix. The solver shows it in Figure 4.2.
A solver in a dozen lines
from ortools.sat.python import cp_model
def solve_kakurasu(n, row_clues, col_clues):
"""Return an n x n 0/1 array satisfying the clues."""
m = cp_model.CpModel()
x = [[m.NewBoolVar(f"x{r}{c}")
for c in range(n)] for r in range(n)]
for r in range(n):
m.Add(sum((c+1) * x[r][c]
for c in range(n)) == row_clues[r])
for c in range(n):
m.Add(sum((r+1) * x[r][c]
for r in range(n)) == col_clues[c])
s = cp_model.CpSolver()
ok = s.Solve(m)
if ok not in (cp_model.OPTIMAL, cp_model.FEASIBLE):
raise RuntimeError("no solution")
return [[s.Value(x[r][c])
for c in range(n)] for r in range(n)]
For the instance the solver returns in about milliseconds. Enumeration of all feasible assignments returns one, so the puzzle is well-posed.
A larger instance
Figure 4.3 is Otto Janko’s Puzzle from the janko.at Kakurasu archive, at and rated at the top tier of the site’s difficulty scale. The row and column clues are large enough to force substantial interaction between constraints; CP-SAT returns the unique shading in Figure 4.4 in about milliseconds, a reminder that binary variables under linear constraints is small work for a modern ILP backend, however challenging the puzzle is to solve by hand.
The arithmetic geometry of the grid
A Kakurasu sits naturally in the integer lattice , each cell a coordinate. The shaded patterns form the integer points of the hypercube ; the clue set carves out an intersection of this cube with an affine subspace of codimension . A well-posed puzzle is one whose cube-affine intersection consists of a single point. The number of clue tuples that yield unique puzzles grows rapidly with ; for the feasible volume under clue values is already small enough that a well-tuned generator produces a near-unique puzzle the first time.
One further curiosity. The maximum row clue is , attained when the entire row is shaded. The minimum is , attained when none is. The same bounds apply to column clues. The middle clue values, around , support the greatest number of feasible row patterns and are the ones that, under random generation, most reliably lead to unique puzzles when paired in sufficient count.
Sources. Kakurasu appears in the Nikoli family of sum-based puzzles as a counterpart to Kakuro; the positional weighting is a unique identifier. The instance in Figure 4.1 is sourced from the recreational_maths collection and was originally solved with Z; the CP-SAT port here is in the same variable space with equivalent constraints. For the broader family of positional-sum puzzles, see the survey material at the Nikoli English-language site.