DEV Community

SEN LLC
SEN LLC

Posted on

Sukoro: when the numbers are degrees, a clue can only ever say yes

Sukoro in the browser with a four-rung solver. Restate the rule and
the puzzle changes shape: a number counts its numbered neighbours, so a number
is the degree of its own cell. The numbers are not information laid on top
of a shape — they are a function of the shape, and an answer is exactly a
connected, locally irregular induced subgraph of the grid. What falls out
is an asymmetry I had not met before in this series: a clue can only say
"there is a number here". There is no notation for "this cell is empty".
So
I enumerated all 1,254,128 clue sets a small board can carry, and 91.5% of
everything printable has no answer at all
while 1.2% is a puzzle — and yet
erasing a clue can never break a board. Puzzle #57 in the solver series.

Demo: https://sen.ltd/portfolio/sukoro/
Repo: https://github.com/sen-ltd/sukoro

Sukoro

Rules

  1. Write a number from 1 to 4 into some cells; leave the rest empty.
  2. A number says how many of its four orthogonal neighbours also hold numbers.
  3. Two orthogonally adjacent numbers must differ.
  4. All the numbered cells form one connected group.

Some numbers are printed. That is the whole thing.

The numbers are not written on the answer — they are the answer

Read rule 2 with graph glasses on. "How many neighbours hold numbers" is the
degree of that cell in the subgraph induced by the numbered cells. So the
numbers are not extra data sitting on a shape; they are a function of it. Rule 3
then says no edge of that subgraph joins two vertices of equal degree, which is
the textbook definition of a locally irregular graph.

an answer = a connected, locally irregular induced subgraph of the grid graph,
minimum degree ≥ 1

Almost everything below is a consequence of that sentence. Three things straight
away:

  • A lone cell is illegal. Its degree would be 0, and 0 is not one of the numbers.
  • A domino is illegal. Both cells read 1 and they touch. K₂ is the standard example of a graph that is not locally irregular, and here it is, printed on paper. The smallest legal group is three cells reading 1–2–1.
  • A solid block is illegal as soon as it has two interior cells: both read 4, and they touch.

Answers can be neither thin nor solid, which caps how much of a board they can
cover. Full enumeration puts the ceiling at 75–81% on every rectangle it can reach
— 2×4, 3×4, 3×5, 4×4, 4×5, 4×6, 3×7, 5×5. There are exactly two exceptions in
the entire family, and I found them by checking every rectangle up to 8×12: 1×3 and 3×3 are the only ones
that can be filled completely.
The solid 3×3 reads

2 3 2
3 4 3
2 3 2
Enter fullscreen mode Exit fullscreen mode

and is locally irregular by luck — it has a single interior cell, so there is no
second 4 for the 4 to sit next to.

The interface follows from the same fact. There is no number pad. You click
a cell to cycle it through number → struck out → undecided, and the digit
appears by itself, because the digit is the count of numbered neighbours you
have just drawn. Nothing in the player ever writes a number.

1. The blank board: a 1×n strip has exactly n − 2 answers

With no clue printed at all, how many answers does an empty grid have? That is
the same question as counting the objects themselves.

1 2 3 4 5 6 7 8 9 10
1×n 0 0 1 2 3 4 5 6 7 8
2×n 0 4 12 26 48 80 126 190 278 398
3×n 1 12 54 162 428 1,012 2,322 5,134 11,338 24,580
4×n 2 26 162 702 2,810 10,514 38,928 143,254
5×n 3 48 428 2,810 18,230 110,138 666,757
6×n 4 80 1,012 10,514 110,138 1,074,750
7×n 5 126 2,322 38,928 666,757

Every figure is exact — no lower bounds anywhere. The small ones are re-derived
from scratch on every test run, and the blank boards up to 4×4 are counted a
second time by an engine that shares no code with the first.

The first row is the whole rule in miniature. A 1×n strip has exactly n − 2
answers.
In one row a group is a run of consecutive cells, and a run reads
1, 2, 2, …, 2, 1. A run of one contains a 0; a run of two has two 1s touching; a
run of four or more has two 2s touching. Only a run of exactly three survives,
and there are n − 2 places to put it.

That also makes the blank 1×3 the one board in this puzzle that is a legal
puzzle with nothing printed on it at all: one answer, zero clues.

None of the other rows returns anything from OEIS. The 2×n row looks polynomial
for a while and is not: the cubic through 2×2 … 2×5 predicts 80 for 2×6, which
is correct, and then 124 for 2×7, where the true value is 126.

2. A clue can only ever say yes

Here is what makes this clue language strange. A printed number asserts there
is a number in this cell, and it is this one
. There is no notation for "this
cell is empty."
Every clue is positive; a setter can only add cells to the
answer, never remove them. Two consequences, pointing in opposite directions.

The lemma: print everything and you are always unique

Print every number in an answer and the board has exactly one answer.

Three lines. Any rival answer S′ must contain the whole clue set S, because the
clues say so. If S′ were strictly bigger, connectivity would put some cell of
S′ \ S next to a cell s of S, which lifts s's degree above the number printed on
it — contradiction. So S′ = S, and since the numbers are the degrees, the
numbers match too. ∎

