第10講 数独の問題を解くプログラムVer0
第4話 「If mah(i1, i2) = 0 Then ・・・ End Ifでは何がなされているの?」その1

今回から
        If mah(i1, i2) = 0 Then
          For i3 = 0 To 8
            dhs(i1, i2, i3) = 0
          Next
          For i3 = 0 To 8
            If i2 <> i3 And mah(i1, i3) > 0 Then dhs(i1, i2, mah(i1, i3) - 1) = 1
          Next
          For i3 = 0 To 8
            If i1 <> i3 And mah(i3, i2) > 0 Then dhs(i1, i2, mah(i3, i2) - 1) = 1
          Next
          i1s = Int(i1 / 3)
          i2s = Int(i2 / 3)
          For i3 = 0 To 2
            For i4 = 0 To 2
              If 3 * i1s + i3 <> i1 And 3 * i2s + i4 <> i2  *(実際にはここで改行はなし)
              And mah(3 * i1s + i3, 3 * i2s + i4) > 0 Then dhs(i1, i2, mah(3 * i1s + i3, 3 * i2s + i4) - 1) = 1
            Next
          Next
          For i3 = 0 To 8
            If dhs(i1, i2, i3) = 0 Then
              w = cnn(i1, i2)
              dhs1(i1, i2, w) = i3 + 1
              cnn(i1, i2) = cnn(i1, i2) + 1
            End If
          Next
        End If
では何がなされているか見ていきましょう。
if文はもちろんmah(i1, i2) = 0のとき、つまりセルが空欄のときみ実行されます。
では何か実行されるのでしょうか。

まず、配列dhs(i1, i2, i3)の意味から説明します。
dhs(i1, i2, i3)は0か1のみの値だけを与え、0は×、1は○の意味を持っているものとします。
dhs(i1, i2, i3) = 0のとき、mah(i1, i2)に対応するセルが入っている行にも列にも小ブロック内にもi3+1
(ここで1を加えている理由は、配列は0から始まるのに対して数独は1から始まるからです。
配列を1から始めれば+1は不要になりますし、mah(i1, i3) - 1などの- 1も削除しなければなりません。
ただし、その場合はfor文も1ずらして For i3 = 1 To 9 としなければなりません。
また、配列の宣言もdhs(8, 8, 8)からdhs(8, 8, 9)に変更しなければなりません。)
の値が使われていないことを示します。
逆にdhs(i1, i2, i3) = 1のとき、mah(i1, i2)に対応セルが入っている行か列か小ブロック内のどこかにi3+1の値が使われていること示します。

具体例がないと何のことかわからないと思いますので、
具体例を示しましょう。下の表では例えば、

*4

の黄色の数字はセルの番号を示し、このセルは空欄になっています。
それに対して

3

などははそのセルに白い数字が入っていることを示します。

0
1
2
3
4
5
6
7
8

はdhs(i1, i2, i3)の1番目の変数i1に対応します。そして、

0 1 2 3 4 5 6 7 8

はdhs(i1, i2, i3)の2番目の変数i2に対応します。

0 1 2 3 4 5 6 7 8
0 *0 *1 *2 *3 *4 *4 *5 *8 *8
1 4 9 11 12 13 14 15 6 17
2 8 19 1 21 2 23 4 25 26
3 6 28 29 30 4 32 33 34 35
4 36 37 2 1 40 5 8 43 44
5 45 46 47 48 8 50 51 52 9
6 54 55 8 57 5 59 3 61 7
7 63 7 65 66 67 68 69 4 6
8 72 4 9 2 76 77 78 79 80

dhs(0, 0, 0)の値は0と1のどちらでしょうか。

*0 *1 *2
4 9 11
8 19 1

同ブロック内に

1

があるので、dhs(0, 0, 0)の値は1です。
つまり、mah(0, 0)には0+1=1を入れられないことになります。
dhs(0, 0, 1)の値はどうでしょうか。

0 1 2 3 4 5 6 7 8
0 *0 *1 *2 *3 *4 *4 *5 *8 *8
1 4 9 11 12 13 14 15 6 17
2 8 19 1 21 2 23 4 25 26
3 6 28 29 30 4 32 33 34 35
4 36 37 2 1 40 5 8 43 44
5 45 46 47 48 8 50 51 52 9
6 54 55 8 57 5 59 3 61 7
7 63 7 65 66 67 68 69 4 6
8 72 4 9 2 76 77 78 79 80


*0 *1 *2
4 9 11
8 19 1

同じ列にも行にもブロックにも1+1=2の値はありません。
なのでdhs(0, 0, 1)=0です。
mah(0, 0)にはを入れてもいいことになります。

0 1 2 3 4 5 6 7 8
0 *0 *1 *2 *3 *4 *4 *5 *8 *8
1 4 9 11 12 13 14 15 6 17
2 8 19 1 21 2 23 4 25 26
3 6 28 29 30 4 32 33 34 35
4 36 37 2 1 40 5 8 43 44
5 45 46 47 48 8 50 51 52 9
6 54 55 8 57 5 59 3 61 7
7 63 7 65 66 67 68 69 4 6
8 72 4 9 2 76 77 78 79 80

今度はdhs(6, 7, 8)は0でしょうか。それとも1でしょうか。

61

の同じ列にも同じ行にも同じブロックにも同じブロックにも8+1=9は使われておりません。
したがって、dhs(6, 7, 8)=0です。
では皆さん、
dhs(6, 7, 0)=
dhs(6, 7, 1)=
dhs(6, 7, 2)=
dhs(6, 7, 3)=
dhs(6, 7, 4)=
dhs(6, 7, 5)=
dhs(6, 7, 6)=
dhs(6, 7, 7)=
の右辺の値を入れてみましょう。
考えてわかったら答えをクリックしましょう。
答え



第3話へ 第5話へ
VB入門講義応用編トップへ

VB入門講義トップへ