DEV Community

SEN LLC
SEN LLC

Posted on

Detour: the clause that isn't printed on the board prunes harder than every number that is

Detour in the browser with a five-rung solver. Draw one closed loop
through every cell exactly once; a number in a region counts how many
times the loop turns inside it. The word doing the work is every: that
clause is not a hint about the loop, it is the loop, and an answer is a
Hamiltonian cycle of the grid graph and nothing else. So every cell has its
two links before a number is read, and the only freedom left is one bit per
cell
. A plug DP counts answers exactly — 4,638,576 at 8×8 and
56,126,499,620,491,437,281,263,608 at 14×14 in 35 s, matching OEIS A003763 —
and prices the two clauses nobody prints on the board. Then the branch-point
table says the quiet one prunes harder than every printed number put
together. 37 tests. Puzzle #64 in the solver series.

Live demo: https://sen.ltd/portfolio/detour/
Source: https://github.com/sen-ltd/detour

Detour

The rules

  • The grid is cut into regions.
  • Draw one closed loop through cell centres.
  • The loop visits every cell exactly once.
  • A number in a region says how many times the loop turns inside that region.

I checked the rules against primary sources before writing a line of code — the
puzz.link rules database and cross-plus-a, two independent statements that
agree. I have abandoned work-in-progress puzzles before because I implemented a
rule I had half-remembered, so this is no longer a step I skip.

"Every cell exactly once" is not a hint. It is the loop.

Every loop genre I had built before this one — Slitherlink, Masyu, Yajilin,
Country Road — spends its clues telling you where the loop goes: which cells
it uses, which it skips, how it threads between them.

Detour does not have that question. "Every cell exactly once" is the
definition of an answer, not a hint about one:

An answer is a Hamiltonian cycle of the grid graph. There is nothing else
it could be.

Which means that before you read a single number, every cell already has two
of its four links
. The only freedom left is, cell by cell, whether those two
are opposite (a straight) or perpendicular (a turn) — one bit per cell —
and every number on the board is a statement about nothing but those bits.

Here is how extreme that is. Rub every number off a board, run the solver as
hard as it will go, and it settles eight links:

board links on the board settled with every number rubbed out what they are
6×6 60 8 (13.3%) the four corners, both links each
8×8 112 8 (7.1%) the four corners, both links each
10×10 180 8 (4.4%) the four corners, both links each

The grid corners have only two links to choose from, so both are forced. Not
one link more comes out.
All of the board's information is in the numbers and
in the structural clauses that are never written down.

Counting exactly: a plug DP

Because an answer is exactly a Hamiltonian cycle, "how many answers could this
grid have" is a question somebody else has already published the answer to. So
the counting machine has to reproduce it or it is lying.

The method is a connectivity-profile ("plug") sweep. Walk the cells in
reading order carrying a frontier of w + 1 plugs: one per column for the
vertical edge crossing the sweep line, plus one for the horizontal edge dangling
out of the cell just processed. A plug is an endpoint of a partial path, so
plugs come in pairs, and the state is which plug is paired with which.
Canonicalise the pairing by first appearance and the number of live states stays
small however much the number of cycles explodes.

grid Hamiltonian cycles published frontier states time
2×2 1 agrees 4 1 ms
4×4 6 agrees 77 1 ms
6×6 1,072 agrees 1,119 2 ms
8×8 4,638,576 agrees 12,852 14 ms
10×10 467,260,456,608 agrees 134,010 205 ms
12×12 1,076,226,888,605,605,706 agrees 1,333,112 2,693 ms
14×14 56,126,499,620,491,437,281,263,608 agrees 12,910,377 35,091 ms

That column is A003763. The last row counts
5.6 × 10²⁵ objects in 35 seconds. A depth-first enumerator that shares no code
with the sweep returns the same numbers everywhere it can reach, which is how I
know the sweep is not merely fast.

I wrote it as a memoised recursion from the end of the sweep rather than a
forward table, for one reason: rec(i, state) is then the number of ways to
finish, which is exactly the weight you need to sample a cycle uniformly at
random
in a single forward walk. Every answer this repo ships is a uniform
draw from all Hamiltonian cycles of its grid — not from whatever a randomised
depth-first search happens to like. A chi-square test over all 1,072 answers of
a 6×6 with 12,000 draws is in the test suite.

And one line that costs nothing and kills a whole family of boards:

The grid graph is bipartite, so a Hamiltonian cycle alternates colours and
needs the colour classes to be equal. An odd-by-odd board has no answer at
all
, whatever numbers you print on it.

