数独を解くプログラム
数独の正式版を解くプログラムを考える前に、 数字の数を少なくしたよりシンプルな
簡易版を解くプログラムを検討しましょう。
プログラムの構成は メインプログラムと機能別に分れた複数の外部副プログラムか
らなります。 枠の表示や数字の表示そしてブランキングに関する外部副プログラム
については 既に問題作成プログラムの所で説明しているので、 ここでは説明を省略
します。
メインプログラムはテキストファイルから問題のデータを読み込むようになっています
。ブランキングされたマス目については、数字の0が割り当てられています。したがっ
て、以下のような問題の場合は、
<数独の問題(例)>
(図1、十進BASICによる2Dグラフィックス)
次のようなデータ内容を持つファイルが必要となります(半角の数字で入力)。
一行目 -> 0,0,3,2
二行目 -> 0,0,0,0
三行目 -> 4,0,0,0
四行目 -> 2,0,1,0
メインプログラムを起動すると、 図1のような問題画面ウィンドウがポップアップしま
す。 数字とブランキング位置に問題がなければ、 ”解を表示しますか?”というメッセ
ージボックスのOKボタンを押して解を表示させます(図2参照)。
<数独の問題(解)>
(図2、十進BASICによる2Dグラフィックス)
次に、 このプログラムの主要部であるSOLVERという問題を解く外部副プログラム
について簡単に説明します。
SOLVERのプログラムは数独のルールに基づいて作られています。 基本的に、 数
字の整合性をチェックする4つの部分から構成されます。
(1)太枠内、 縦及び横に並んだ各4つの数字の内3つが既知ならば 残りの一つの
数字を決定できる
(2)ある特定の数字が3つ存在すれば、4つ目の数字のマス目を決定できる
(3)太枠内の数字の内2つが判らなくても、枠外の数字の情報からそれらを決定でき
る場合がある
(4)太枠内の数字の内3つが判らなくても、枠外の数字の情報から判っている数字の
上下左右の数字を決定できる場合がある
以上のポイントに従って各部分はコーディングされています。(2)〜(4)に関しては判
り辛いと思うので、以下の図を参考にしてください(図3〜図5を参照)。
<(2)に関する説明図>
(図3、十進BASICによる2Dグラフィックス)
赤マルのマス目の位置に同じ数字が入っているとすると、 黒マルのマス目の位置に
も同じ数字が入ることに注意してください。
<(3)に関する説明図>
(図4、十進BASICによる2Dグラフィックス)
左下の太枠内で赤マルと青マルのマス目に既に異なる数字が入っている状況で、枠
外の緑マルのマス目に数字があれば、枠内の黒マルのマス目にも同じ数字が入るこ
とに注意してください。
<(4)に関する説明図>
(図5、十進BASICによる2Dグラフィックス)
左下の太枠内で赤マルのマス目に数字が一つだけ入っている状況で、 枠外の緑マ
ルのマス目に数字があれば、枠内の黒マルのマス目にも同じ数字が入ることに注意
してください。
課題(その1)
上記のプログラムで解けない問題があるか調べてください。もし、あるとすれば、SO
LVERのプログラムにどのようなコードを追加しなければなりませんか。
課題(その2)
問題そのものに論理矛盾があった場合に、 それを検知し警告を出すプログラムを作
成してください。 また、 このプログラムをSOLVERのプログラムに組み込んでくださ
い。
それでは、数独(正式版)の問題を解くプログラムを考えてみましょう。メインプログラ
ムとSOLVERのコード部分を除いた他の外部副プログラムは以下のようになります
。
SOLVERの具体的なコードがここに入ります。
SOLVERのプログラムコードを考えるために必要なポイントを纏めてみます。 簡易
版の所で出てきたポイントが基本になりますが、 その内容はさらに複雑になります。
ウィキペディアの問題例(図6参照)が解けるレベルのものを考えます。
<ウィキペディアの問題例>
(図6、十進BASICによる2Dグラフィックス)
(1)と(2)は以下のようにストレートに拡張できますが、中級レベル以上の問題を解く
初期の段階では、 これらのポイントはあまり役に立ちません(但し、 終盤では極めて
有効なポイント)。
(5)太枠内、 縦及び横に並んだ各9つの数字の内8つが既知ならば、 残りの一つの
数字を決定できる
(6)ある特定の数字が8つ存在すれば、9つ目の数字のマス目を決定できる
(3)や(4)に相当する初期の段階でも使えるポイントを探してみます。 数字を求める
手順を複雑にし過ぎると、コーディング自体も煩雑になるので注意してください。プロ
グラムのコンパクト化と判り易さはトレードオフになります。 正式版の場合、 求める
数字の数もかなり増えるので、 ここではプログラムのコンパクト化に焦点を当てて考
えます。 従って、 上記の2つのポイントだけでなく、(6)の内容も統合したポイントは
次のようになります。
(7)太枠内の判らない特定の数字のマス目は 枠外のその数字の情報から決定でき
る場合がある
このポイントに関する記述はシンプルですが、 これを使えば中級レベル以下の問題
は解けるようになると思います。
<(7)に関する説明図>
(図7、十進BASICによる2Dグラフィックス)
左下の太枠内を見てください。 左側の一列に数字が全て入っている状態で、枠外の
緑マルに同じ数字が入っていれば、黒マルにもその数字が入ることに注意してくださ
い。
課題(その3)
(7)のポイントだけを使って、ウィキペディアの問題例(図6参照)を最後まで解いてく
ださい。
(7)のポイントのみを考慮したSOLVERのプログラムコードは以下のようになります
。
中間部分は省略します。
このプログラムを使ってウィキぺディアの問題例(図6参照)を解いた結果を図8に示
します。
<ウィキペディアの問題例(解)>
(図8、十進BASICによる2Dグラフィックス)
プログラム自体は人間が作ったものですが、一瞬で問題を解くコンピュータの処理速
度の凄さを実感してください。IQが飛びぬけて高い人間でも、このコンピュータの速度
には付いていけません。
課題(その4)
上記のSOLVERのプログラムコードに (5) のポイントも考慮したコードを追加してく
ださい。
課題(その5)
上記のプログラムでは数独の難問は解けません。 難問を解くために必要なポイント
を纏めてください。また、それ(又はそれら)をコード化してください。