DEV Community

SEN LLC
SEN LLC

Posted on

Choco Banana: the half of the rule that can only say no is six times the more expensive half

Choco Banana in the browser with five rule sets inside. Every group of
shaded cells must be a rectangle; every group of unshaded cells must not be.
The same predicate, affirmed once and denied once — and the denied half turns
out to be the one you cannot afford to lose. Puzzle #52 in the solver series.

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

Choco Banana

Rules

Shade some cells of an H×W grid.

  1. Every orthogonally connected group of shaded cells is a rectangle — a chocolate bar.
  2. Every orthogonally connected group of unshaded cells is not a rectangle — a banana.
  3. A number in a cell gives the size of the group that cell belongs to, and says nothing at all about which colour that group is.

Rules 1 and 2 are the same predicate, affirmed once and denied once. Rule 3 hands
you an area and withholds the colour. Those two asymmetries are the whole puzzle,
and they are what this repository measures.

The two directions are not equivalent as inference

"Is a rectangle" is closed under bounding boxes. Any set of shaded cells
known to be in one group drags its entire bounding box in with it, so two shaded
cells can fill a block. It pushes.

"Is not a rectangle" is closed under nothing. A banana that happens to be a
rectangle right now is not yet illegal. It only becomes illegal once it is sealed
shut and can no longer grow. So the rule cannot advance a position — it can only
reject one, and only at the very last moment.

Which makes the denied half look like the cheap half.

It is not.

Attribute every cell the solver writes to the rung that wrote it, over the 68
shipped boards:

size boards value rect size anti probe
6×6 38 19.8% 5.5% 62.6% 4.2% 7.9%
8×8 30 15.3% 3.5% 67.4% 4.5% 9.2%

The two halves of the rectangle predicate write about the same number of cells,
and both are dwarfed by the group-size arithmetic. But now drop one rung at a
time out of the full stack:

variant settled finishes with no guessing assumptions
all rungs 100.0% 68/68 0
value 86.7% 50/68 332
rect 97.2% 54/68 498
anti 89.8% 36/68 11,686
size 23.5% 8/68 3,623,318

Without probing sitting on top, − rect costs 17,452 assumptions across the set
and − anti costs 103,958. The rule that can only say no is six times more
expensive to do without than the rule that can say yes.

Why

The affirmed half has already moved house.

Its real work is happening inside the size rung. A clued chocolate bar of area
v gets matched against the set of area-v rectangles that still fit around the
cell without swallowing a known banana; cells common to every survivor are shaded,
and cells touching the group but inside no survivor are banana. That is "is a
rectangle" — with a number attached. By the time you get to rect standing on
its own, there is almost nothing left for it to do.

The denied half has no second home. Nothing else in the solver knows that a
sealed rectangle of unshaded cells is illegal, so when you delete it, that
knowledge is simply gone and the search pays for it.

(The unique column is worth a footnote: with size removed the search blows
past its 60,000-node ablation budget on 58 of the 68 boards, so it can only
confirm uniqueness on 10 of them. The answer counts did not change — the
budget did. That is itself a measurement of the cost.)

As rules rather than as inferences, both halves are load-bearing

Uniqueness is a property of the rule set, not of the solver. So ablate the two
halves as rules of the puzzle and re-count the answers:

size boards full rules without "banana ≠ rectangle" without "chocolate = rectangle"
6×6 38 38/38 12/38 21/38
8×8 30 30/30 12/30 9/30

Delete "a banana is not a rectangle" and 26 of the 38 6×6 boards and 18 of the 30
8×8 boards stop having a unique answer, the median board picking up 2 and 4.5
answers respectively. Delete the other half and at 8×8 it is worse — only 9 of
30 survive.

So as constraints the two halves are comparable; the asymmetry lives entirely on
the inference side, and it points the opposite way from the intuition.

A number is a factorisation, not a quantity

The clue gives a size and withholds the colour, so reading it is an arithmetic
question.

  • A connected set of 1 or 2 cells is a rectangle however you draw it. So 1 and 2 are always chocolate.
  • A chocolate bar of area v exists on an H×W board only if v = a·b with a ≤ H and b ≤ W. A number outside that multiplication table is always banana — on a 6×6 board that is 7, 11, 13, 14, 17, 19, 21, 22, 23, 26….

And a banana of area v exists exactly when 3 ≤ v ≤ H·W − 1 (with H, W ≥ 2).
The two ends are precisely the cases that force a rectangle, and everything
strictly between is constructible: take ⌊v/W⌋ full rows plus the remainder, and
when the remainder is zero, shave one cell off the last full row and hang it
below instead.

So the value rung never looks at the grid at all. The number and the board
dimensions are enough.

v 6×6 8×8 10×10
1, 2 chocolate chocolate chocolate
7 banana either either
11, 13 banana banana banana
14 banana either either

More than half of all possible group sizes name their own colour on sight: 21 of
36 on a 6×6 board (58.3%), 37 of 64 on an 8×8 (57.8%), 61 of 100 on a 10×10
(61.0%). On the shipped 6×6 boards, 271 of the 388 clues (69.8%) are of that
kind — 195 of them because they are a 1 or a 2, 76 because they are off the
times table.

The number of areas a bar may have on an n×n board is exactly
OEIS A027424: 1, 3, 6, 9, 14, 18, 25, 30, 36, 42.

Some answers no clue set can pin down

The clue language of Choco Banana is precisely the map cell → size of its
group
. So the strongest clue set that can exist is a number in every cell, and a
one-line theorem falls out:

An answer can be made unique if and only if it is the only legal grid with
its size map.

