無料ブログはココログ

数独の参考書

  • 古金谷博、藤尾聡子、鳥居隆司: プログラムを作ろう!Java入門
    数独プログラムを作り始めたころ、たまたま書店で見つけたJavaのプログラム入門書です。 帯には「数独の作問プログラムを作って遊ぼう!」と書いてある。内容はJavaの入門書だが、数独のGUI作り、重複数字の検出、複数解の検出プログラムなど、数独プログラムの入門書として参考になる。 発行:日経BPソフトプレス (★★★)
  • ダイソー: ナンプレの問題集
    ダイソーナンプレブックシリーズ11 私のレベルで鉛筆を使い、この本の問題を解くにはかなり苦労します。この本を参考に数独プログラムで問題の解き方を調べています。 (★★★)
  • ニコリ: 数独攻略ガイド
    数独の解法である「基本の手筋」が詳しく丁寧に説明されている。読み応えがあります。 (★★★)

2012年5月17日 (木)

複数解の検出プログラム

Blog0517
バックトラック法は、順次、空マスに数字を置いて、数独のルールを
満たすか確認する。ルールを満たせば、次の空マスに移り、
同じ要領で数字を置いていく。ルールを満たさなければ、数字を置いた
マスを空にして、1マス戻る。
盤面が唯一解の場合はその解を返す。複数の解がある場合、とりあえず
最初に見つけた解を戻り値として返す。
バックトラック法で解を見つけた場合、その解が唯一解であるかの
判断は若干の工夫がいる。
バックトラック法では最初の解を返すので、数字を入れる空マスの
順序を替えれば、別の答えを見つける可能性がある。このことを
利用して数独の複数解の検出を行う。

数字を入れる順の一例
(1) 盤面の左上の空マスから、右にむかって行順で数字を入れる。
(2) 盤面の右下の空マスから、左にむかって行順で数字を入れる。
(3) 盤面の左上の空マスから、下にむかって列順で数字を入れる。
(4) 盤面の右下の空マスから、上にむかって列順で数字を入れる。
(5) 左上のブロックからブロック単位で行順に数字を入れる。
(6) 右下のブロックからブロック単位で行順に数字を入れる。
このほかにも、いろいろな数字の入れ方が考えられる。

簡単な操作で複数解の検出ができるプログラムを下記のサイトに載せる。
game81のページ
NpValidLEプログラム

操作方法
(1) ラジオボタンで課題を選択する。Web版プログラムの組込みの
課題数は5個に制限している。
kadai1、kadai2 複数解の問題
kadai3~kadai5 唯一解の問題
(2) Check Validボタンを押す。
 この時の盤面をAとする。
(3) もう一回、Check Validボタンを押す。
 この時の盤面をBとする。
盤面A、あるいは盤面Bで青い数字のマスと空マスがある場合、
複数解の問題と判断する。
(4) もう一回、Check Validボタンを押す。
 これは(2)と同じ盤面になる。
(5) とりあえず、1つの解を知りたい場合は、Check Boxボタンを押す。
 盤面Cとする。

解説
盤面Aは盤面の左上の空マスから、右にむかって行順で数字を入れて
解いた答えと、盤面の右下の空マスから、左にむかって行順で数字を
入れて解いた答えの共通部分を表示している。
盤面Bは盤面の左上の空マスから、右にむかって行順で数字を入れて
解いた答えと、数字を1から9ではなく、9から1へと入れて解いた
答えの共通部分を表示している。
盤面Cは左上のブロックからブロック単位で解いた場合の答えを
表示している。盤面Cは差分を取っておらず、解があれば、すべての
マスが数字で埋まっている。

追加の説明
画面上の白い枠はテキストフィールド欄。ここにA形式の1行文字列を
入力すれば、任意の問題で複数解の確認を試すことができる。
A形式の1行文字列の一例
A807m5 609k830 5k6h20 4h5h20 28k 809k70 403k2 29m104 5h906h

