第2講 局所リスト構造解析
第5話 乗り越えなければならない課題と解消策
まず、課題を列挙しましょう。
課題1
{1,2,3,4,5,6,7,8,9}
から、
{1,2,3,4,8,6,7,9,5}
をいかに実現するか。
課題2
の場面も考えられる中
mx(i, j) = mx(i, j) - 1
をいかなる条件下で行うか。
課題3
課題2の場面では
{1,2,3,4,8,6,7,9,5}
をそのままにしておかなければならないが、
何もしないという判断をいかにするか。
一応3つ課題を考えてみましたが、
3つの課題を一気にクリアする方法がありそうです。
それは、次のようにするのです。
Dim ybs As Byte, xbs As Byte
Dim isy As Byte, ia As Byte
ybs = rn * Int(y(g) / rn)
xbs = rn * Int(x(g) / rn)
For i = 0 To n - 1
isy = Int(i / rn)
ia = i Mod rn
If ybs + isy <> y(g) And xbs + ia <> x(g) And p(ybs + isy, xbs + ia) = 0 Then
For j = 0 To mx(ybs + isy, xbs + ia)
If p(y(g), x(g)) = rlst(ybs + isy, xbs + ia, j) Then
・
・
・
Exit For
End If
Next
End If
Next
これはブロック内の重複を調べる部分です。
行や列の行の重複についても同様ですが、
ブロックにおける検査が一番難しいので、
例示しました。
では、皆さん第3話、第4話と上をヒントにして、
を実現するプログラムを
第1講第6話の 参考ダウンロード添付ファイルを改良して
組んだ下さい。
もちろん、以上の説明があってもこのプラミングは大変難しいといえますが、
第4部に挑戦するほど前向きで能力の高い皆さんですから、
粘り強く考えれば必ずプログラミングできますよ。
尚、各プロシージャはなるべく大きくならないように、
座標プロシージャ・数字入力プロシージャ・全体リスト構造解析・局所リスト構造解析
などの専用プロシージャを作って下さい。
それから、汎用性のあるものにするために、
For i =0 To 8
ではなく、
For i =0 To n - 1
等として下さい。
nに入力する値を9とすると9×9の数独が
16とすると16×16の数独が
25とすると25×25の数独になるようにしたいからです。
文字にできるところはなるべく文字にすることが、
汎用性=普遍性のあるためのプログラムにするためのコツです。
さらに、ヒントとして数字入力プロシージャの一部を書いておきましょう。
Dim i As Byte, ii As Byte, iii As Byte
ii = Int(Rnd * mx(y(g), x(g)))
For i = 0 To mx(y(g), x(g))
iii = (i + ii) Mod (mx(y(g), x(g)) + 1)
p(y(g), x(g)) = rlst(y(g), x(g), iii)
これは、リスト順に入れていくのではなく、
ランダムに入れるための措置です。
たびたび出てくるgについては、
第23講 数独を解くソフト 第2話
等を参照して下さい。
更にくどいようですが、
プログラムが簡単になるように、
Dim m As Integer, n As Integer, h As Integer
Dim p(9, 9) As Byte, mx(9, 9) As Byte, rlst(9, 9, 9) As Byte
'pは数独を収納する配列
'mxは各セルの候補数字の個数を収納する配列
'rlstは候補数字を収納する配列
Dim y(81) As Byte, x(81) As Byte
Dim a(9, 9) As Integer
Dim hintosu As Byte, rn As Byte
Dim cn As Integer
はグローバル変数またはグローバル配列にすることをお勧めします。
すぐ下に色がついて表示されているものは、
リスト構造解析です。
赤いセルのリスト構造解析が赤い囲いで示されています。
確かに、数独のルールから1,2,9,4は候補の可能性があり、
6,3,8,7,5は赤いセルには入れられません。
5,3は列の条件から、
6はブロックの条件から、
8,7,3は行の条件から不可ですね。
リスト構造解析の部分はなくても良いのですが、
プログラミングにはミスが付きものですから、
本当に正しく動いているかを確認するための方法を考えることも重要です。
色の付け方は、第24講 各種のグラフの作成第3話
を参照して下さい。
マクロの記録から学ぶでした。
1つ言い忘れていました。
Private Sub CommandButton1_Click()の冒頭には
Rnd (-1)
Randomize Timer
を入れるの忘れないようにしましょう。
エクセル起動1回目の問題が毎回変わるようにするためでしたね。
この2行を入れないと、作成される問題は1回1回は異なるとはいえ、
同じ順番で同じ問題が生成されてしまいます。
毎回異なる順番で異なる問題を生成させるために、
Rnd (-1)によって初期化してから、
シード値を時間から取得する必要があります。
以上の考え方の説明があっても、
初心者の方には、疑似疑似数独作成ソフト
(疑似が1つ減っています。
第30講第6話で作ったものは、問題配置の時点で数独のルールを破っているのに対して、
問題配置時には少なくともルールを守るようになるからです。
疑似がすべて取れると数独作成ソフトの一応の完成となります。)
をプログラムするのは、
まだまだ難しいと思いますので、第6話にプログラムの骨格を示しますので、
それを参考にプログラミングして頂ければと思います。
第7話にプログラム例を載せますので、
第6話を見なくてもプログラミング出来る方は、第7話に飛んで下さい。
eclipse c++ 入門
魔方陣 数独(ナンプレ)で学ぶ VBA 入門
数独(ナンプレ)のシンプルな解き方・簡単な解法の研究
vc++講義へ
excel 2013 2010 2007 vba入門へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
専門用語なしの C言語 C++ 入門(Visual C++ 2010で学ぶ C言語 C++ 入門)
専門用語なしの excel vba マクロ 入門 2013 2010 2007 対応講義 第1部
eclipse java 入門へ
excel 2016 vba 入門へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