第11講 数独の問題を解くプログラムVer1の解説
第3話 プロシージャSub bangousakuseiをトレースし第1話掲載の番号付けを再現しよう!
ここではプログラムをトレースし、番号割り振り
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 80 | 9 | 10 | 33 | 48 | *4 | *5 | *8 | 11 |
1 | *4 | *9 | 12 | 34 | 13 | 35 | 14 | *6 | 15 |
2 | *8 | 16 | *1 | 49 | *2 | 36 | *4 | 17 | 0 |
3 | *6 | 37 | 18 | 19 | *4 | 38 | 20 | 50 | 39 |
4 | 21 | 1 | *2 | *1 | 40 | *5 | *8 | 3 | 4 |
5 | 41 | 22 | 42 | 23 | *8 | 43 | 44 | 51 | *9 |
6 | 5 | 24 | *8 | 25 | *5 | 26 | *4 | 27 | *7 |
7 | 45 | *7 | 6 | 28 | 29 | 46 | 30 | *4 | *6 |
8 | 31 | *4 | *9 | *2 | 47 | 52 | 2 | 7 | 32 |
を再現してみましょう。プログラムを再掲すると、
Sub bangousakusei()
Dim i1, i2, i3 As Integer
g = 0
For i = 1 To 9
For j = 0 To 8
For k = 0 To 8
If cnn(j, k) = i Then
iz(g) = j
jz(g) = k
g = g + 1
End If
Next
Next
Next
hs = g
End Sub
トレースする際には、変数g,i,j,kが何を表すかしっかりつかんでいなければなりません。
gは、
80 |
などの紺色の番号に相当します。そして、iはcnn(j, k)の値、すなわち
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 3 | 3 | 3 | 4 | 5 | 4 | 5 | 8 | 3 |
1 | 4 | 9 | 3 | 4 | 3 | 4 | 3 | 6 | 3 |
2 | 8 | 3 | 1 | 5 | 2 | 4 | 4 | 3 | 1 |
3 | 6 | 4 | 3 | 3 | 4 | 4 | 3 | 5 | 4 |
4 | 3 | 1 | 2 | 1 | 4 | 5 | 8 | 2 | 2 |
5 | 4 | 3 | 4 | 3 | 8 | 4 | 4 | 5 | 9 |
6 | 2 | 3 | 8 | 3 | 5 | 3 | 3 | 3 | 7 |
7 | 4 | 7 | 2 | 3 | 3 | 4 | 3 | 4 | 6 |
8 | 3 | 4 | 9 | 2 | 4 | 5 | 1 | 2 | 3 |
3 |
などの赤の番号に相当します。j(またはiz(g))は
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
の濃紺の番号に相当します。最後k(まはたjz(g))は
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
のピンクの番号に対応しています。
ではトレースしてみましょう。
i=0のとき、cnn(j, k)の値すなわち
3 |
などはすべて1以上なので、if文のcnn(j, k) = iの条件を満たしません。
左辺が1以上で右辺が0だからです。したがって、if文が実行されるための条件はi>0です。
i=1,j=0,k=0のとき、cnn(j, k) = iはcnn(0, 0)=1すなわち3=1で条件をクリアしません。
i=1,j=0,k=1のとき、cnn(j, k) = iはcnn(0, 1)=1すなわち3=1で条件をクリアしません。
i=1,j=0,k=2のとき、cnn(j, k) = iはcnn(0, 2)=1すなわち3=1で条件をクリアしません。
i=1,j=0,k=3のとき、cnn(j, k) = iはcnn(0, 3)=1すなわち4=1で条件をクリアしません。
i=1,j=0,k=4のとき、cnn(j, k) = iはcnn(0, 4)=1すなわち5=1で条件をクリアしません。
i=1,j=0,k=5のとき、cnn(j, k) = iはcnn(0, 5)=1すなわち0=1で条件をクリアしません。
(cnn(0, 5)のときは、mah(0,5)=4すなわちmah(0,5)>0ですから、第10講で解説したとおり、
cnn(0, 5)については、何の処理も行われませんので、cnn(0, 5)=0でした。)
以下同様に続き、
i=1,j=2,k=8のとき、cnn(2, 8)=1すなわち1=1となりはじめてcnn(j, k) = iの条件をクリアしてif文が実行され、
iz(0)=2,jz(0)=8(2行目のg=0よりgは0でした。)となります。そして、g=g+1よりg=1となります。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 3 | 3 | 3 | 4 | 5 | 4 | 5 | 8 | 3 |
1 | 4 | 9 | 3 | 4 | 3 | 4 | 3 | 6 | 3 |
2 | 8 | 3 | 1 | 5 | 2 | 4 | 4 | 3 | 1 |
3 | 6 | 4 | 3 | 3 | 4 | 4 | 3 | 5 | 4 |
4 | 3 | 1 | 2 | 1 | 4 | 5 | 8 | 2 | 2 |
5 | 4 | 3 | 4 | 3 | 8 | 4 | 4 | 5 | 9 |
6 | 2 | 3 | 8 | 3 | 5 | 3 | 3 | 3 | 7 |
7 | 4 | 7 | 2 | 3 | 3 | 4 | 3 | 4 | 6 |
8 | 3 | 4 | 9 | 2 | 4 | 5 | 1 | 2 | 3 |
をご覧になれば、i=1でif文が実行されるのは、(2, 8)以外では(4, 1)と(8, 6)のときのみです。
(2, 8)のときがif文が実行される2回目で、iz(1)=2,jz(1)=8,g=2となります。
そして、(8, 6)のときが3回目の実行でiz(2)=8,jz(2)=6,g=3です。
i=2のときは
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 3 | 3 | 3 | 4 | 5 | 4 | 5 | 8 | 3 |
1 | 4 | 9 | 3 | 4 | 3 | 4 | 3 | 6 | 3 |
2 | 8 | 3 | 1 | 5 | 2 | 4 | 4 | 3 | 1 |
3 | 6 | 4 | 3 | 3 | 4 | 4 | 3 | 5 | 4 |
4 | 3 | 1 | 2 | 1 | 4 | 5 | 8 | 2 | 2 |
5 | 4 | 3 | 4 | 3 | 8 | 4 | 4 | 5 | 9 |
6 | 2 | 3 | 8 | 3 | 5 | 3 | 3 | 3 | 7 |
7 | 4 | 7 | 2 | 3 | 3 | 4 | 3 | 4 | 6 |
8 | 3 | 4 | 9 | 2 | 4 | 5 | 1 | 2 | 3 |
(4, 7),(4, 8),(6, 0),(7, 2),(8, 7)の順でif文が実行されていき、それぞれ
iz(3)=4,jz(3)=7,g=4
iz(4)=4,jz(4)=8,g=5
iz(5)=6,jz(5)=0,g=6
iz(6)=7,jz(6)=2,g=7
iz(7)=8,jz(7)=7,g=8となっていきます。
以下同様に動いていって最終的に
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 80 | 9 | 10 | 33 | 48 | *4 | *5 | *8 | 11 |
1 | *4 | *9 | 12 | 34 | 13 | 35 | 14 | *6 | 15 |
2 | *8 | 16 | *1 | 49 | *2 | 36 | *4 | 17 | 0 |
3 | *6 | 37 | 18 | 19 | *4 | 38 | 20 | 50 | 39 |
4 | 21 | 1 | *2 | *1 | 40 | *5 | *8 | 3 | 4 |
5 | 41 | 22 | 42 | 23 | *8 | 43 | 44 | 51 | *9 |
6 | 5 | 24 | *8 | 25 | *5 | 26 | *4 | 27 | *7 |
7 | 45 | *7 | 6 | 28 | 29 | 46 | 30 | *4 | *6 |
8 | 31 | *4 | *9 | *2 | 47 | 52 | 2 | 7 | 32 |
が完成するわけです。