画面下側のステータス行
status(22) A 345678/567 res=5
数字22 ヒント数(表出数字の個数)
A 盤面
345678/567 バックトラック法で試しに置いた数字の回数の1回目/2回目
バックトラック法で試しに数字を置く回数の上限を設けており、回数が
100万回を超える場合は、試しを終了する仕様にしている。

このプログラムはアルゴリズムの点で複数解の問題であるにも
かかわらず、複数解と検出できない見逃しエラーがあるので
注意する。また、アルゴリズムから唯一解の問題を複数解とする
誤判定はないと考えている。

2012年4月28日 (土)

複数解とバックトラック法

Blog0427

上の図の問題を、数独プログラムgame81LEで解こうとすると、
解が見つからず、問題を解けない。
3枠4マス目に数字3を仮置きすると、すべての空マスを埋める
ことができる。数字8を仮置きしても残りの空マスを埋められる。
複数解の問題なのでgame81LEでは解けない。複数解を検出する
アルゴリズムがあれば、game81LEで複数解ありと表示できる。

バックトラック法を使うと、複数解ありの問題を解くことができる。
上の問題をバックトラック法で考える。3枠4マス目に置ける数字を
1から9まで順に考える。最初に数字3が置ける。この数字が置ければ
以下は簡単に問題を解くことができる。
次に置ける数字の順序を9から1までにする。最初に数字8が
置ける。以下は簡単に問題を解ける。複数解の2番目の解になる。
2つの解の差分を取れば、複数解のマス位置を確認できる。

Blog0427_3
上の図も複数解の問題です。
問題を簡単にするため、2、5、7、8の4つの枠を抜き書きする。

Blog0427_2
4通りの解のパターンがある。
この問題で先のアルゴリズムを試すと、複数解の検出ができなかった。
数字を置く順番ではなく、数字を置くマスの順序を後ろからにすると
複数解の検出ができた。

バックトラック法を使い、仮置きする数字の順序、あるいはマスの順序を
入れ替えて複数解を検出する方法では、まだ検出見逃しエラーがある。
さらなる工夫が必要と考えている。

複数解判定の別な方法として、盤面の特徴抽出法を考えている。
先の問題では、盤面の空マスの数が6個、残り数字の種類が3種類、
残り数字使用頻度がそれぞれ2個という特徴がある。
複数解固有の盤面の特徴から判定する。

ここでのバックトラック法のプログラムは、矢吹太朗氏(青山学院大学)の
C言語版を参考に作成しました。キーワード(sudoku inquisitor)

バックトラック法
コンピュータで数学的な問題の解を探索するアルゴリズムの一種で、
もっともポピュラーなものの一つ。
ある解を求めるときに、可能性のある手順を順に試していき、
その手順では解が求められないと判明した時点で一つ前の状態に
戻って別の手順を試す、という方法。 (IT用語辞典 e-Words)

2012年4月21日 (土)

無効な盤面のチェック

Blog0421
上の図で5枠(中央のブロック)の真中のマス(緑色)に
数字5以外を入れると、無効な盤面になる。
たとえば、数字1を入れれば同じ枠内で数字1が重複する。
数字2を入れれば、5行目で数字2が重複する。
いずれの場合も数字が重複することにより、無効な盤面となる。

6枠(中段右のブロック)の6マス目に数字4を入れると、
無効な盤面になる。この数字を入れたことにより、5枠で
数字4を入れる空マスが無くなる。
8枠8マス目では数字2あるいは8を入れると、5枠でこれらの
数字を入れることができず、無効な盤面になる。

NpEngineクラスのnextStepメソッドの動作
(1) 候補数字(マップ)のリスト作成
(2) 無効な盤面のチェック、枠、行、列に重複数字があれば終了
(3) 隠れ数字による候補数字リストの前加工
(4) 枠に着目した解法で解く。解があれば(8)へ
 無効な盤面のチェック、枠内に9通りの数字が置けない場合は終了
