第9講 サブプロシージャの再帰的使用
第12話 魔方陣生成ソフトのコード解説その2
コード主要部分再掲
Sub f(g As Integer)
Dim i As Integer, j As Integer
For i = 1 To n * n
If g > 0 Then
For j = 0 To g - 1
If i = a(j) Then GoTo tobi
Next
End If
a(g) = i
If g Mod n = n - 1 Then
w = 0
For j = 0 To n - 1
w = w + a(n * Int(g / n) + j)
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
If Int(g / n) = n - 1 Then
w = 0
For j = 0 To n - 1
w = w + a(n * j + (g Mod n))
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
If g = n * n - 1 Then
w = 0
For j = 0 To n - 1
w = w + a(n * j + j)
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
If g = n * (n - 1) Then
w = 0
For j = 0 To n - 1
w = w + a(n * j + n - 1 - j)
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
If g + 1 < n * n Then
Call f(g + 1)
Else
Call h
End If
tobi:
Next
End Sub
解説の続き
1行1行追いながらの解説に入る前に、
何話かをかけて、各If文の業務内容を確認しておきます。
以下の記述は、
n = 3 すなわち、3次魔方陣の自動生成を行うという前提で行います。
最初のIf文
If g > 0 Then
For j = 0 To g - 1
If i = a(j) Then GoTo tobi
Next
End If
では何をしているかと申しますと、
数字の重複チェックを行っています。
魔方陣は、すべて異なる整数を入れなければならないからです。
もし重複がある場合には
If i = a(j) Then GoTo tobi
によって、tobiに飛びNextによりiは1つ進むようになっています。
If g Mod n = n - 1 Then
w = 0
For j = 0 To n - 1
w = w + a(n * Int(g / n) + j)
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
の任務は何でしょうか。
If文の条件 g Mod n = n - 1 が何を意味しているのか理解できれば、
どんな仕事をしているのかが、分かります。
0 | 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 |
条件 g Mod n = n - 1 を満たすのは、2,5,8の場合のみです。
n - 1 = 3 - 1 = 2
g Mod n = 2 Mod 3 = 2
g Mod n = 5 Mod 3 = 2
g Mod n = 8 Mod 3 = 2
ですよね。
それに対して、
g Mod n = 0 Mod 3 = 0
g Mod n = 1 Mod 3 = 1
g Mod n = 3 Mod 3 = 0
g Mod n = 4 Mod 3 = 1
g Mod n = 6 Mod 3 = 0
g Mod n = 7 Mod 3 = 1
0,1,3,4,6,7は条件を満たしません。
w = 0
For j = 0 To n - 1
w = w + a(n * Int(g / n) + j)
Next
の4行では何をしているでしょうか。
g = 2 の場合
j = 0 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(2 / 3) + 0) = w + a(0)
j = 1 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(2 / 3) + 1) = w + a(1)
j = 2 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(2 / 3) + 2) = w + a(2)
0 | 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 |
以上から、1行目の合計が行われていることが分かります。
g = 5 の場合
j = 0 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(5 / 3) + 0) = w + a(3)
j = 1 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(5 / 3) + 1) = w + a(4)
j = 2 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(2 / 3) + 2) = w + a(5)
0 | 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 |
以上から、2行目の合計が行われていることが分かります。
g = 8 の場合
j = 0 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(8 / 3) + 0) = w + a(6)
j = 1 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(8 / 3) + 1) = w + a(7)
j = 2 のとき、
w = w + a(n * Int(g / n) + j) = w + a(3 * Int(8 / 3) + 2) = w + a(8)
0 | 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 |
以上から、3行目の合計が行われていることが分かります。
ですから、
If g Mod n = n - 1 Then
w = 0
For j = 0 To n - 1
w = w + a(n * Int(g / n) + j)
Next
If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
End If
では行(横)合計が魔方陣の条件を満たしているかを調べているわけです。
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 入門へ第2部へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