code wiki / _hdl_build / nx_sudoku.nx
nx_sudoku.nx
buildroot/runtime/_hdl_build/nx_sudoku.nx
about
nx_sudoku.nx -- the FILE SURFACE for sudoku: proven-unique puzzle banks in the estate's own format.
THIS FILE HOLDS NO ALGORITHM. Rules, solver, solution counter and carver live in nx_sudoku_core.nx
and are shared with nx_sudoku_wasm (the playable module). An earlier version of this file carried its
own sd_ok/sd_fill/sd_count/sd_carve, which meant TWO implementations of one ruleset in the estate --
the duplicate-ruler defect. The extraction was only half the fix; deleting this copy is the rest.
Verified by re-banking seed 1101 and comparing bytes: a refactor that reproduces the banked artifact
exactly has provably changed no behaviour.
NATIVE BANK FORMAT. The bank is a sovereign nx_gamesave state file, NOT a TSV. TSV has no header, no
version, no checksum and no atomicity: a torn write or a flipped byte reads back as a plausible
puzzle. gs_save gives the estate's guarantees for free -- 48-byte versioned header, rolling checksum
with CORRUPTION REFUSED LOUD, a future format REFUSED rather than misparsed, atomic tmp+fsync+rename,
and additive .prev banking (rule 13).
layout: 162 i64 per puzzle -- [0..80] the puzzle digits, [81..161] its solution.
UNIQUENESS IS COUNTED, NEVER ASSUMED: a clue is removed only while exactly one solution survives, and
every row is re-counted before it reaches the file. The clue floor is 17 -- McGuire, Tugemann &
Civario (2012) proved no 16-clue sudoku has a unique solution, so fewer is CLAMPED, not honoured.
usage: nx_sudoku --kat self-test -> VERDICT=GREEN/RED, exit carries it
nx_sudoku bank <count> <clues> <seed> <out.sav> the native, checksummed bank
nx_sudoku jsbank <in.sav> <out.js> derive the page fragment FROM that bank
nx_sudoku gen <count> <clues> <seed> text emit, for eyeballing a grid
exit : 0 ok | 1 RED/refused | 2 usage
license_tier: ORIGINAL expect_exit: 0
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_gamesave.nxnx_sudoku_core.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 30 | const SD_MAGIC_12345: i64 = 12345 |
| 31 | const SD_MAGIC_4242: i64 = 4242 |
| 33 | const SD_SCHEMA: i64 = 5211 // sudoku bank v1 schema id, checked on load |
| 34 | const SD_CELLS: i64 = 162 // 81 puzzle + 81 solution |
functions
| 37 | func sd_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } |
| 38 | func sd_pn(v: i64) -> i64 |
| 48 | func sd_cat(dst: *u8, off: i64, s: *u8) -> i64 called by 1: main |
| 53 | func sd_atoi(s: *u8) -> i64 called by 1: main |
| 66 | func sd_fill_bank(cells: *i64, cnt: i64, clu: i64, seed: i64) -> i64 |
| 97 | func sd_selftest() -> i64 |
| 196 | func sd_emit_row(p: *i64, s: *i64) -> i64 |
| 209 | func main(argc: i64, argv: *i64) -> i64 |