クリーク (Creek) を、5 つのルールセット内蔵でブラウザに実装した。数字はマスの中ではなく格子の「角」に乗っていて、その角に接する(最大 4 つの)マスのうち何個が黒かを表す。黒くないマスは全部つながって 1 本の小川 (creek) をなす。ソルバー内蔵パズル第 48 弾。
デモ: https://sen.ltd/portfolio/creek/
リポジトリ: https://github.com/sen-ltd/creek
このパズルには閉じた式がある
紙の角にある数字は、接するマスがちょうど 1 個しかない。つまりその 1 マスを名指ししている。辺の上の数字は 2 マス、内部の数字は 4 マスを見る。角 (i,j) の数字を C(i,j)、マスを x[r][c] とすると
C(i,j) = x[i−1][j−1] + x[i−1][j] + x[i][j−1] + x[i][j] (盤外の項は落とす)
で、これは盤面の混合 2 階差分そのものだから、包除原理で逆に解ける:
x[r][c] = Σ_{i≤r, j≤c} (−1)^((r−i)+(c−j)) · C(i,j)
**答えは数字の「市松符号付き累和」**である。リポジトリの solveByScan はこの式を 6 行で書いただけのものだ。
全部の角に数字が書いてある盤面を 6×6 / 8×8 / 10×10 で各 600 枚測ると、閉じた式が答えを再現する率 100%、解が一意な率 100%、そしてラダー最弱の count(1 つの角を数えるだけ)だけで完答する率も 100%。理由は単純で、「未確定 1 マスの角を数える」を繰り返すことがこの三角スキャンそのものだから。
つまり全開示のクリークには問題が無い。クリークの難しさは 100% 「作者がどの数字を消したか」に宿る。
| 8×8 で残した数字(81 個中) | 一意 |
count で完答 |
ラダー全部で完答 |
|---|---|---|---|
| 81 (100%) | 100.0% | 100.0% | 100.0% |
| 73 (90%) | 99.2% | 98.5% | 99.2% |
| 65 (80%) | 89.0% | 82.7% | 89.0% |
| 57 (70%) | 56.5% | 42.3% | 56.5% |
| 49 (60%) | 19.5% | 10.0% | 19.5% |
| 41 (50%) | 2.3% | 0.5% | 2.3% |
紙の縁の数字は、捨ててよい数字
角の数字は盤上で最強だ。何も推論せずにマス 1 個を名指しする。ところがそれが捨てるべき数字でもある。
答えを 1 枚とって、(a) 外周リングの角を全部消す、(b) 同じ個数だけ内部の角をランダムに消す、を比べた:
| 盤面 | 外周リングを消す | 同数を内部から消す |
|---|---|---|
| 6×6(24 個) | 一意 92.5% / 自由度 11.00 | 一意 0.0% / 自由度 15.00 |
| 8×8(32 個) | 一意 97.2% / 自由度 15.00 | 一意 0.0% / 自由度 19.00 |
| 10×10(40 個) | 一意 99.7% / 自由度 19.00 | 一意 1.0% / 自由度 23.03 |
消した式の本数は同じ。しかも線形代数的な自由度はほとんど変わらない(100 変数中、たった 4 次元の差)。それで一意率は ~100% と ~0% に割れる。
崩壊の原因は核(kernel)の大きさではなく、核の「形」だ。
核は巨大で、そしてほぼ全部が非合法
外周リングを消すと、残るのは本物の 2×2 窓だけになる。2 つの盤面が全 2×2 和で一致するなら、その差 d の市松ひねり e[i][j] = (−1)^(i+j) d[i][j] は混合 2 階差分が消える。よって
e[i][j] = u_i + v_j
核の次元はちょうど w+h−1(8 種類の盤形で行簡約と突き合わせて確認済み)。
ここで d ∈ {−1,0,+1}(両方 0/1 行列だから)を課すと、カタログは 3 形しか残らない:
- row — 1 行まるごとを市松交互に反転
- col — 1 列まるごと、同上
- cross — 行 r と列 c を逆符号で同時に、交点だけ据え置き
外周を消したクリークに「小さな曖昧さ」は存在しない。いちばん安い第 2 解でも 1 行まるごと動かす必要がある。だから:
| 盤面 | 核の次元 | ±1 の符号パターン数 | まだ一意 | 合法な flip がある |
|---|---|---|---|---|
| 6×6 | 11 | 2,048 | 93.2% | 6.5%(row 23 / col 15 / cross 1) |
| 8×8 | 15 | 32,768 | 98.2% | 1.8%(row 5 / col 6 / cross 0) |
| 10×10 | 19 | 524,288 | 100.0% | 0.0% |
findFlipCertificate はこのカタログを走査するだけで、探索を一切しない。外周消し盤の曖昧さを 98.1%(6×6・非一意 107 枚)と 100%(8×8・30 枚)説明し、一意盤での誤検出は 0。一方ランダムに消した盤では 0.3% と 0.1% しか説明できない——内部の窓も欠けていて定理の前提が壊れているからだ。証明書は証明が効く範囲でだけ効き、測定がそれを言っている。
ルールラダー
| 段 | 読むもの |
|---|---|
count |
角 1 個。4 マス以下の個数制約で、そのスコープでは既に GAC |
linear |
手がかり系全体をビルド時に 1 回だけ行簡約し、簡約後の行で区間伝播 |
pair |
隣り合う角 2 つはドミノを共有する。合併した 6 マス以下を厳密列挙 |
connect |
小川は 1 本。死んだ連結成分は黒、切断点は白 |
probe |
色を仮定してサブラダーを回し、爆発したら捨てる |
ablation: 動くのは非線形の 1 段だけ
full ラダーから 1 段抜いて fixpoint をビット単位で比較(各サイズ 120 盤):
| 抜いた段 | fixpoint が動いた盤 | 完答した盤 | probe の仮定回数 |
|---|---|---|---|
−count
|
0/120, 0/120, 1/120 | 61→61, 29→29, 7→7 | +0.8%, +6.2%, +3.9% |
−linear
|
0/120, 0/120, 0/120 | 61→61, 29→29, 7→7 | +0.0%, +0.4%, +2.6% |
−pair
|
0/120, 0/120, 0/120 | 61→61, 29→29, 7→7 | +7.2%, +5.8%, +9.2% |
−connect
|
37/120, 52/120, 64/120 | 61→42, 29→16, 7→5 | +16.8%, +8.4%, −6.4% |
(6×6 / 8×8 / 10×10)線形な 3 段は互いに冗長で、どれを抜いても残り 2 段が fixpoint をビット単位で復元する。ただし無料ではない: pair を抜くと prober の仮定が 6〜9%、count を抜くと 1〜6% 増える。答えを動かすのは、ラダー中で唯一線形代数でない connect だけ。
増分ラダーは例によって逆を向く: 6×6 で count 34.2% → linear 35.0% → pair 35.0% → connect 45.0% → probe 50.8%。増分だけ読めば全段必須、ablation だけ読めば 3 段は飾り。両方出す。
比較不能な 2 段が、同じゴールに着く
linear は盤面全体を有理数上で考える。pair は 6 マスしか見ないが、そのマスが整数だと知っている。どちらも他方を含まない。ランダム 9,000 盤で:
-
linearが消せてpairが消せないビット: 756 -
pairが消せてlinearが消せないビット: 1,947 - 両者の fixpoint が違った盤: 742
- 片方だけが完答した盤: 0(両方向とも)
それでもバンクには pair 級の盤がある。盤を局所最小まで間引くと、盤はちょうど 2 段が分岐するフロンティアに載るからで、その確率は 1.7%。null result は「ルールについての主張」ではなく「どこをサンプルしたかについての主張」だった。
答え側のダイヤル
黒率。 細い小川は易しく、太い小川は難しい(8×8・数字を 60% ランダムに残す):
| 黒率 | 一意 | 敵対的な最小数字数 |
|---|---|---|
| 20% | 8.7% | 32 / 81 |
| 40% | 13.3% | 29 / 81 |
| 60% | 24.7% | 22 / 81 |
| 70% | 42.7% | 18 / 81 |
小川の形。 面積を固定し、汀線(境界の長さ)だけを変える(白の隣が少ないマスを優先して伸ばす):
| 成長 | 汀線(辺) | 0 の割合 | 4 の割合 | 一意 |
|---|---|---|---|---|
| 塊 (t=1) | 26.5 | 35.6% | 10.3% | 25.3% |
| t=2 | 40.4 | 25.1% | 6.6% | 16.7% |
| t=4 | 51.2 | 18.2% | 4.0% | 15.3% |
| 触手 (t=8) | 55.9 | 15.3% | 3.1% | 14.7% |
盤の大きさも白の面積も印刷する数字の個数も同じで、一意率が半分になる。仕組みはヒストグラムにある: 0 と 4 は単独で 4 マスを確定するが、くねった小川はそれをほとんど印刷しない。汀線を倍にすると、両極端が 1 に置き換わる。
敵対的なインクとランダムなインク。 局所最小まで間引いた盤が要求する数字は 6×6 / 8×8 / 10×10 で 16 / 29 / 43 個——格子の約 35% でサイズによらずほぼ一定。ランダム開示はその 2.0 倍を要求する。
生成器は行き詰まれない
クリークの答えは「白マスが連結な任意の塗り」なので、生成器は答えを探さずに作る: 1 マスから始めて、フロンティアのマスを 1 つずつ吸収する。白が盤全体になるまでフロンティアは空にならないから、棄却もリスタートも失敗も構造的に起こらない。
台帳は自作エンジン同士ではなく式と突き合わせる
-
1×m 盤 — 白は 1 区間なので
m(m+1)/2 + 1: 2, 4, 7, 11, 16, 22, 29, 37(全数列挙と完全一致) - 2×m 盤 — 列内 2 マスは隣接するので合法盤は「白の列が連なりを成し、隣り合う列が重なる」もの全体。転送行列で 4, 14, 41, 109, 276, 682, 1665, 4041, 9780, 23638(全数列挙と完全一致)、以降 57097, 137877, 332900, …
- n×n 盤 — 2, 14, 219, 11507
- 全開示写像の単射性 — 3×3 / 4×3 / 4×4 を全数で: 512→512, 4,096→4,096, 65,536→65,536。2 枚の盤が同じ数字列を印刷することは無い
-
核の次元 — 予測
w+h−1を 8 種類の盤形で行簡約と照合
エンジン突き合わせは、ルールも候補配列も行簡約も共有しない生エンジンとの解数一致 300 盤 × 5 レベルで 100%。
そしてラダー側の恒等式: 3 サイズ × 5 消去率のランダム 9,000 盤で、probe が完答する ⇔ 盤が一意が両方向とも例外 0。
バンクとテスト
出荷バンクは 75 盤(6×6 / 8×8 / 10×10 × 5 グレード)。グレードは「推測なしで完答できる最弱のルールセット」。全盤とも出荷前に探索エンジンで一意性を再証明済みで、probe 級以外の証明の分岐数は中央値 0。テストは 30 本。
TypeScript、ランタイム依存ゼロ。
デモ: https://sen.ltd/portfolio/creek/
リポジトリ: https://github.com/sen-ltd/creek