(5) 行、列に着目した解法で解く。解があれば(8)へ
・・ 以下省略

nextStepメソッドは2カ所で無効な盤面のチェックを行っている。
無効であれば、エラーコードを返す。
2つの無効な盤面チェックルーチンは、すべての無効な盤面を
検出していない。2つのチェックルーチンをパスしたから
有効な盤面とは言えない。チェック見逃しエラーがある。

見逃しエラーの無い無効な盤面チェックルーチンあると、
有効な盤面の確認ルーチンができ、次の手順で
数独の問題を解くことができる。

for( int p = 0; p < 81; p++ ) {
  for( int d = 1; d <=9; d++ ) {
    // マス位置pが空マスならば
    if( isKaraMasu(board,p) {
    // マス位置pに数字dを置く
      putKoma(board,p,d);
      // 盤面が有効であれば、次の空マスに進む
      if( isValid(board) break;
    }
  }
}

見逃しエラーの無い無効な盤面チェックルーチンの作成は
数独の問題を解くことと同じ意味になる。

2012年4月13日 (金)

数独エンジンのツールプログラム

数独のある局面で次の1手を探すプログラムをナンプレエンジン
(NPE)、あるいは数独エンジンと呼んでいる。
数独プログラムgame81LEでこのプログラムを使用している。

現在のNPEは次の解法を実装している。
NpEngineクラスのnextStepメソッドの戻り値と解法
1   - 枠に着目した解法
2、3 - 行、列に着目した解法
4   - マスに着目した解法

NPEの解法はこの3種類で、候補数字リストの前加工として、隠れ数字を
採用している。

次のプログラム開発として、予約の処理追加など、NPEのさらなる
性能アップを考えているが、数独プログラム上でのNPEへの機能追加は
プログラム作成、検証の手間が煩雑で、プログラム作業の効率が
良くないと感じている。
このため、NPEプログラムの作成、検証用に使えるツールプログラム
NpeToolkitLEを準備した。Javaアプレットを組込みの課題数5個として
下記のHPにアップロードした。

game81のホームページ

toolkit - goo辞書検索で、工具セットの意味。

ツールプログラムの使い方
画面上部のテキストフィールドに、盤面の数字配置を表す
A形式の1行文字列を入力する。
ラジオボタンでNPEの機能Engine Typeを選択する。
showボタンを押す。結果が盤面とステータス行に表示される。

問題の入力はテキストフィールドとは別に、コンボボックスと
ラジオボタンを使い、プログラムに組み込みの問題をロードすることが
できる。A形式の文字列を入力するより、簡単に問題を設定できる。

結果の見方

Blog0412_a2_3
画面の左側が盤面、右側が手順の一覧、30手分を表示する。
424 774 R821 C971 R832 ..
29コマ目 424 - 4枠2マス目に数字4
30コマ目 774 - 7枠7マス目に数字4
31コマ目 R821 - 行に着目した解法、8枠2マス目に数字1
32コマ目 C971 - 列に着目した解法、9枠7マス目に数字1
33コマ目 R832 - 行に着目した解法、8枠3マス目に数字2

Blog0412_2a_4
上の図はNPEの機能、隠れ数字の効果を評価している。
左図Engine Type 1 = 1 隠れ数字の前加工なし
右図Engine Type 1 = 2 隠れ数字の前加工あり
隠れ数字の前加工機能を採用することで、枠に着目した解法で
解ける手番が増えていることが分かる。

参考資料
nextStepメソッドの動作
(1) 候補数字(マップ)のリスト作成
(2) 無効な盤面のチェック、枠、行、列に重複数字があれば終了
(3) 隠れ数字による候補数字リストの前加工
(4) 枠に着目した解法で解く。解があれば(8)へ
 無効な盤面のチェック、枠内に9通りの数字が置けない場合は終了
(5) 行、列に着目した解法で解く。解があれば(8)へ
(6) マスに着目した解法で解く。解があれば(8)へ
(7) 解が見つからなければ、終了
(8) 複数の解(次の手)が見つかった場合は、優先数字を参考に
 解を1つ返す。

無効な盤面の確認は、重複数字があるかと、枠内に9通りの数字が
置けるかの2つの条件で行っている。

2012年4月 5日 (木)

数独課題の難易度表示

数独の問題を解いていると、難しいと分類されている問題が
簡単に解けてしまうことがある。
難しいと構えて問題を解いていたのに期待はずれを感じる。
数独の難易度を定量的に評価する方法について考える。

ここではある局面の難易度は、その局面の解法に依存すると前提する。
そして課題としての難易度は、課題の初手から最終手までの各局面の
難易度の合計とする。
数独エンジンNPEは1手ごと、解法結果を返す。初手から
最終手までの解法のリストを作り、解法ごとに難易度のポイントを与え、
そのポイントの合計を課題の難易度とする。

解法別の難易度ポイントの一例
枠に着目した解法は難易度ポイントを2ポイントとする。
ただし、盤面のコマ数が51個以上の場合は、空コマ数が少なくなるので
1ポイントとする。
行、列に着目した解法は5ポイントとする。
マスに着目した解法は10ポイントとする。
数独の終盤は空マス数が少なくなり、ほとんどの局面は枠に着目した
解法で解くことができる。行、列、マスに着目した解法は、盤面の
コマ数に関係なく一定値とした。

難易度を数式で表す。

Blog0405_1Nsは初手のときの盤面のコマ数
関数kaihoCode(k)はkコマ目の解法コードを返す関数
関数g(kaiho,k)は、解法コードと盤面上のコマ数に応じて
難易度のポイント数を返す関数。

この数式でしばらく難易度評価を試してみた。
結論から言うと、この評価式はあまり役には立たなかった。
評価式には数独エンジンNPEで解けない難しい問題は評価できない、
易しい問題は初手の盤面のコマ数で値が決まるなど、問題点がある。
数独の作家はこのような評価を好むとは思われない。
また、ユーザにとっては理解できない数字は意味がない。

Blog0405_2メニュー View - show Next Stepで表示する画面の下側
Status(24) 1 11111 11111 11111 .. 11111 OK! /11111..1/ d= 100, f=0

ステータス行の読み方
 Status(24) 括弧内の数字は盤面のコマ数、今回は24個
 1 11111 11111 11111 .. 11111
  初手から70マス目までの1手ごとの解法コード
  71マス目から80マス目の解法コードは省略
  1 枠に着目した解法
  2 行、列に着目した解法
  3 マスに着目した解法
  OK!は81マスまで数字が入れられることを表す。
 /111111111111/ 5マス目ごとの解法コード集計
 d=103 難易度評価値
 f=0 各解法の出現頻度、今回は行、列、マスに着目した解法は使わない。
 f=25の場合、マスに着目した解法を2回、行、列に着目した解法を
 5回使ったことを表す。

2012年4月 3日 (火)

数独プログラムのアップデート(4月版)

Blog0403a
数独プログラムgame81LEをアップデートしました。

game81のホームページ

機能追加した項目
(1) メニューViewにshow Next Stepを追加

NpEngineクラスのnextStepメソッドを使うと、次の1手の解を
取得できる。show Next Step はnextStepメソッドを30回繰り返して、
30手分の解を求め、盤面と解いた手順を一覧表にして表示する。
30手の途中で解が見つからない場合は、そこまでを表示する。

上の図の見方
177 467 957 887 577 293 583 923 763 ・・

25コマある盤面での次の1手 → 177
3桁の数字177は1枠7マス目に数字7を置くことを表す。
26コマある盤面での次の1手 → 467
3桁の数字467は4枠6マス目に数字7を置くことを表す。

解法の種類により3桁の数字の前にR、C、Mの英字が1文字付く。

枠に着目した解法 ブランク
行に着目した解法 R
列に着目した解法 C
マスに着目した解法 M

show Next Step はある程度問題を解き進めた後、盤面の空マスが
残り30個程度になった場合、答え合わせするのに利用できる。
最後まで問題を解かなくても、show Next Stepを使い、
途中で答え合わせできる。

2012年3月27日 (火)

隠れ満点法

Blog0327
上の図はダイソーナンプレブックシリーズ11の課題18の途中図です。

1つの空マスに着目する。
数独のルールでそのマスに入れられる数字を1から9まで順に調べ、
入れられる数字が1つならば、その数字が解になる。

たとえば、上の図の8枠1マス目(7行4列目)のマスに着目する。
8枠内に数字2345がある。7行目に数字347がある。
4列目に数字1356がある。したがって、8枠1マス目には
数字1から7が入らないので候補数字は8、9の2つになる。

次に2枠に着目する。
3枠の数字9と、5枠の数字9から、2枠の4マス目、7マス目の
2つのマスのいずれかに数字9が入る。言い換えると、
2枠の4マス目、7マス目の2マスに数字9が隠れている。
この隠れ数字9を使い、8枠1マス目の数字8が確定する。

1つの空マスに着目した解法をこのブログでは満点法とする。
また、隠れ数字を利用した満点法は隠れ満点法とする。
数独プログラムgame81LEは、ヒントBのボタンを押すと、満点法で
解ける空マスの位置を薄い緑色でヒント表示する。しかしながら、
上の課題のように、隠れ数字がある満点法にはまだ対応していない。

この課題はさらにもう1回、隠れ満点法が使える盤面(局面)がある。
上の図で6枠の数字1、数字9が確定する。4枠の数字9が確定する。
4枠の上側の行に隠れ数字7がある。隠れ満点法で
5枠の数字8が確定する。

2012年3月 1日 (木)

次の1手と優先数字

数独のある盤面で次の1手を探すプログラムを
数独エンジンNPEとする。

NPEプログラムで必ず次の1手が求められれば、空マスの数だけ
このプログラムを繰り返すことにより、数独の問題を解くことが
できる。構想中のNPEプログラムの概要をまとめる。

NPEを用いて数独の解を求めるプログラム
int keyNum ← 優先数字
int[][] orgStage ← 盤面のコマ配置
NpEngine npe = new NpEngine(orgStage);
do {
  int kaiho = npe.nextStep(keyNum);
  int[] arrResult = npe.getArrResult(); // 1手の解答
  kaihoの値で場合分け
  int[][] kifuData 棋譜データに1手追加
  keyNum = 今回の解の数字
} while( 解が有効 )
終了時のコマ配置を取得
棋譜と盤面を表示する。

NpEngineクラス
フィールド
  int[][] stage  コマの配置
  int[] arrResult 
ゲッター
  getStage()  コマ配置の取得
  getArrResult() 結果の取得
コンストラクタ
  NpEngine(orgStage) コマ配置をstageに設定する。
メソッド
  nextStep(keyNum)
   解を1つ求め、結果配列に保存する。
   フィールドのstageを1手進める。
   戻り値は解法識別番号。

優先数字
紙と鉛筆で数独問題を解く場合、1つの数字に着目して
解くことが多い。たとえば、あるブロックの空マスに数字7が
入ることを見つけた場合、次に別のブロックで数字7が入る
空マスを探す。優先数字を使い、NPEでこの動作が実現できる
よう工夫している。

NPEのプロトタイプでの動作
次の盤面で優先数字の動作を確認する。
24個数字がある盤面から、NPEを使い30手分進める。

   ABC DEF GHI
1: -2- --7 3--
2: --- 8-- --7
3: --5 -1- -4-
4: -3- 9-- 7--
5: 1-- --- --3
6: --2 --4 -9-
7: -7- -8- 2--
8: 4-- --5 ---
9: --8 3-- -5-

(1)優先数字の動作を無効にした場合

Blog0301a

177 467 459 434 154 583 577 531 568 644
772 715 485 635 345 957 887 814 224 215
555 841 852 542 526 476 418 188 622 392

3桁の数字で1手を表す。百の位が枠番号、十の位がマス番号、
一の位がマスに入る数字を表す。
上のリストでは、
初手(25コマ目)1枠7マス目(3行1列目)に数字7、
2手目(26コマ目)4枠7マス目(5行3列目)に数字7が
入ることを表す。
空マスには、初手から7、7、9、4、4、3、7、1、8、4、・・と
順に数字が入る。

(2)優先数字の動作を利用した場合

Blog0301b
177 467 957 887 577 459 434 154 644 814
224 994 531 841 583 923 763 143 293 568
772 852 542 262 392 622 259 215 345 715

結果の評価
優先数字を利用した場合、利用しない場合と比較して、
空マスに入る数字が7、7、7、7、7、9、4、・・と同じ値が
連続するようになっている。紙と鉛筆で解く場合と近い
動作をしている。

2012年2月20日 (月)

数独エンジン

Blog0220a
数独のある局面で次の1手を探すプログラムをナンプレエンジン
(NPE)、あるいは数独エンジンとする。

数独エンジンNPEの動作
9×9×9の配列を用意する。添え字は9枠、9マス、9数字に
対応する。
boolean[][][] weight = new boolean[9][9][9];
各ブロックの各マスについて、枠内、行内、列内にどの数字が
あるかを調べる。

上の盤面、左上のブロック(1枠)、左上のマス(1マス目)では
枠内に数字2、5、行内に数字2、3、7、列内に数字1、4がある。
配列で表すと
weight[0][0][0]=true;  // 1枠1マス目の関連範囲に数字1があり
weight[0][0][1]=true;  // 1枠1マス目の関連範囲に数字2があり
weight[0][0][2]=true;
weight[0][0][3]=true;
weight[0][0][4]=true;
weight[0][0][5]=false;  // 1枠1マス目の関連範囲に数字6はない
weight[0][0][6]=true;
weight[0][0][7]=false;
weight[0][0][8]=false;

この配列に載らない数字が各マスに入力できる数字になる。
この数字を各マスの候補数字と呼ぶ。
上図の1枠1マス目の空マスでは、数字6、8、9が候補数字に
なる。この3つの数字のいずれかが1枠1マス目に入る。
メニューバーのView-Show Map2は、この候補数字のリストを
表示している。

候補数字の配列から、次の1手を求めるには、
ブロックに着目して、配列のブロック内で候補数字の出現頻度を
調べる。出現頻度1回の数字があれば、マス位置と数字が
確定する。
同じように、行内、列内、1つのマスについても候補数字の
出現頻度を調べる。それぞれ出現頻度1回の数字があれば、
マス位置と数字が確定する。

数独プログラムgame81LEは数独エンジンの結果を利用して
空マスを色分け表示している。
ヒントAのベージュ色 - ブロック内
ヒントAの薄いピンク色 - 行内、列内
ヒントBの薄い緑色 - 1つのマス
色分けでヒント表示されている空マスには、手筋で考えれば、
そこに入る数字が確定する。

数独プログラムを使っていて、ヒントAボタン、ヒントBボタンを
押しても、ヒントを表示しない場合がある。
これは問題が難しいことによるが、言い換えれば数独エンジンの
性能が十分でないことによる。

2月版の数独プログラムは、
新たに隠れ数字と2マスの予約マス探索の2つを採りいれ、
エンジンの性能を強化している。この2つの探索法の追加により
今まで解けなかった問題を解けるようになった。

Blog0220b
show Map3のステータス行の見方
メニューバーのView - Show Map3 で選択する。
マップ3画面を表示する。
上の図は、マップ3画面で、7カ所のマスで「*」表示があり、
画面下のステータス行には次の表示がある。
Status(24) 835 912 R824 C594 C349
「*」表示のマスは、数字が確定できるマスを表しており、
ステータス行はそのマス位置と数字を表している。

Statusに続く括弧内の数字は盤面のコマ数を表す。盤面を
特定するのに利用する。
3桁の数字、英字に続く3桁の数字はマス位置と数字を表す。
835は枠に着目して、8枠3マス目に数字5が確定する。
R824は行に着目して、8枠2マス目に数字4が確定する。
C594は列に着目して、5枠9マス目に数字4が確定する。

プログラムは盤面のマスに、直接、答えの数字を書くことも
考えられるが、数独を解く手順が楽しめるよう、「*」で
ヒント表示する仕様とした。
数独にはRPGゲームのようにシナリオがあり、作者の
意図を確かめながら、数独を解くのも楽しみである。
早く問題を解きたい場合は、ステータス行の数字を
利用するとよい。

今回のプログラムではステータス行にヒントBで解ける答えは
載っていない。上の図で緑色の枠で囲った空マスがこれにあたる。
ステータス行にすべての答えが載っていない場合がある。

2012年2月18日 (土)

予約マスの探索

Blog0218_2a
数独プログラムgame81LE

1枠(左上のブロック)に着目する。
1行目、2行目の数字89、3列目の数字89から
1枠の7マス目、8マス目に数字89が入る。
7マス目、8マス目が数字89で予約される。
次に、数字1に着目する。
1行目、2列目、3列目の数字1から
1枠の4マス目、あるいは7マス目に数字1が入る。
ところが、1枠7マス目はすでに数字89で
予約されている。したがって、1枠の4マス目に
数字1が確定する。

Blog0218_2b

数独プログラムのメニューバー View-Show Map3を
選択する。数独の予約に対応したマップを表示する。
緑色の1桁の数字 - 入力済みの数字を表す。
青色の数字のあるマス - 予約の数字があるマス
上の図では7マス目、8マス目に数字89が予約の数字
ピンクの数字のあるマス - 残りの候補数字が1つ
あるマス上の図では数字1が残りの候補数字になる。
ブロック内に青色数字が2マス、ピンク色数字のマスが
1マスの場合のみ、残り候補数字が1つになり、ピンク色の
数字のマスに入る数字が確定する。
ブロック内に青色数字が3マスのみ、あるいは
青色数字の2マス、ピンク色数字の2マスの場合などは
予約として利用できない場合がある。

予約マスの探索アルゴリズム
1つのブロックに着目する。
作業用のブロックを1つ用意する。
ブロック内の候補数字の出現頻度を調べる。
ブロック内に2個ある候補数字を作業用ブロックの
同じマス位置にコピーする。
全ての候補数字についてコピーが終わったならば、
作業用ブロックのマス内の数字の個数を確認する。
個数が1個の場合、マップにピンク色で候補数字を
表示する。
個数が2個の場合、青色で候補数字を表示する。

上の図の左上のブロックで予約マスの探索動作を確認する。
ブロック内に2個ある候補数字は数字1、8、9
コピーが終わった時点の作業用ブロックの内容
[  ][  ][  ]
[1  ][  ][  ]
[189 ][ 89][  ]
4マス目がピンク色、7マス目、8マス目が青色で
数字表示される。7マス目、8マス目が予約マス

別のコマ配置の場合、
[  ][  ][  ]
[1  ][  ][  ]
[1  ][ 89][ 89]
4マス目、7マス目がピンク色
8マス目、9マス目が青色で予約マスになる。

さらに、別のコマ配置の場合、
[  ][  ][  ]
[18 ][  ][  ]
[19 ][ 89][  ]
4マス目、7マス目、8マス目が青色表示
しかしながら、予約マスはない。

もうひとつ、別のコマ配置の場合、
[1  ][  ][  ]
[1  ][ 9 ][  ]
[ 8 ][ 8 ][ 9 ]
6個のマスがピンク色表示
予約マスはない。

そのブロックに予約マスがあるかどうかは、ユーザが
マップ3を見て判断する。マップ3は予約マスの可能性が
あるマスを青色で表示する。

«隠れ数字