Canal View

Flood some cells to make one connected canal that never fills a 2×2 block. Every number stays dry, and counts the flooded cells it can see: walk out in the four directions and add up the runs that start next to it. A run stops at the first dry cell, and whatever is behind that cell is not counted. Click a cell to flood it, again to mark it dry, again to clear it.

the board

canal — flooded dry — marked as not canal number — always dry proved — what the selected rung already knows

A number is not a statement about its row and column

The rule everyone reads first is "the number counts the black cells it can see in the four directions". The word doing the work is see: a run stops at the first dry cell, and whatever is behind that cell is not counted. So a number describes the near end of its four rays and nothing else — and one dry cell hides an unbounded amount of canal.

Measured over the 72 boards shipped here: an 8×8 number says 3.84 on average while 5.28 flooded cells actually sit in its four rays, so it is looking at 72.8% of them. At 12×12 that falls to 64.7%. The bigger the board, the more of it every number is blind to.

boarda number saysflooded in its raysshare it seesrays with canal behind the wallhidden cells, meanmost hidden by one dry cell
8×83.845.2872.8%9.51.736
12×125.067.8364.7%25.52.3410

The last column is the one to look at: on a 12×12 board a single dry cell hides a run of 10 flooded cells from a number that is staring straight at it.

Count the sightlines twice

Every flooded cell is seen from at most one number per direction, so the pairs (number, flooded cell it sees) can be counted two ways: down the numbers it is the clue sum, across the cells it is at most four each. That is a floor on the size of the canal that costs no search at all, and the 2×2 rule is the ceiling — the largest 2×2-free subset of an h×w grid is hw − ⌊h/2⌋⌊w/2⌋, take every other row whole and every other cell of the rows between.

⌈Σ clues / 4⌉ ≤ canal ≤ hw − ⌊h/2⌋⌊w/2⌋

boardfloor from the cluesactual canalceiling from 2×2clue sum ÷ canal
8×81132.1481.37
12×122872.41081.51

The sandwich is loose, and that is the interesting part. It would be tight if every flooded cell were seen from all four sides; measured, a flooded cell is seen 1.37 times at 8×8 and 1.51 times at 12×12. Splitting the missing sightlines says why — every (flooded cell, direction) pair is exactly one of three things.

board(cell, direction) pairsseenno number that waya dry cell in betweenblocked
8×84,6161,5762,45158912.8%
12×1210,4323,9334,3512,14820.6%

The second column is exactly four times the canal and the third is exactly the clue sum — the same identity, arrived at from the other side, and npm test checks it board by board. Occlusion alone accounts for 20.6% of all sightlines at 12×12, and it grows with the board.

boardseen by nobodyby oneby twoby threeby fourflooded cells
8×8966063876411,154
12×121031,317961214132,608

A ray is not 2m cells, it is m + 1 states

Whatever the answer turns out to be, a ray out of a number reads the same shape: a flooded cells, then a dry cell, then anything at all. A direction of length m therefore has m + 1 states rather than 2m, and a number's whole cross is one bounded composition of its value into four arms. That is the only thing the solver ever branches on.

boardnumberscells in a number's rays2cellscompositions that fit
8×811.48.94788.4
12×1221.6138,19217.9

Which is why the complete solver is cheap: the median shipped 12×12 board is finished in 7 search nodes and the worst in 319, at 22.2 ms a board.

The canal is allowed to trap a lake

Nothing in Canal View says the dry cells have to join up, and they almost never do: a shipped 12×12 board walls off 12.1 dry regions from the outside on average, and 36 of 36 boards have at least one.

boardcanalof the gridlakesboards with a lakeindependent loopsboards with a loop
8×832.150.1%3.536/362.135/36
12×1272.450.3%12.136/366.836/36

A canal with a lake in it is a canal with a cycle, and "no 2×2" is exactly what makes a cycle possible without making it thick. The smallest shape that is 2×2-free without being a tree is the eight-cell ring — and at eight cells it is the only one. Counting fixed polyominoes both ways shows where the two ideas part company.

cellsfixed polyominoesno 2×2 blocktree-like2×2-free with a cycle
11110
22220
36660
41918180
56355550
62161741740
77605705700
82,7251,9091,9081
99,9106,4856,47312
1036,44622,28222,20280