Verified on 100 of 100 randomly drawn answers. Switch the connectivity rule
off and it holds on 39 of 100. The lemma is really the connectivity rule
wearing a disguise, which matters because the generator is built on it.

Almost nothing printable means anything

A clue set is a partial assignment: choose some cells, write 1–4 in each. On a
small board that is a finite alphabet over finite positions, so every clue set
a setter could ever print can be enumerated and solved
. I walked 1,254,128 of
them.

board clues clue sets impossible ambiguous exactly one
3×4 1 48 29.2% 70.8% 0.0%
3×4 2 1,056 65.8% 27.0% 7.2%
3×4 3 14,080 91.2% 5.0% 3.8%
3×4 4 126,720 98.5% 0.6% 0.9%
4×4 2 1,920 58.6% 40.1% 1.2%
4×4 4 465,920 96.6% 2.3% 1.1%
4×5 3 72,960 77.6% 20.4% 2.0%
5×5 2 4,800 42.9% 57.0% 0.2%
5×5 3 147,200 68.5% 30.8% 0.6%

(An extract; the whole table is on the demo page.)

91.5% of everything printable is impossible and only 1.2% of it is a puzzle.
The dead space grows with the clue count instead of shrinking — 98.5% at 3×4
with four clues — because every extra number is another chance to assert
something the grid cannot do.

And a single clue is never enough anywhere: 0 of the 352 one-clue boards has
exactly one answer.

3. The same census, restricted to the truth

Strip the lies out and the question changes completely. Take every answer of a
blank board, then every subset of that answer's numbers as a clue set. These can
never be unsolvable — the answer they came from still satisfies them — so the
only failure mode left is ambiguity, which is the setter's actual problem.

board answers true clue sets walked fewest clues that ever work median answer needs worst answer needs
3×4 162 13,582 2 3 4
3×5 428 131,428 2 3 6
4×4 702 261,346 2 3 6

Two numbers can pin an answer, and the median answer needs three. The gap
between this table and the previous one is the clue language: a setter is not
searching a space of clue sets, they are searching a space of answers and then
throwing numbers away.

Scaling up

board clues random clue sets: impossible random: exactly one true clue sets: exactly one
6×6 3 53.0% 0.2% 4.8%
6×6 12 100% 0% 21.1%
8×8 8 95.0% 0% 0%
8×8 25 100% 0% 16.9%
10×10 8 85.0% 0% 0%
10×10 25 100% 0% 0%

Scattering numbers at a board breaks down long before the board gets
interesting: 2 of 4,940 random clue sets across every size and clue count
sampled produced a puzzle, and from 8×8 upwards not one of them did.

Reading the clues off a real answer is better and still not a method. At 10×10,
a random subset of the answer's own numbers came out unique 0 times in 66
draws
, spread over every clue count from 3 to 25. (Small sample — drawing a
random 10×10 answer is itself expensive — but it never once worked.) The shipped
10×10 boards print 16–22 numbers and are unique every time, so which numbers
you keep matters as much as how many.

So the generator does not sample. It draws an answer, prints all of it (unique
by the lemma), and then erases one number at a time for as long as the board
stays unique. Worth noting against the previous entry in this series: in
Heteromino that erase-while-unique phase was impossible to write, because
there was no legal single-clue edit that removed a clue. Here it is three lines.

4. What the number is worth, and what the position is worth

A printed number does two jobs at once — it says a cell is numbered, and it says
which number. Those can be separated and measured. Replace every clue with a
bare mark ("a number lives here, but not which one") and the first job
survives while the second is discarded.

board shipped clues, numbers and all same cells, numbers erased every answer cell marked, no numbers every number printed
6×6 24 / 24 0 / 24 0 / 24 24 / 24
8×8 24 / 24 0 / 24 0 / 24 24 / 24
10×10 24 / 24 0 / 24 0 / 24 24 / 24

This came out stronger than I expected. Erasing the values off the shipped clue
positions leaves 0 of 72 boards unique. Marking every cell of the answer —
telling the solver the exact shape and withholding only the digits — also leaves
0 of 72. Writing the numbers on those same cells pins the answer 72 of
72
, which is the lemma above.

Knowing the shape of the answer everywhere is not the same as knowing the
answer.
A board of bare marks always admits some larger legal shape on top of
the one you meant; it is only when the numbers go in that the degrees are
pinned and growth is forbidden.

5. Dropping each rule

rule set boards that stop being unique of those, boards left with no answer
nothing removed 0 / 72 0
adjacent numbers may repeat 72 / 72 0
the numbers need not be connected 70 / 72 0
both removed 72 / 72 0

The column of zeroes on the right is not luck. Relaxing a rule can only add
answers
— the intended answer still satisfies the weaker rule set — so nothing
here can become unsolvable. That is the opposite of the previous entry in this
series (Heteromino), where tightening the rule left all 72 boards with no
answer at all.

Dropping connectivity leaves two boards standing out of 72: boards whose clues
happened to leave nowhere for a second group to go.

6. The ladder: the bottom two rungs cannot finish a single board

Branch points needed to prove the 72 shipped boards unique, summed per rung:

