Binairo (Takuzu, バイナリーパズル) with a line-dictionary solver inside. Fill the grid with black and white circles so that:
- no three equal circles sit consecutively in any row or column;
- every row and every column holds exactly half of each color;
- no two rows are identical, and no two columns are identical.
The solver never encodes the human trick catalog. Instead it enumerates — once per size — the dictionary of all n-bit words that are legal as one line: balanced and triple-free (14 words at n=6, 34 at 8, 84 at 10, 208 at 12). Each row and each column ranges over that dictionary; propagation keeps, per line, the candidate words that match its decided cells and projects: a cell on which every surviving word agrees is decided.
Every classic technique falls out as a shadow of that single projection —
- sandwich:
1 _ 1forces the middle0, because every candidate word says so; - pair:
1 1flanks itself with0s, same reason; - counting: a color at quota flips the rest of its line, same reason.
The no-duplicate rule becomes alldifferent over the dictionary: a word already spent by a finished parallel line is removed from every sibling's candidates — which is exactly the human "don't copy that finished row" move, and it catches duplicated lines as a plain domain wipe-out. Run to a fixpoint, the projection is as strong as enumerating each whole line. When it stalls, a search branches on the line with the fewest candidates left (after a fixpoint an undecided line always has at least two) and counts solutions, proving every bundled board has a single one.
Boards are authored answer-first: a full grid is built row-by-row out of the dictionary — keeping every column prefix legal, so column balance comes free — then givens are greedily deleted while uniqueness survives. Every remaining given is load-bearing (the test suite checks that dropping any one breaks uniqueness). TypeScript, no runtime dependencies.
Live demo: https://sen.ltd/portfolio/binairo/
npm install
npm run dev # local dev server
npm test # vitest: dictionary, projection = trick catalog, uniqueness proofs
npm run build # static site in dist/
npm run generate # re-generate the bundled boards| file | role |
|---|---|
src/binairo.ts |
pure engine: line dictionary, projection propagation, alldifferent, search |
src/puzzles.ts |
the six bundled boards (6×6 … 12×12) with their solutions |
src/main.ts |
SVG board UI: stone cycling, locked givens, live conflicts, hint, animated solve |
src/binairo.test.ts |
39 tests: dictionary vs brute force, each human trick as projection, boards |
tools/generate.mts |
answer-first board generator with greedy given deletion |
MIT
