第15講 3次魔方陣と4次魔方陣の作成

第7話 3次魔方陣と4次魔方陣の自動生成コード解説その4
コード再掲
Dim mah(4, 4) As Byte, x(16) As Byte, y(16) As Byte
Dim n As Byte, cn As Integer
Private Sub CommandButton1_Click()

  n = Cells(3, 8)
  cn = 0
  zhy
  ms (0)
  Cells(4, 12) = cn

End Sub


Sub zhy()

  Dim i As Byte
  For i = 0 To n * n - 1
    x(i) = i Mod n
    y(i) = Int(i / n)
  Next

End Sub


Sub ms(g As Byte)

  Dim i As Byte, j As Byte, k As Byte, a As Byte, b As Byte, w As Byte
  a = x(g)
  b = y(g)

  For i = 0 To n * n - 1
    mah(b, a) = i + 1
    If g > 0 Then
      For j = 0 To g - 1
        If mah(b, a) = mah(y(j), x(j)) Then GoTo tobi
      Next
    End If
    If a = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(b, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If b = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, a)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = n - 1) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = 0) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, n - 1 - j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If g + 1 < n * n Then
      ms (g + 1)
    Else
      For j = 0 To n - 1
        For k = 0 To n - 1
          Cells(6 + j + Int(cn / 10) * (n + 1), 1 + k + (cn Mod 10) * (n + 1)) = mah(j, k)
        Next
      Next
      cn = cn + 1
    End If
tobi:
  Next

End Sub

今話では

   0
0  0 1 2
   
1  3 4 5
     
2  6 7 8
     


これ以降を追います。
横合計検査
    If a = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(b, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
をクリアした後









それ以降の検査
    If b = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, a)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = n - 1) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = 0) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, n - 1 - j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
は一切該当しませんので、
    If g + 1 < n * n Then
      
ms (g + 1)
    Else
      For j = 0 To n - 1
        For k = 0 To n - 1
          Cells(6 + j + Int(cn / 10) * (n + 1), 1 + k + (cn Mod 10) * (n + 1)) = mah(j, k)
        Next
      Next
      cn = cn + 1
    End If
If文によって、

   0
0  0 1 2
   
1  3 4 5
     
2  6 7 8
     



に飛び、
  For i = 0 To n * n - 1
    mah(b, a) = i + 1
から、

   0
0  0 1 2
   
1  3 4 5
   
2  6 7 8
     


となりますが、数字重複検査
    If g > 0 Then
      For j = 0 To g - 1
        If mah(b, a) = mah(y(j), x(j)) Then GoTo tobi
      Next
    End If
に抵触してGoTo tobiが実行され、Nextにより、

   0
0  0 1 2
   
1  3 4 5
   
2  6 7 8
     


今回は、重複検査をクリアします。
2は1,5,9のいずれとも重複しないからです。

















合計検査
    If a = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(b, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If b = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, a)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = n - 1) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
    If (a = 0) And (b = n - 1) Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(j, n - 1 - j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
にはすべて該当しませんので、
    If g + 1 < n * n Then
      ms (g + 1)
    Else
      For j = 0 To n - 1
        For k = 0 To n - 1
          Cells(6 + j + Int(cn / 10) * (n + 1), 1 + k + (cn Mod 10) * (n + 1)) = mah(j, k)
        Next
      Next
      cn = cn + 1
    End If
If文によって、

   0
0  0 1 2
   
1  3 4 5
   
2  6 7 8
     


の次元世界に飛翔し、
  For i = 0 To n * n - 1
    mah(b, a) = i + 1
により、

   0
0  0 1 2
   
1  3 4 5
 
2  6 7 8
     


となりますが、
もちろん重複検査
    If g > 0 Then
      For j = 0 To g - 1
        If mah(b, a) = mah(y(j), x(j)) Then GoTo tobi
      Next
    End If
によってチェックされ、

  For i = 0 To n * n - 1
    mah(b, a) = i + 1
から

   0
0  0 1 2
   
1  3 4 5
 
2  6 7 8
     


となりますが、再び
    If g > 0 Then
      For j = 0 To g - 1
        If mah(b, a) = mah(y(j), x(j)) Then GoTo tobi
      Next
    End If
をクリアできず、

   0
0  0 1 2
   
1  3 4 5
 
2  6 7 8
     





















となり、ようやく重複検査を通ります。
合計検査は一切関係ありませんので、
    If g + 1 < n * n Then
      ms (g + 1)
によって、

   0
0  0 1 2
   
1  3 4 5
 
2  6 7 8
     


に跳躍し、

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


セル番号
と重複し

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


今度は、セル番号
と重複します。

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     





















でようやく重複検査に合格しますが、横合計検査
    If a = n - 1 Then
      w = 0
      For j = 0 To n - 1
        w = w + mah(b, j)
      Next
      If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
    End If
を通り抜けることが出来ません。

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


重複検査に抵触し

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


横合計検査をパスできず、
以下、重複検査と横合計テストに何度もチェックされながら

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     





















   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


・・・

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


となり、重複検査に障り、

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     


・・・

   0
0  0 1 2
   
1  3 4 5
2  6 7 8
     



















ここまで来てはじめて重複テストと横合計検査をクリアします。


第6話へ 第8話へ

004
  


VBA講義第1部へ
vc++講義へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ

数学研究室に戻る