deg neq conn probe
6×6, 24 boards 3,840,046* 48,958 932 2
8×8, 24 boards 9,497,265* 1,862,473* 5,280 0
10×10, 24 boards 9,600,024* 7,618,877* 19,296 64

* is a lower bound. Each board was cut off at 400,000 branch points, and on
the bottom rung 53 of the 72 boards never finished — including every single
10×10.

What each rung settles from an untouched board, before any guess (this is what
the checkbox above the board displays):

unclued cells settled deg neq conn probe
6×6 11.5% 23.9% 27.2% 97.1%
8×8 10.2% 18.7% 21.3% 100%
10×10 10.7% 17.0% 19.1% 94.7%
  • deg is pure arithmetic. A cell holding v needs exactly v numbered neighbours, so v must sit between the neighbours already settled as numbered and the neighbours that could still become numbered. It runs both ways: at the upper bound the undecided neighbours must all be empty, at the lower bound they must all be numbered.
  • neq is local irregularity as an elimination — a settled number forbids itself next door.
  • conn is the only rung that looks at the whole board at once. It strikes out every cell that cannot reach the cells already settled as numbered, and it forces a number into any cell whose removal would cut those settled cells in two. That second one is an articulation point of the "could still be numbered" graph, and it is worth doing properly: one Tarjan pass with subtree counts of the settled cells, rather than removing candidates one at a time and re-flooding. It is worth three orders of magnitude.
  • probe is singleton consistency, and it finishes 68 of the 72 boards outright with no search at all.

The shape of this ladder is the interesting part. Local arithmetic gets about a
fifth of the board and then stalls; the global rule is what actually solves this
puzzle. Sukoro is a connectivity puzzle wearing numbers.

7. Which numbers actually appear

1 2 3 4
the 72 shipped answers 24.5% 38.0% 27.3% 10.2%
the numbers those boards print 42.8% 24.0% 26.6% 6.6%
every answer of a blank 5×5 37.0% 34.8% 23.1% 5.2%

4s are rare, and geometry explains that: a 4 needs all four neighbours numbered
and none of them a 4, so it wants a cross of smaller numbers around it, and the
local irregularity rule keeps taking that away.

The second row is the one I did not expect. The distribution of numbers in
the answers and the distribution of numbers actually printed on those same
boards are not the same: 24.5% of the numbers in the answers are 1s, against
42.8% of the numbers printed. Nothing in the minimiser knows what a digit
means — it erases whatever it can and keeps whatever it cannot.

The explanation, after the fact: a 1 says "exactly one of my neighbours is
numbered", which strikes out up to three cells at once. A 4 says "all four are
numbered", which strikes out nothing.
The clue that survives erasure is the
clue that forbids the most.

8. Erasing a clue cannot break a board

One last consequence of clues being purely positive. Erase one, and the original
answer still satisfies everything that remains — so a board can gain answers but
can never lose its last one.

board clues erased one at a time answers left, median boards made unsolvable clues moved instead still unique made unsolvable
6×6 54 6 0 162 3.1% 80.2%
8×8 90 8+ 0 270 2.2% 73.7%
10×10 153 8+ 0 459 2.4% 82.8%

(Counting stops at 8 answers, so 8+ means "at least 8".)

0 of 297 erasures produced an unsolvable board, exactly as the argument
says, and every one of them cost uniqueness — which is what makes the shipped
set minimal.

Moving a clue has no such protection. It keeps uniqueness 2–3% of the time
and kills the board outright 74–83% of the time: the exhaustive census's
91.5% seen from inside a board that works. Erasing and moving are the same size
of edit and not remotely the same kind of edit.

9. Two engines, sharing no code

Engine 1 gives each cell a five-way domain — blank, 1, 2, 3, 4 — as a
bitmask, propagates the four rungs to a fixpoint, and branches on the cell with
the fewest options left.

Engine 2 never builds a domain at all. It walks the grid in reading order
deciding one bit per cell — does this cell hold a number or not — and the
moment a cell's whole neighbourhood is decided it reads that cell's degree
straight off the board and checks it there.

Engine 2 can only be written that way because of the fact this whole article is
about: choosing the shape chooses the numbers, so engine 2 never picks a
value for anything. Every count engine 1 reports on a small board is checked
against engine 2 in the test suite, and all 72 shipped boards are cross-checked
by it.

Implementation

TypeScript and Vite, no runtime dependencies.

src/sukoro.ts     rules, the four rungs, engine 1
src/brute.ts      engine 2 (shares no code)
src/generate.ts   answer search, clue minimiser, clue-space censuses
src/ledger.json   blank-board answer counts   (npm run ledger)
src/puzzles.json  the 72 shipped boards       (npm run generate)
src/stats.json    every figure in this article (npm run stats)
tools/notes.mts   generates the demo page's notes from those two
Enter fullscreen mode Exit fullscreen mode

Every figure on the demo page is generated by tools/notes.mts from
src/stats.json and src/ledger.json. Not one of them is transcribed by
hand
— re-run the measurements and the prose follows. 53 tests.

Puzzle #57 in the solver series.

Top comments (0)