Dosun-Fuwari in the browser with a four-rung solver. Both clauses of
the rule only ever mention a piece of the same kind — a balloon can only be
held down by a balloon, an iron ball only held up by an iron ball — and that
one word collapses the board. Inside a maximal vertical run of white cells the
balloons are a prefix and the iron balls a suffix, so a run of length
Lhas exactly the(L+1)(L+2)/2states(b, s)withb + s ≤ L: the
triangular numbers, A000217. Where the cells sit
does not matter at all. And because a run-top is a legal balloon whatever else
is on the board, every room that owns a run-top chooses independently of every
other room — so a board with no starved room has exactly∏T_i · ∏B_ianswers
(225 of 225 measured, and 0 of 650 once a room is starved). Which means a
unique, non-trivial board has to starve a room of run-tops and force a
stacked balloon. A solver that never stacks finds no answer at all on all 72
shipped boards. Puzzle #58 in the solver series.
Demo: https://sen.ltd/portfolio/dosun-fuwari/
Repo: https://github.com/sen-ltd/dosun-fuwari
The rules
The white cells of the grid are cut into rooms. Put exactly one balloon
(○) and one iron ball (●) in every room.
- Balloons are light and float, so a balloon sits in the top row, or directly under a black cell, or directly under another balloon.
- Iron balls are heavy and sink, so an iron ball sits in the bottom row, or directly over a black cell, or directly over another iron ball.
That is all. Black cells belong to no room.
The thing worth staring at is that each clause names only a piece of its own
kind. What holds a balloon down is a cap or a balloon — not an iron ball.
That single word decides nearly everything below.
The grid is a decoy
Take a maximal vertical strip of white cells and call it a run. By
construction it is capped at both ends: a black cell, or the edge of the grid.
Now look inside it. A balloon needs a cap or a balloon directly above, so there
is no such thing as a balloon with an empty cell over it — the balloons of a run
are a contiguous prefix. By the same argument the iron balls are a
suffix. The middle is empty.
So the state of a run of length L is written completely by a pair (b, s)
with b + s ≤ L, and there are (L+1)(L+2)/2 of those — the triangular
numbers.
L=1: 3 L=2: 6 L=3: 10 L=4: 15 L=5: 21 L=6: 28 ...
And the placement space of a whole board is the product over its runs. Not
where the cells are — only how long the vertical strips are. A shipped 8×8 has
10.7 runs and about 10^13 placements before a single room is read; a 12×12 has
22.2 runs and 10^28.4. The solver never looks at a cell. It carries one short
list per run and crosses entries off.
This reduction is the load-bearing claim in the repository, so the tests do not
trust it. They enumerate all 3^L fillings of a single column by brute force and
confirm the survivors are exactly the (L+1)(L+2)/2 states for L = 1..9. Then
they cross-check the run-based solver against a second engine that knows
nothing about runs — a plain backtracker that picks a balloon cell and an iron
ball cell in every room by exhaustion and validates the finished grid cell by
cell — and require the same answer set, not merely the same count.
Restating the rule as "or another piece" gives you a different puzzle
The wording that circulates trades "another balloon" for "another piece": a
balloon may be held down by an iron ball, an iron ball held up by a balloon. It
reads like the same rule, said shorter.
It is not. It legalises an iron ball resting on the balloon directly below it,
while that balloon is hanging from that same iron ball, with nothing under either
of them — a two-cell blob floating in mid-column, each piece's excuse being the
other.
Once that is allowed, a run's states stop being a prefix and a suffix, and the
counts become A095263, the Pisot sequence E(3,7),
satisfying a(n) = 3a(n-1) - 2a(n-2) + a(n-3):
| run length | official | loose reading |
|---|---|---|
| 1 | 3 | 3 |
| 2 | 6 | 7 |
| 3 | 10 | 16 |
| 4 | 15 | 37 |
| 6 | 28 | 200 |
| 8 | 45 | 1,081 |
| 12 | 91 | 31,572 |
10^13 becomes 10^19.2 on an 8×8, and the puzzle does not survive the
difference. Of the 36 shipped 8×8 boards, 0 have a unique answer under the
loose reading — every one of them blew past a 5,000-answer counting cap. Redone
on 6×6 boards small enough to count out exactly, 40 unique puzzles became 0
unique puzzles, and the smallest answer count among them was 3,264.
The informal wording does not make the puzzle easier. It deletes it.
The repository states the same fact a third way, as a fixpoint instead of a local
check. ungroundedCount walks each piece's support chain and asks whether it
terminates at a cap — the physical reading, "does this settle", rather than the
written one. Under the official rules the answer is always zero on every
legal placement, and the tests assert it. Under the loose reading a two-cell
example leaves both pieces ungrounded.
A run-top is always a legal balloon, and that decides everything
The top cell of a run leans directly on a cap. So a balloon there is legal
whatever else is on the board. Same for the bottom cell and an iron ball.
Now count. If every room contains at least one run-top, each room picks its
balloon from its own tops and nothing any other room does can interfere. The
choices are independent, and a board with T_i tops and B_i bottoms in
room i has exactly
∏ T_i · ∏ B_i
answers.
That is a prediction, so I measured it instead of assuming it. 225 of 225
boards with no starved room had exactly the predicted count, and none had more.
On the 650 boards that did starve a room, the formula was right 0
times. It is not an approximation that frays at the edges — it is a different
regime.
And out of that falls the design problem of this puzzle. To be unique, every term
must be 1: every room holds exactly one run-top and one run-bottom, so there are
exactly as many rooms as runs. But then the answer is "every run-top is a
balloon, every run-bottom is an iron ball", which a solver can write down
without reading the rooms at all.
Uniqueness and interest collide head-on, and there is exactly one way out:
starve a room. Give it no run-top whatsoever. Its balloon then has to be
stacked on a balloon that lives in some other room, and that demand reaches
across and pins the other room's choice too.
Every board here is built that way — 8×8 with a median of 3 starved rooms, 12×12
with 6 — and the ablation is blunt: a solver that never stacks a piece on its own
kind finds no answer at all on 72 of the 72 shipped boards.
The dial is the number of starved rooms
The generator draws the trivial board first — one room per run, always unique,
never a puzzle — and then starves rooms one at a time. Hand a run's top cell to a
neighbouring room, and the room left behind has lost its top and must stack. Each
starved room is another chance to lose uniqueness.
| starved rooms | 8×8 drawn | unique | rate |
|---|---|---|---|
| 0 | 220 | 220 | 100.0% |
| 1 | 220 | 200 | 90.9% |
| 2 | 220 | 185 | 84.1% |
| 3 | 216 | 157 | 72.7% |
| 4 | 153 | 112 | 73.2% |
The binding constraint turns out not to be the uniqueness rate but the drawing.
Past four, an 8×8 runs out of runs long enough and adjacent enough to starve —
which is why the 8×8 boards here stop at four. A 12×12 has 22.2 runs, reaches
eight, and is still at 55.1% there.
Random boards are dead on arrival
Scatter black cells at random, cut the white cells into random connected rooms,
and ask for an answer:
| board | black | drawn | no answer | one | more |
|---|---|---|---|---|---|
| 6×6 | 0 | 600 | 600 | 0 | 0 |
| 6×6 | 0.12 | 600 | 594 | 0 | 6 |
| 8×8 | 0 | 600 | 600 | 0 | 0 |
| 8×8 | 0.12 | 600 | 599 | 0 | 1 |
| 8×8 | 0.20 | 600 | 596 | 0 | 4 |
| 10×10 | 0.15 | 600 | 600 | 0 | 0 |
3,589 of 3,600 have no answer at all, and 0 have exactly one. Every room
needs a cell it can reach with a prefix and a cell it can reach with a suffix,
and random rooms simply do not oblige.
So the generator works answer-first — and it never checks the placement rules at
all. It only ever puts a balloon at the top of a run and an iron ball at the
bottom, and those are legal by position. What it checks is uniqueness, the only
thing actually in question.
The ladder
Four rungs, each a strictly stronger propagator over the same per-run domains.
-
run— the run states and nothing else, no propagation. -
room— one balloon and one iron ball per room: a run state that drops two of a kind into one room is dead, and a room only one run can serve forces that run. -
profile— a piece pinned in one room cuts its whole run, so the rest of that run's cells lose the option everywhere else they touch. -
probe— singleton consistency: assume one run state, propagate, drop it if that alone contradicts.
The split lands exactly on the structure above. Of 150 generated boards with no
starved room, all 150 finish at room — counting alone, never once
consulting floating or sinking. All 72 shipped boards need profile, and
none needs probe or any search whatsoever. Starving one room moves a board
a whole rung, and no further.
Where the generator kept dying
The first generator was the obvious one: draw a random placement, draw rooms
around it, retry until unique. It did not work at all, and the ways it failed
were instructive.
- Draw rooms first, and 3,589 of 3,600 boards have no answer.
- Draw the answer first and flood rooms around it, and you get dozens of answers.
- Build rooms by growing a patch from every piece and pairing balloon patches to iron-ball patches with a bipartite matching, and 150 of 150 boards have no perfect matching — balloons stratify near the top and iron balls near the bottom, so a balloon patch's whole border is other balloon patches.
- Hill-climb by handing empty cells to neighbouring rooms until unique: 0 of 25. The ambiguity sits on an interior cell with no other room to give it to.
I only understood why after working out ∏T_i · ∏B_i above: every one of those
attempts was failing for the same reason. As long as each room owns a run-top,
the choices are independent and the product is never 1. The ambiguity was not
under-constrained, it was structurally unremovable. Once "starved room" was the
concept, the generator became a few lines.
Summary
- Both clauses of the rule name only a piece of the same kind, so a run's balloons are a prefix and its iron balls a suffix, and its state count is the triangular number A000217.
- The loose "or another piece" restatement legalises a floating mutually-supporting pair, changes the state count to A095263, and takes the shipped boards from 36/36 unique to 0/36.
- A run-top is always a legal balloon, so a board with no starved room has
exactly
∏T_i · ∏B_ianswers — 225 of 225 measured. - Therefore a unique, non-trivial board must starve a room and force a stack. A solver that never stacks finds nothing on all 72 shipped boards.
- The ladder splits on the same line: 150/150 unstarved boards finish at
room, 72/72 shipped boards needprofile, and nothing needsprobeor search.
Puzzle #58 in the solver-backed series. 21 tests, no runtime dependencies.

Top comments (0)