Columns two and four are published sequences — A001168 and A066158 — and npm run ledger refuses to write its output if the enumerator disagrees with either. Column three is what a canal actually has to be, and it is in neither.

For scale, every canal that fits in a small grid, counted once by testing all 2hw subsets and once by growing sets outwards from an anchor. The two counts have to match.

gridconnected setsalso 2×2-freeshare
2×2131292.3%
2×3403382.5%
3×321813963.8%
3×41,12654448.3%
3×55,7262,08036.3%
4×411,5063,75532.6%
4×5116,16625,82222.2%

What holds a finished board still

Take a shipped answer and flip one cell. All 6,301 single-cell flips across the bank are illegal — but which rule catches them is not what the board looks like it is about.

ruleflips it killsflips only it kills
a number5,2982,974
the 2×2 rule932197
the canal joining up2,395806
nothing at all0

15.9% of the flips are caught by the 2×2 rule or by connectivity and by nothing else. Drop either rule and that many single-cell edits of the answer become legal on the spot — which is exactly what the misreading table below measures.

The ladder

Four rungs over the same compositions. The first pair of numbers is the share of cells the rung can name on its own, the second is the boards it finishes outright.

rungcells, 8×8cells, 12×12boards, 8×8boards, 12×12
arm54.6%41.9%0/360/36
block63.7%53.9%0/360/36
flow81.5%67.5%18/366/36
search100%100%36/3636/36

The dial is how many numbers are left

Number every dry cell and the board says its own answer out loud. Rub numbers out at random from there and ask whether the answer is still alone.

numbers kept, 8×8drawnuniquerate
every dry cell108108100.0%
261088376.9%
221085450.0%
181082119.4%
1510865.6%
1210800.0%
1010800.0%
810800.0%
numbers kept, 12×12drawnuniquerate
every dry cell108108100.0%
561086156.5%
4410876.5%
3610843.7%
3010800.0%
2610800.0%
2210800.0%
1810800.0%

The boards shipped here carry 11.4 numbers at 8×8 and 21.6 at 12×12. Rubbing out at random down to 12 numbers on an 8×8 gave 0 unique boards in 108 draws, and down to 22 on a 12×12, 0 in 108. Every number still on a shipped board is one whose removal was tried and refused.

And look at the top row of each table. Numbering every dry cell is not quite a guarantee: over 200 freshly drawn 8×8 canals, 3 still had a second answer, and in 3 of those 3 the cells that moved were exactly the ones no number was looking at. You can write the whole answer down and still not have said it.

Boards do not happen by accident

Numbers scattered at random, with values drawn either from the small range real boards use or from the whole range their rays allow:

boardnumbersvaluesdrawnno answerone answermore
8×811small20019307
8×821small20020000
8×811whole range20019802
8×821whole range20020000
12×1217small200126074
12×1231small20020000
12×1217whole range20020000
12×1231whole range20020000

Not one unique board in 1,600 draws. The interesting column is "no answer": unlike a puzzle drawn around an answer, a random board usually cannot be solved at all, because the counts it demands and the canal that would have to carry them do not fit together.

Four ways to misread it, and what each one does

misreadingboardboardsintended answer still legalanswers, medianuniquenone
the 2×2 rule dropped8×82424/243220
12×122424/24≥2,00000
the canal allowed to break up8×82424/241,24800
12×122424/24≥2,00000
the dry cells required to join up too8×8240/240024
12×12240/240024
the number read as its whole row and column8×8120/120011
12×12120/120012

The two halves of that table fail in opposite directions. Dropping a rule keeps the intended answer legal and buries it under hundreds of others, so nothing looks wrong until you notice that a second answer exists. Adding a rule that is not there — or reading the number as its whole row and column — makes the intended answer illegal: the board is empty, and you can spend a long time looking for an answer that is no longer there.

Two engines

The compositions are the load-bearing idea here, so they are checked against an engine that has never heard of them: walk the cells in reading order, try flooded then dry, prune only on a 2×2 that has already closed and on a number whose count can no longer land, and check the finished grid against the rules directly. On the 30 6×6 boards small enough for it to finish — 1,939,359 nodes of brute force — the two agree 30 times with 0 disagreements, and they agree on the answer set, not only the count. The same check runs with the 2×2 rule dropped, where the answers multiply into the hundreds: 30 agreements, 0 disagreements, 1,126 answers.