(⇐) If it is the only one, write every size and it is pinned. (⇒) If another
answer B has the same size map, then B satisfies every clue A satisfies, so
no clue set on earth can exclude it.

And the right-hand side is not always true. On a 3×4 board, a 2×3 chocolate bar
in any of the four corners leaves six banana cells in an L — and all four grids
read 6 in every single cell.

###.     .###     ....     ....
###.     .###     ###.     .###
....     ....     ###.     .###
Enter fullscreen mode Exit fullscreen mode

Write all twelve numbers and four answers still stand.

Exhaustively, over every legal grid on small boards:

board answers distinct size maps answers in a tied group biggest tie
2×2 … 3×3 5 … 121 all distinct 0 (0.0%) 1
3×4 599 596 4 (0.7%) 4
3×5 3057 3055 4 (0.1%) 2
4×4 4835 4831 8 (0.2%) 2
4×5 40899 40875 48 (0.1%) 2

Not one pair exists up to 3×3; they appear at 3×4 and then sit at around 0.1%.
The generator has to detect them and walk away — its adversarial clue-buying loop
returns null the moment it cannot find a single cell where the two answers
disagree about a size.

Both clue dialects are incomplete

Restrict clue buying to numbers that name their own colour, then to numbers that
do not:

size boards unrestricted forcing only silent only price (median)
6×6 38 38 19 15 6.0 / 7.0 / 8.0

Unrestricted, all 38 answers can be pinned. With only self-naming numbers, 19.
With only silent ones, 15. The price — the median size of the minimal clue set —
barely moves (6 / 7 / 8), so what each dialect loses is not cost but reach.

probe is sound here, but not complete

In the previous puzzle in this series, "singleton consistency finishes the grid"
and "the board has exactly one answer" agreed on all 718 clue prefixes tested.
Not here.

  • clue prefixes tested: 581
  • agreement: 525 (90.4%)
  • unique but probe stalls: 56
  • probe finishes but the board is not unique: 0

The gap only points one way. Not once did probe claim to have finished a
board that turned out to have a second answer — if it had, that would be a
soundness bug, not a statistic. But 56 times a board had exactly one answer and
probe still needed a guess to find it. Difficulty and search strength come
apart here in a way they did not last time.

Every shipped clue set is minimal in the strict sense: removing any one of the
518 uniqueness clues, one at a time, left 0 of them still unique, and the
median board grew to 26 answers.

External ledgers

Answers on a board with no clues at all, agreed by all engines:

grid legal grids
n×n, n = 1…5 1, 5, 121, 4835, 584931
1×n 1, 1, 1, 1, 1, 1, 1, 1
2×n, n = 1…10 1, 5, 19, 57, 171, 509, 1505, 4441, 13105, 38689
3×n, n = 1…8 1, 19, 121, 599, 3057, 15525, 78781, 399575

None of those is in OEIS as of 2026-09. The 1×n row is not a coincidence and
not a bug: every connected piece of a strip is a rectangle, so no banana can live
on one at all, and the only legal grid is all-chocolate for every n.

The one number that does reach outside the repository is the multiplication
table, A027424 above.

Three engines

Three implementations that share no code have to agree on every board:

  • solveCtx — the propagating search
  • bruteByMask — treats the grid as an integer and tries all of them
  • bruteByCells — walks cells in raster order and closes each group the moment its last neighbour is coloured, checking rectangularity and clue sizes there and then

67/67 on the shipped boards for solver vs cell enumerator, 100/100 on random
clued boards small enough for all three. 72 tests.

That cross-check earned its keep during development. The anti rung was built
the obvious way: collect the list of unshaded components, then loop over it. But
a write inside that loop can merge two bananas, which makes every later entry
in the list stale — and a stale component is a subset of the real one, so it can
look like it has no way out, i.e. like a sealed rectangle. The solver was
rejecting correct answers as contradictions. The cell enumerator caught it on one
4×4 board with solver=0, brute=1. The fix is one line — return 'changed' the
instant you write, and let the outer loop rebuild the list — and there is a
regression test with the minimal 4×4 case that reproduces it.

The five rungs

rung what it is
value the number alone names the colour: 1/2 are chocolate, an area off the H×W times table is banana
rect every chocolate bar fills its bounding box
size a clued group is exactly that big: lower bound (what it holds) and upper bound (what it can reach), both saturating, plus the intersection of the surviving rectangle placements
anti a banana may not be a rectangle: a sealed rectangular banana is a contradiction, one with a single way out must take it, and a cell walled in on four sides is chocolate
probe singleton consistency on top

Cumulatively on 6×6 they settle 19.8% → 34.4% → 69.7% → 79.8% → 100%.

Generation

Answer first. Step one finds a legal grid by running the solver on a board with
no clues, with the branching order shuffled and the colour order biased, so every
answer is legal by construction. Step two buys clues adversarially: while a second
answer exists, find a cell where the two grids put a differently sized group and
write that size there. It stops when uniqueness is reached, or gives up when no
such cell exists — which, as above, genuinely happens.

Then the clue set is minimised twice: once down to a uniqueness-minimal set, and
once down to a set that also lets the target rung finish without guessing. The
median 6×6 board needs 6 clues to be unique and 11 to be guess-free; at 8×8 it is
10 and 16.5.

Try it

git clone https://github.com/sen-ltd/choco-banana
cd choco-banana && npm install
npm run dev
npm test
Enter fullscreen mode Exit fullscreen mode

?board=8-3&fill=size opens a specific board with one rung already run, so a
link can point at exactly the position being discussed.

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

Top comments (0)