Orcantus

Guide

Number Place(9×9数字配置)の解き方 — 中級編: naked/hidden singleで止まったら、1マスだけ仮に決めて矛盾を探す

初級編では、naked single(そのマスの行・列・ブロックにすでに入っている数字を除くと、残る候補がちょうど1個になるマス)だけで解ける9×9盤を扱いました。この中級編では、naked singleに加えてhidden single(ある行・列・ブロックの中で、その数字を置けるマスが1個しかない場合に確定するマス)を組み合わせても、一部のマスが2択のまま残ってしまう場面を扱います。実例はE.generate('scan-medium-49', 'medium')で生成した9×9盤面です(1回目の試行でこの条件を満たしました)。

Note

初級編と同じく、ここでの「中級」はこの記事シリーズの読み物としての順番です。Number Place本体には個々の盤面の解きやすさを判定する仕組みがなく、level: 'medium'という指定も、numberplace/engine.jsのlevelForBlanksが空きマス数だけで判定する簡易な区分です(空きマスの目標はeasy36・medium50・hard上限なし)。この記事の実例をlevel=mediumで生成したのは、後述する空きマス数の多さが実際に「naked/hidden singleだけでは解けない」場面を作りやすかったためであり、Number Place側の判定基準そのものではありません。

結論。naked single・hidden singleの繰り返しで絞り切れないマスが残ったら、そのうち1マスを仮に数字で決めて、同じ2つの技法を波及させる。波及の結果、ある行・列・ブロックのいずれかで、まだ埋まっていないマスの候補が0個(1〜9のどれも入れられない)になったら、その仮定は誤り。もう一方の候補が正解になる。 この記事の実例では、この「仮定→波及→矛盾の発見」が1マスで1回だけ必要でした。

まずnaked single・hidden singleで絞れるところまで絞る

初級編で扱ったnaked singleに加えて、この記事ではhidden singleという技法も使います。hidden singleとは、「ある行(または列、または3×3ブロック)の中で、まだ数字が入っていないマスのうち、特定の数字vを候補として持てるマスが1個しかない」場合、そのマスをvで確定する、という技法です。そのマス自身の候補が2個以上あっても、周りのマスがどれもvを候補に持てなければ、hidden singleとして確定できます。

出題時点の数字配置は次のとおりです(.は空欄、50マスが空き、levelForBlanks(50)は'medium'、閾値はeasy45以下・medium54以下)。

. . . | 9 7 . | 2 8 .
8 . . | 3 . 2 | . . 4
. 3 . | . . . | . 6 .
------+-------+------
9 . . | . . . | 3 . .
3 4 . | . . . | . . 2
7 1 . | 8 . 3 | 9 . 6
------+-------+------
. . . | 2 4 . | 6 . .
. 9 . | . . 1 | 5 . .
6 2 . | . . . | . 1 7

naked single・hidden singleを交互に繰り返し適用すると、81マス中21マスが次の順で確定します(nakedはnaked single、hidden-行/列/ブロックはどの単位で確定したhidden singleかを示します)。

naked      行8列1=4     naked      行9列4=5     hidden-行   行1列9=3
naked      行8列9=8     naked      行9列7=4     naked      行7列9=9
naked      行7列8=3     naked      行8列8=2     hidden-列   行2列8=9
hidden-列   行3列1=2     hidden-行   行3列3=9     hidden-列   行1列3=4
hidden-行   行1列1=1     naked      行7列1=5     hidden-行   行3列7=7
naked      行2列7=1     naked      行3列9=5     naked      行4列9=1
naked      行5列7=8     hidden-行   行6列8=4     hidden-行   行7列3=1

内訳はnaked singleが12マス、hidden singleが9マスです。この時点(21手目)の盤面は次のとおりです。

1 . 4 | 9 7 . | 2 8 3
8 . . | 3 . 2 | 1 9 4
2 3 9 | . . . | 7 6 5
------+-------+------
9 . . | . . . | 3 . 1
3 4 . | . . . | 8 . 2
7 1 . | 8 . 3 | 9 4 6
------+-------+------
5 . 1 | 2 4 . | 6 3 9
4 9 . | . . 1 | 5 2 8
6 2 . | 5 . . | 4 1 7

残る29マスは、naked single・hidden singleのどちらを繰り返しても、これ以上確定しません(実際にNode.js上でさらに数巡試しましたが、状態は変化しませんでした)。これがnaked/hidden singleだけでは解けない局面です。

1マスを仮に数字で決めて波及させる

