第13講 プロシージャの再帰的使用による数独解答自動生成
第3話 ブロックの重複をチェックするには?

列や行の重複チェックと比べると、
ブロックの重複チェックはかなり難しいですね。
理由の1つは、列や行が1次元であるのに対して、
ブロックは2次元だからです。
さらに、難しくしている理由が2つあります。
その1つ目は、

1 2 3
4 5 6
7 8 9

列と行のチェックはすでにしてあるので、
チェックの重複を避けなければならないということです。
良問で難問である数独(問題)を生成するためには、
膨大な計算量を必要とします。
かなりの試行錯誤をしないと、
良問にして難問である数独の生成は難しいのです。
いえ、良問と難問という条件を削ったとしても、
難しいというのが正解です。
数独は
① 答え(解)が存在する
② 別解が存在しない
という矛盾する2つの要求を満たさなければならないからです。
適当にヒントを配置したのでは、
ほとんどの場合、
解なしか複数答えがあるのかどちらかになってしまいます。
ですから、膨大な計算量になりますから、
重複チェックの重複は避けたいのです。

1 2 3
4 5 6
7 8 9

例えば、中央のセルと型と重複していないかを調べる訳ですが、
2と4の位置にあるセルとの重複検査はすべに済んでいるので、
1と3の位置にあるセルのみと比較することになります。
ここで皆さんは、えっ?
7と9はどうなのと疑問を抱いたのではありませんか。
その検査は不要というか、
するとおかしなことになってしまいます。
gはセル番号でしたから、番号を1つずらしておきましょう。

0 1 2
3 4 5
6 7 8

数字は、0→1→2→3→・・・の順に埋まっていきます。
ですから、セル

4

の位置にあるときは、
数字は0,1,2,4の位置のセルしか埋まっていないのです。
ですから数字は、例えば次のように埋まっている訳です。

1 2 3
4 1

(セル番号とセルの中に入っている数字を明確に区別しないと
訳がわからなくなります。
今度の表記は、セルに入っている数字です。)
セル番号0とセル番号4には同じ数字1が入っているので、
この場合には、
次のセル=セル番号5のセルには進まないようにしなければならないです。
すなわち、
   If h = 1 Then
      ・・・
      ・・・
            
h = 0
      ・・・
      ・・・

    End If

    If h = 1 Then
      If g + 1 < n * n Then
        Call f(g + 1, cn, n, x())
          ・・・
          ・・・
として、次のセルに進まないようにしてやらなければならないのです。

さて、

1 2 3
4 1

という状態ですらから

0 1 2
3 4 5
6 7 8

重複検査は、0と2の位置のセルのみと行えば良いことがお分かりでしょうか。

0 1 2
3 4 5
6 7 8

さて、6の位置にあるときはどこと
重複チェックを行えば良いですか。





第2話へ 第4話へ



トップ

初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門

数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