第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
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
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
 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

となっているわけです。

第3話へ 第5話へ



トップ

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

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