3×3, 5×5, 7×7, 9×9, 11×11: all zero. The solver returns before it looks at the
board.

Pricing the two clauses nobody prints

The rule has two structural clauses that appear nowhere on the board: every
cell
and one loop. The same sweep counts what happens when you drop either.

how the rule is read 4×4 6×6 8×8 cost at 8×8
both clauses 6 1,072 4,638,576
several loops allowed 18 13,903 360,783,593 77.8×
cells may be skipped 213 1,222,363 603,841,648,931 130,178×
neither clause 321 5,735,477 11,282,914,491,065 2,432,411×

The third row is A140517, the number of cycles in an
n×n grid. The second is A222202, disjoint cycle
covers. The same generalised DP reproduces three published sequences, which
is an independent check that generalising it did not break it. The fourth row —
1, 13, 321, 23857, 5735477, 4468252413 — returned nothing when I searched the
OEIS in September 2026.

The two clauses are wildly different sizes: 130,000× against 78×. Hold that
thought, because the search is about to disagree about which one matters.

Every answer turns an even number of times, and far more than four

A closed rectilinear curve turns through 360° exactly once on the way round, so
its right turns exceed its left turns by exactly four: R − L = 4, and the total
T = R + L = 2L + 4.

On a fully numbered board the numbers must add up to something even.

A free global test, and it holds on 108 of the 108 boards here. It also gives a
bound, T ≥ 4, and that bound is worthless. Filling the grid is what actually
costs turns, and the sweep splits every cycle by its turn total:

grid cells fewest turns most turns mean distinct totals all even
4×4 16 8 12 9.3 2 yes
6×6 36 12 28 20.0 9 yes
8×8 64 16 56 35.5 21 yes
10×10 100 20 88 55.9 35 yes

The polygon bound says four. The true floor is twice the short side of the
grid
, on every grid in the table, and it is reached by exactly the answer you
would draw by hand: the boustrophedon comb that runs down one column and snakes
back across the rest. The ceiling has no such tidy shape, and no answer of any
size gets every cell to be a corner.

The mean is the number a setter should keep in mind. A 10×10 answer turns 55.9
times in 100 cells, so 55.9% of a typical answer's cells are corners, and a
board's numbers have to add up to roughly that whether the setter thought about
it or not. The shipped answers average 55.9% too — which is what uniform draws
ought to do, and is the cheapest check I have that the sampler is uniform.

What one number is worth

At 6×6 there are only 1,072 answers, so "what does this clue rule out" can be
answered by walking all of them.

answers left share of all 6×6 answers
all 6×6 answers 1,072 100.0%
one region's number (median of 332) 327 30.5%
the sharpest single number in the bank 10 0.9%
the bluntest single number in the bank 760 70.9%
the numbers a shipped board actually prints 1 0.1%

A median single number keeps 30.5% of the answer space; the bluntest keeps
70.9%, which is barely saying anything. Nothing in this genre is decided by
one number.
It is decided by how few answers survive all of them at once.

Numbering every region is not enough

The generator draws an answer uniformly, cuts the grid into regions at random,
and writes the true turn count into every region. That is the most
informative board that partition can carry. It is usually still not a puzzle.

board draws unique with every region numbered rate
6×6 200 149 74.5%
8×8 200 86 43.0%
10×10 60 7 11.7%

At 10×10, 88.3% of fully numbered boards still have a second answer, and
most of the generator's time goes on throwing those away. The shipped boards
then go the other way — numbers are erased for as long as the board stays unique
— which leaves a median of 5, 10 and 16 numbers at the three sizes.

The dial is real. It is just not the dial the generator turns.

Keep a random subset of a shipped board's full clue set and uniqueness climbs
with the number of numbers, so this genre does have a clue dial. But it starts
flat: at 8×8, no subset of nine or fewer numbers is ever unique, whichever
nine you pick.

The dial the generator turns is the partition. Take one shipped answer, leave
it completely alone, and redraw the regions over the top 40 times, numbering
every region each time. Over 12 answers and 480 redraws, 257 produce a unique
board — 53.5% — with the friendliest answer landing 27 of 40 and the most
hostile 16.

Same answer, same rule, same clue count. Whether it is a puzzle depends on
where the walls fell.

Region size is a real knob too, and it pulls the way you would expect once you
notice what a small region can say:

