第8講 配列の学習
第7話 2次元配列による数独もどきに行の条件を付け加える・・・コード解説



Private Sub CommandButton1_Click()
  Dim i As Byte, j As Byte, k As Byte, a(8, 8) As Byte, h As Byte
  For i = 0 To 8
    For j = 0 To 8
      a(i, j) = Int(9 * Rnd) + 1
      
If j > 0 Then
        h = 1
        For k = 0 To j - 1
          If a(i, k) = a(i, j) Then
            h = 0
            Exit For
          End If
        Next
        If h = 0 Then j = j - 1
      End If

    Next
  Next
  For i = 0 To 8
    For j = 0 To 8
      Cells(5 + i, 2 + j) = a(i, j)
    Next
  Next
End Sub
参考ファイル

コード解説
      If j > 0 Then
というのは、2列目以降ということです。
再度繰り返しますが、本サイトでは縦列を単に列といい、
横列を行といいます。
この言い方は、数学の行列の理論に従っています。
ですから、2列目以降とは

の赤の部分を指しています。
jは0から始まりますので、
j=0ときが1列目、j=1のときが2列目、j=2のときが3列目、・・・
と列数目とjは1つずれます。
例えば、2列目(ということは
j=1のときです)が

7 7              

7のとき
        h = 1
        For k = 0 To j - 1
          If a(i, k) = a(i, j) Then

If文の肯定側に相当して
            h = 0
            Exit For
hは0とされ、kのFor文が強制的に終了されます。
強制的に終了される必要があるのは、
1つでも重複があれば、jは進めてはいけないことが分かるので、
それ以上の探索は無意味だからです。
数独自動生成アプリにおいては、
良問の難問を生産するには場合によっては億から兆のレベルの
計算量を必要としますので、
できるだけ無駄な計算をさせないようにさせないと、
数独生成に時間がかかってしまいます。
忙しい現代ですから、
数独生成に10分もかかったらそのアプリは、
誰も使ってくれないでしょう。
待ってくれるのはせいぜい30秒程度でしょう。
ですから、高速化を常に頭に置いておかなければなりません。
さて、kのFor文が強制的に終了された場合、hは0になっていますから
        If h = 0 Then j = j - 1
によって、jは1つ戻されます。
j=1(2列目だから)でしたからjは0に戻される訳です。
そして、
    Next
によって、jは1つ進められますから、
jは1に戻ります。
通常であれば1から2に進むところ重複が発見されたので、
進まずもう一度1のままjのFor文が遂行されます。
もし、次も

7 7              

7であれば同じことが繰り返されます。そして、

7 2              

2列目が7以外になったとき、
        h = 1
        For k = 0 To j - 1
          If a(i, k) = a(i, j) Then
            h = 0
            Exit For
          End If
        Next
        If h = 0 Then j = j - 1

If文は実行されず、hは1のままですから
        If h = 0 Then j = j - 1
が実行されず、Nextによってはじめて1から2へと進みます。
そのまま進行して

7 2 6 8 6        

5列目(j=4のとき)に重複する6が現れたときも、
        For k = 0 To j - 1
          If a(i, k) = a(i, j) Then
            h = 0
            Exit For
          End If
        Next

kのFor文の3回目のループのときに、
If文に抵触して、jは4から進まず4のままもう一度ループを繰り返します。
5列目が7,2,6,8以外のものになるまで、
        If h = 0 Then j = j - 1
は繰り返され、jは強制的に留められた状態を繰り返し、

7 2 6 8 1        

重複がなくなったときに、やっとjは4から5に歩を進められることになります。
以上のことを繰り返す内に

7 2 6 8 1 3 4 5 9

数独の行(横列)の条件を満たすものができるのです。


6話へ 第8話へ


トップ

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

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