DEV Community

SEN LLC
SEN LLC

Posted on

Gokigen Naname (Slant): the no-loop rule is a counting theorem — every board is a forest with exactly 2n+1 trees

Gokigen Naname (Slant) in the browser with four rule sets inside.
Fill every cell of an n×n grid with one diagonal — / or \**. A circled
number on a lattice point counts the diagonals whose tip touches it, and
the diagonals must **never close a loop
. Puzzle #34 in the solver series.

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

Gokigen Naname

I picked this one because the rule that looks topological — no loops — turns
out to be arithmetic.

The no-loop rule is V − E

Every cell adds exactly one edge to a graph on the (n+1)×(n+1) lattice
points: \ joins the cell's top-left and bottom-right corners, / joins the
other two. Either way, one edge. A finished board is therefore n² edges on
(n+1)² vertices.

A graph with no cycle has exactly V − E connected components, and
(n+1)² − n² = 2n+1. Every legal Slant board is a spanning forest with
exactly 2n+1 trees, whatever the clues say.
The component count is not a
degree of freedom. Measured over 1,500 generated boards: 2n+1 trees, zero
exceptions — which is why the demo's win message says so.

export function edgeOf(k: number, orient: number, n: number): [number, number] {
  const [tl, tr, bl, br] = cornersOf(k, n);
  return orient === BACK ? [tl, br] : [tr, bl];
}
Enter fullscreen mode Exit fullscreen mode

The whole puzzle is a paraphrase of that function, and every rule in the
solver is a sentence about it.

The four rule sets

The solver prunes a candidate array cand[k] ∈ {/, \, both}.

level rule
count one clue at a time: placed diagonals reach the number → the rest turn away; the undecided cells are exactly the missing ones → they all turn in
cycle a union-find over the lattice points; an orientation that would join two already-connected points is dead
duet two orthogonally adjacent clues read as one constraint: enumerate the ≤64 joint assignments of their ≤6 cells, keep only what every survivor agrees on
probe assume one diagonal, run the rules below to a fixpoint, drop the assumption if that alone is a contradiction

duet swallows the textbook tricks whole. "Adjacent 3s force the four outer
diagonals in", "adjacent 1s make their flanking cells equal" — special cases
of the enumeration.

The second of those hides a trap. What the textbook rule actually
concludes about the two cells flanking adjacent 1s is "A and B point the same
way" — the output is not a cell value but an equality between two cells.
A unary propagator cannot write that down, and the enumeration confirms it:
both A=B=/ and A=B=\ survive, so no cell is forced. Try to translate classic
techniques into propagators one-for-one and you discover some of them output
relations, not values. duet extracts the unary part; the leftover equality
fires through count the moment one side decides; whatever still escapes is
probe's job. The test for adjacent 3s shows exactly this shape — four outer
cells forced, the two middle cells still open as an XOR:

expect(c2[cellId(1, 1, 5)]).toBe(BACK); // outer: forced by duet
expect(c2[cellId(1, 2, 5)]).toBe(BOTH); // middle: only a relation survives
Enter fullscreen mode Exit fullscreen mode

Incremental and ablation tell different stories

300 raw generator boards per size, clue density 0.75, unfiltered by
uniqueness or difficulty — so the numbers are not shaped by the property they
measure. Fraction finished by the fixpoint alone:

board count +cycle +duet +probe unique answers in the raw stream
5×5 78.7% 82.0% 82.7% 83.3% 83.3%
7×7 56.3% 62.7% 66.7% 68.3% 68.3%
10×10 31.7% 42.7% 52.7% 55.0% 55.0%

Now the same rules ranked by ablation — full ladder minus one rule, same
boards:

board full −count −cycle −duet
5×5 83.3% 71.7% 79.3% 83.3%
7×7 68.3% 55.7% 60.3% 68.3%
10×10 55.0% 39.0% 40.7% 55.0%

Incrementally, duet looks like the hero of 10×10: +10.0 points. Ablate it
and not a single board is lost — the probe behind it catches every board
it would have caught. Remove cycle instead and the full ladder drops 14.3
points: probe cannot substitute for it. Same "measured against the bench"
problem as the last two puzzles in the series. But redundant is not useless:
what duet buys is finishing boards without guessing that cycle alone
cannot — precisely what a difficulty grade measures, so the shipped bank's
four grades include a duet tier, and every (size, grade) bucket is full.

The −count column is my favourite: delete the fundamental rule and the
ladder still solves 39% of 10×10 boards, because duet quietly re-derives
counting for every clue that has an orthogonal neighbour. At density 0.75
most clues do; only the isolated ones go completely invisible.

Probe = uniqueness, again

In the first table the probe column equals the unique-answer column at
every size
— and across all eleven points of the density sweep below, too.
A sound fixpoint can never finish a board with two answers, so "solved by
rules" is capped by the uniqueness rate. The ladder sits exactly on that
ceiling.

Slant is clue-hungry

Sweeping clue density on 10×10 boards, 150 per point:

density unique probe count
0.55 1.3% 1.3% 0.0%
0.65 11.3% 11.3% 2.0%
0.75 50.7% 50.7% 28.0%
0.85 90.7% 90.7% 85.3%
0.95 100% 100% 100%

The threshold is sharp: nearly nothing decides at 0.55, everything at 0.95.
One clue is a weak constraint — a number 0–4 over at most four cells —
against n² bits of board freedom. Published Slant puzzles put numbers on more
than half the lattice points, and that is not a stylistic choice; it is
information-theoretic necessity. (Degree distribution of the raw stream at
10×10: 0/1/2/3/4 = 8.6 / 38.5 / 34.8 / 15.1 / 2.9% — clue 4s are rare by
statistics, not by design.)

Certifying uniqueness barely needs search at the top of the ladder: over 100
raw 10×10 boards, the median number of branchings to confirm the solution
count was 1 for count, 1 for cycle, and 0 for both duet and
probe
.

Checking it

Two independent counters score every board: a propagating search run at each
of the four rule levels, and a brute force that shares none of their code —
row-major cell order, nothing but degree arithmetic and a rollback
union-find, every leaf judged by a standalone validator. All levels must
agree with the brute force on the number of solutions of every board — a
sound rule set cannot change how many solutions a board has.

One exact anchor: a clueless 2×2 board has 15 fillings — 2⁴ = 16
assignments minus the single diamond loop around the centre point. All five
counters agree on 15. 27 tests.

Play it

The Hint button fills one provable cell at the selected level; the rules
selector doubles as difficulty, and the bank only serves boards that first
become guess-free at that level. A probe-grade 10×10 needs an assumption even
after count, cycle and duet have all had their say.

Next up: another puzzle with the solver built in.


SEN LLC — public experiments in software.
More of the portfolio: https://sen.ltd/portfolio/

Top comments (0)