target region size regions on an 8×8 draws unique with every region numbered
2 24.8 120 82 (68.3%)
3 20.6 120 78 (65.0%)
4 16.1 120 51 (42.5%)
5 13.4 120 36 (30.0%)
6 11.5 120 32 (26.7%)
8 9.2 120 10 (8.3%)

The shipped boards use 4 at 6×6 and 8×8 and 5 at 10×10 — not the setting that
yields the most puzzles, but the one that leaves enough cells per region for the
number to be worth reading.

The ladder, and the rung that is not on the board

  • degree — every cell has exactly two loop links. Arithmetic on four bits, and what fixes the corners.
  • turn — the region numbers, read through the straight/turn bit. A cell known to be a turn has exactly one link from each axis, so deciding one bit decides up to four links.
  • cut — for any set of cells the loop crosses the boundary an even number of times, and at least twice, because it has to reach the cells inside. Applied to every region and every straight cut across the board.
  • loop — no cycle may close before it has swallowed the whole board.
  • probe — assume a link, run the cheaper rungs, drop it if the board dies.
rung 6×6 settled 6×6 finished 8×8 settled 8×8 finished 10×10 settled 10×10 finished
degree 13.3% 0/36 7.1% 0/36 4.4% 0/8
turn 29.0% 0/36 21.0% 0/36 14.7% 0/8
cut 30.9% 0/36 21.2% 0/36 14.7% 0/8
loop 36.9% 1/36 24.0% 0/36 15.6% 0/8
probe 94.7% 33/36 71.3% 18/36 42.6% 0/8

Propagation alone finishes 33 of 36 boards at 6×6, 18 of 36 at 8×8, and none of
the 10×10s. That is the honest answer to "how hard is this genre": the numbers
are weak enough locally that most boards need a case split somewhere.

Now price the rungs as pruning instead. Run the complete search but only let
it propagate up to a given rung between branches, and count branch points:

propagation allowed 6×6 median 6×6 worst 8×8 median 8×8 worst
up to degree 13,902 13,902 past the 200,000 cap past the cap on 36 of 36
up to turn 46 649 1,412 26,135
up to cut 35 402 1,155 21,843
up to loop 10 68 46 1,232

This is the table I would keep if I could keep only one. Reading the numbers
takes a median 8×8 board from past a 200,000-node cap down to 1,412 branch
points. Then adding the single clause that is printed nowhere on the board
that the links form one loop and not several — takes it from 1,155 to 46, a
further 25×.

The printed numbers are worth a lot. The unprinted clause is worth more.

Which is the opposite of what the answer-space table said, and both are true.
"Every cell" shrinks the space by 130,000× but it is baked into the degree
rung from the first instant, so there is nothing left for the search to earn
from it. "One loop" only bites once there are partial paths to look at — so it
is worth little as a bound and a great deal as a pruner. Shrinking the space
and pruning the search are not the same skill.

Three ways to misread the board, and they do not fail alike

misreading board intended answer still legal answers (median, capped at 12) still unique
several loops allowed 6×6 36/36 8 0/36
the number counts straights 6×6 0/36 0 3/36
no numbers at all 6×6 36/36 1,072 0/36
several loops allowed 8×8 36/36 12 0/36
the number counts straights 8×8 0/36 0 0/36
no numbers at all 8×8 36/36 4,638,576 0/36

Reading the number as counting straights is the loud failure: the intended
answer stops being legal on 72 of 72 boards, so the board does not work and you
find out on the first deduction. You cannot ship that mistake.

Allowing several loops is the quiet one, and it is the dangerous one. One
loop is a special case of several, so the intended answer stays legal and
nothing ever contradicts — but uniqueness dies on 72 of 72 boards. That is the
mistake worth guarding, and guarding it is exactly what the loop rung is.

Takeaways

  • A Detour answer is a Hamiltonian cycle of the grid graph, so the numbers only ever speak about one bit per cell.
  • A plug DP counts them exactly, reproducing three published OEIS sequences and reaching 14×14 in 35 seconds — and the same DP samples answers uniformly.
  • Turn totals are always even; the real floor is twice the short side, not the polygon bound of four.
  • Numbering every region leaves only 11.7% of 10×10 boards unique. The dial the generator turns is the partition, not the clue count.
  • Measured as pruning, the unprinted one-loop clause beats every printed number on the board.

Every figure on the page and in the README is generated from stats.json and
counts.json; none of them is typed in by hand. 37 tests.

Live demo: https://sen.ltd/portfolio/detour/
Source: https://github.com/sen-ltd/detour

Top comments (0)