Kropki in the browser with four rule sets inside. Fill an n×n
grid with digits 1..n so every row and column holds each digit exactly
once. Between every pair of adjacent cells the truth is printed: a
white dot joins consecutive digits, a black dot joins a digit
and its double, no dot means neither. Puzzle #42 in the solver
series.
Demo: https://sen.ltd/portfolio/kropki/
Repo: https://github.com/sen-ltd/kropki
I picked this puzzle for two reasons.
Every constraint lives inside a line
The Latin rule binds a row or a column. Every dot binds two orthogonal
neighbours — which also share a row or a column. So no constraint in
Kropki ever crosses a line, and that shapes the whole solver. The
ceiling for propagation is to answer the exact per-line question —
which digits extend to a complete, dot-respecting permutation of this
row or column? — with a forward/backward bitmask DP (state: set of used
digits × last digit placed), stitching prefixes to suffixes to get each
cell's surviving candidates.
The ladder has four rungs:
| level | rule |
|---|---|
dot |
naked singles + arc consistency per edge (silence propagates too, as a negative constraint) |
single |
+ hidden singles: a digit with one home on a line lands there |
line |
+ the exact per-line DP above |
probe |
+ assume a digit in one cell, run line to fixpoint, discard on contradiction |
Inside its own line, line subsumes both lower rungs, and since all
constraints are intra-line, the ladder is nested: dot ⊂ single ⊂
line. That makes the ablation result a theorem before it is a
measurement — and it measures exactly flat (200 boards/size, full probe
ladder minus one rule):
| board | full | −dot | −single | −line |
|---|---|---|---|---|
| 5×5 | 99.0% | 99.0% | 99.0% | 99.0% |
| 6×6 | 99.5% | 99.5% | 99.5% | 99.5% |
| 7×7 | 96.0% | 96.0% | 96.0% | 96.0% |
Even −line is unharmed: the probe re-earns its share by branching over
dot+single. Meanwhile the incremental ladder earns at every step on
the same unfiltered stream:
| board | dot | +single | +line | +probe | unique |
|---|---|---|---|---|---|
| 5×5 | 95.0% | 99.3% | 99.5% | 99.5% | 99.5% |
| 7×7 | 64.3% | 88.0% | 99.0% | 99.0% | 99.0% |
| 8×8 | 30.5% | 56.5% | 97.5% | 97.5% | 97.5% |
| 9×9 | 6.7% | 16.7% | 82.0% | 86.0% | 86.0% |
Read only the ablation and every rule is redundant; read only the
incremental table and every rule is essential — this series' recurring
lesson (measure both) lands here with one side a theorem, as it did on
Tilepaint (#41). And the 4-point gap between line (82.0%) and probe
(86.0%) at 9×9 is a measured quantity with a precise meaning: the part
of the puzzle that is pure row-by-column coupling, unreachable by
any amount of intra-line reasoning.
The probe ⇔ unique law refused to break
This series carries an empirical law — probe fixpoint completes ⇔ the
answer is unique — and the recent pattern was that purely arithmetic
puzzles break it: ambiguity hides in multi-cell rearrangements a
single-cell probe can never refute (Kurotto #40, Tilepaint #41). Kropki
is purely arithmetic too. This time the law held: probe-complete and
unique agreed on all 1,750 measured boards (probe ⇒ unique is a
theorem; the converse is measurement — zero exceptions).
The shape of ambiguity explains why. The minimal difference between two
Latin squares is an intercalate — a 2×2 subrectangle holding a/b
over b/a — and its swap is a four-cell rearrangement, exactly the kind
a probe cannot see. But in the full-information regime a silent
intercalate (one whose swap preserves every printed dot) is so rare
that whenever ambiguity appears at all, the probe genuinely gets stuck
too. The counterexample habitat was measured empty. Whether a law
breaks is not something you argue; it is something you count.
Ambiguity still has a face you can read off a finished answer with no
search: a silent intercalate needs every outside neighbour x of the
four swapped cells to satisfy labelOf(a,x) = labelOf(b,x). That one
4-cell certificate explains 16 of the 21 non-unique 9×9 boards (76%),
and 39 of 61 on half-thinned 6×6 boards (64%). It never once fired on
a unique board — the theorem "silent intercalate ⇒ second solution",
machine-checked from the contrapositive side.
The silence between the dots
Classic Kropki prints all dots, so a blank edge is a negative
constraint: not consecutive, not double. To price that silence, compare
full information against boards where only the blank labels are
withheld (all dots stay):
| board | edges w/b/none | unique (full) | unique (dots only) |
|---|---|---|---|
| 4×4 | 33.7% / 33.0% / 33.3% | 100.0% | 82.5% |
| 6×6 | 26.2% / 20.3% / 53.5% | 99.5% | 74.5% |
| 7×7 | 23.8% / 14.8% / 61.4% | 96.0% | 52.7% |
| 8×8 | 22.1% / 14.4% / 63.5% | 96.0% | 47.0% |
Blank edges dominate as n grows (63.5% of edges at 8×8), and dropping
their meaning halves uniqueness: 96% → 47%. Most of the information
on a Kropki board is carried by the dots that are not there. The
colours are asymmetric too: 1·2 is both consecutive and double, and
black wins deterministically — so a white dot also whispers "not
{1,2}". White is stronger than it looks.
There is also a dial that withholds edges of every kind at random
(6×6, 200 boards each):
| hidden fraction | probe | unique | non-unique explained by certificate |
|---|---|---|---|
| 0 | 100.0% | 100.0% | — |
| 25% | 97.0% | 97.0% | 6/6 (100%) |
| 50% | 69.5% | 69.5% | 39/61 (64%) |
| 75% | 3.0% | 3.0% | 132/194 (68%) |
The probe and unique columns never split here either.
Generation is: draw a Latin square, read the dots
A Kropki answer is any Latin square. The generator draws one by
row-wise randomized backtracking (with a restart cap), then reads every
edge label off the answer — no puzzle-level search, no retries. Boards
for the weaker levels buy their solvability with givens, then minimize
them. The price of weakness, in givens (medians):
| board | dot | single | line | probe |
|---|---|---|---|---|
| 5×5 | 0 | 0 | 0 | 0 |
| 7×7 | 0 | 0 | 0 | 0 |
| 9×9 | 2 | 1 | 0 | 0 |
Up to 7×7 even the weakest rule needs a median of zero givens —
full-information Kropki is self-sufficient; givens only pay for weak
levels at 9×9. The shipped bank holds 52 boards (5/7/9 × four grades,
including five probe-grade 9×9s), each re-proved unique by the
searching engine.
Engine trust comes from two independent implementations: a propagating
search over candidate sets, and a raw row-by-row enumeration that
shares no code with the ladder — digits tried straight against the
definition. 600/600 (board, engine) pairs agree on solution counts.
24 tests.
At SEN LLC we keep shipping these small, measured, publishable builds.

Top comments (0)