未確定の29マスの中から、行1列2に注目します。このマスの候補は、行1にすでに入っている数字(1,4,9,7,2,8,3、7個)を除いた{5,6}のうち、列2にすでに入っている数字(3,4,1,9,2)にも、このマスが属する3×3ブロック(行1〜3・列1〜3)にすでに入っている数字(1,4,8,2,3,9)にも5・6のどちらも含まれないため、候補は{5,6}の2択です(全81マスの中で最も候補が少ないマスの1つです)。

この2択のうち、「行1列2 = 5」と仮に決めて、naked single・hidden singleを波及させます。

  1. 仮定: 行1列2 = 5
  2. naked single: 行1列6 = 6 / 行2列5 = 5 / 行6列5 = 2 / 行4列5 = 6 / 行6列3 = 5 / 行8列5 = 3 / 行4列2 = 8 / 行4列3 = 2 / 行5列3 = 6 / 行7列2 = 7 / 行7列6 = 8(この順で11マスがnaked singleとして次々に確定します)
  3. この時点で行8列3を見ると、行8にすでに入っている数字は4,9,3,1,5,2,8(7個)で、残りは{6,7}のはずです。しかし、**このマスが属する3×3ブロック(行7〜9・列1〜3)にはすでに1,7,5,4,9,6,2**が入っており、ブロックの残りは{3,8}しかありません。行が要求する{6,7}と、ブロックが許す{3,8}には共通の数字がなく、候補が0個になります。

行・列・ブロックのどの単位で見ても、あるマスに入れられる数字が1つもない状態は、Number Placeのルール(各行・各列・各ブロックに1〜9が1回ずつ)そのものと矛盾します。したがって、手順1の仮定(行1列2 = 5)は誤りで、正しくは「行1列2 = 6」です。

仮定をひっくり返すと、残り全部がnaked singleだけで決まる

「行1列2 = 6」で確定し直したうえで、naked single・hidden singleを再び波及させると、今度は矛盾なく残り28マスすべてがnaked singleだけで確定します(hidden singleは1回も必要ありませんでした)。完成形は次のとおりです。

1 6 4 | 9 7 5 | 2 8 3
8 7 5 | 3 6 2 | 1 9 4
2 3 9 | 1 8 4 | 7 6 5
------+-------+------
9 5 8 | 4 2 6 | 3 7 1
3 4 6 | 7 1 9 | 8 5 2
7 1 2 | 8 5 3 | 9 4 6
------+-------+------
5 8 1 | 2 4 7 | 6 3 9
4 9 7 | 6 3 1 | 5 2 8
6 2 3 | 5 9 8 | 4 1 7

この完成形は各行・各列・各3×3ブロックに1〜9が過不足なく1回ずつ現れ、E.generateが実際に持っていた完成盤(answer)と1マスの違いもなく一致します(実行して確認済み)。

なぜnaked/hidden singleの繰り返しだけでは見抜けないのか

naked single・hidden singleは、どちらも「その1マス」または「その1つの行・列・ブロック」だけを見て判定します。行1列2を仮に5と決めても、決めた瞬間にはどの行・列・ブロックとも矛盾しません(だからこそ、この2つの技法だけでは81マス中50マスまでしか進めませんでした)。矛盾が表面化するのは、その仮定から11マス先まで波及させて、行8のnaked singleの積み重ねと、行8列3が属するブロックの情報が突き合わさったときです。この記事の実例では、行1列2から始まった連鎖が11マス分の確定を経て初めて、行とブロックの食い違いが判明しました。

手順のまとめ

  1. naked single・hidden singleで絞れるところまで絞る(この実例では81マス中21マス)。
  2. 残ったマスの中から候補が最も少ないマス(この実例では候補2個)を選び、仮に一方の数字で決める。
  3. 同じ2つの技法(naked single・hidden single)を波及させる。
  4. 波及の途中で、ある行・列・ブロックのいずれかで、まだ埋まっていないマスの候補が0個になる場合、その仮定は誤り。もう一方の数字に決め直して手順3をやり直す。
  5. 矛盾が起きなければ、そのまま波及させて残りを埋める。

誤りやすい判断

読者の検証方法

この記事が確認していないこと

この結果が言っていないこと

  • 検証はnumberplace/engine.js・numberplace/app.js(エンジンv1、2026-09-29時点)を対象にしています。将来の版で表示・判定基準が変わる可能性があります。
  • この記事の解法手順(naked/hidden singleの波及、仮定と矛盾の検出)はnumberplace/engine.jsに実装された機能ではなく、この記事のために独立に実装し、生成済みの盤面に対して実行して検証したものです。手動でのnaked/hidden singleの適用順は、この記事のために実装したスクリプトが盤面を行優先で走査した順であり、numberplace/engine.jsのバックトラッキング探索(MRVでマスを選ぶ)とは選び方が異なります。