第14講 末項確定法による魔方陣自動生成ソフトの高速化
第4話 改良ファイル肝の部分の解説その1
Sub f(g As Byte, cn As Integer, n As Byte, x() As Byte, iz() As Byte, jz() As Byte)
Dim h As Byte, i As Byte, j As Byte, k As Byte, a As Byte, s As Integer, gi As Byte, gj As Byte
Dim ji As Byte, jj As Byte, hh As Byte, w As Byte, w1 As Integer, ii As Byte
a = cn Mod 10
s = Int(cn / 10)
gi = iz(g)
gj = jz(g)
If gi = 0 And gj = n - 2 Then
w = 0
For i = 0 To n - 3
w = w + x(0, i)
Next
w = w + x(0, n - 1)
w1 = Int(n * (n * n + 1) / 2) - w
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
If n Mod 2 = 0 Then
For i = 0 To 3 * n - 4
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
End If
If n Mod 2 = 1 Then
For i = 0 To 3 * n - 5
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
End If
x(gi, gj) = w1
Call f(g + 1, cn, n, x(), iz(), jz())
Exit Sub
End If
まず、
If gi = 0 And gj = n - 2 Then
のgi = 0 And gj = n - 2
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
セルが1行目(n-1)列目(上表でいうと0行目2列目、0から数えているため)
に来ている場合です。
つまり、4次魔方陣の場合はセル番号9に相当します。
If gi = 0 And gj = n - 2 Then
は偶数次の場合は
If g = 3 * n - 3 Then
奇数次の場合は
If g = 3 * n - 4 Then
と変更しても同じです。
n=4のときは、
3*n-4=3×4-3=9
になりますよね。
奇数次のとき、番号が1つ減っている理由は、
0 | 9 | 10 | 11 | 5 |
12 | 1 | 13 | 6 | 14 |
15 | 16 | 2 | 17 | 18 |
19 | 7 | 20 | 3 | 21 |
8 | 22 | 23 | 24 | 4 |
対角線のところがかぶっているからです。
n=5ときは、
3*n-4=3×5-4=11
ですよね。1行目4列目になっていますね。
If gi = 0 And gj = n - 2 Then
とした理由は、
偶数の場合と奇数の場合に場合分けしないで済むからです。
1行目(n-1)列目の場合、試行錯誤は必要ありません。
試行錯誤しないようにしているのが、If文
If gi = 0 And gj = n - 2 Then
というわけです。
次の
w = 0
For i = 0 To n - 3
w = w + x(0, i)
Next
は4次魔方陣なら、
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
1行目の2列目
0 | 8 |
までの合計を出しています。
w = w + x(0, n - 1)
はその合計に1行目4列目
4 |
を加えています。
w1 = Int(n * (n * n + 1) / 2) - w
は魔方陣の行の合計(4次魔方陣の場合34)から、
先の合計(すなわち、1行目(n-1)列目のセルを除いた1行目の合計)
を引いています。
1行目(n-1)列目のセルは自動決定だからです。
このとき、組み合わせによってはw1が1より小さくなったり、
nの2乗より大きくなったりします。
例えば、
1 | 3 | 4 | |
2 | |||
15 | |||
16 |
の場合
34-(1+3+4)=42
で上限の16(4の2乗)を越えてしまっています。
あるいは、
13 | 11 | 12 | |
2 | |||
5 | |||
14 |
なら、
34-(13+11+12)=-12
です。
魔方陣は1からnの2乗までの数字を入れるという原則になっていますから、
禁則に反します。
なので、nの2乗より大きくなる場合と1より小さくなる場合、
その前のセルに戻ってやり直す必要がありますので、
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
となっているわけです。
初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門
数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