第5講 4次魔方陣と6次魔方陣の作成
第5話 謎に満ちた4次魔方陣作成コードの解凍

4次魔方陣作成のコードの主要部分再掲
Private Sub CommandButton1_Click()
         ・
  For i = 0 To 1 '対角線部分を交換する
    w = Cells(11 - i, 5 - i)
    Cells(11 - i, 5 - i) = Cells(8 + i, 2 + i)
    Cells(8 + i, 2 + i) = w
  Next
         ・
  For i = 0 To 1 '逆対角線部分を交換する
    w = Cells(16 - i, 2 + i)
    Cells(16 - i, 2 + i) = Cells(13 + i, 5 - i)
    Cells(13 + i, 5 - i) = w
  Next
  Cells(17, 2) = "4次魔方陣の完成!"
End Sub


解説
きっと皆さんの頭の中は大混乱でしょう。
謎を解凍するために、
  For i = 0 To 1 '逆対角線部分を交換する
    w = Cells(16 - i, 2 + i)
    Cells(16 - i, 2 + i) = Cells(13 + i, 5 - i)
    Cells(13 + i, 5 - i) = w
  Next
について、トレース(くどいですが、コンピュータの動きを追うことです)してからミソを解説しましょう。

トレース
 i = 0 の場合
    w = Cells(16 - i, 2 + i)
    Cells(16 - i, 2 + i) = Cells(13 + i, 5 - i)
    Cells(13 + i, 5 - i) = w
 は
    w = Cells(16 - 0, 2 + 0)
    Cells(16 - 0, 2 + 0) = Cells(13 + 0, 5 - 0)
    Cells(13 + 0, 5 - 0) = w
 から
    w = Cells(16, 2)
    Cells(16 , 2) = Cells(13, 5)
    Cells(13 , 5) = w
 となり、
 011 
 012 
 が交換され、
 011
 013
 となります。
 i = 1 の場合
    w = Cells(16 - i, 2 + i)
    Cells(16 - i, 2 + i) = Cells(13 + i, 5 - i)
    Cells(13 + i, 5 - i) = w
 は
    w = Cells(16 - 1, 2 + 1)
    Cells(16 - 1, 2 + 1) = Cells(13 + 1, 5 - 1)
    Cells(13 + 1, 5 - 1) = w
 から
    w = Cells(15, 3)
    Cells(15 , 3) = Cells(14, 4)
    Cells(14 , 4) = w
 となり、
 011
 041
 が交換され
 011
 042
 となります。
以上によって4次魔方陣が完成するわけですが、
それでも皆さんの頭には?がたくさん浮かんでいますよね。
043
の場合の対角線の座標を見ていると
(1,1),(2,2),(3,3),(4,4)
です。
ですから、対角線上を動かしたければ
  For i = 1 To 4
    Cells(i, i) = *
  Next
とすればよいのです。

次に逆対角線の場合
044
の座標を見ると
(1,4),(2,3),(3,2),(4,1)
です。
この動きをFor文で実現するには、どうしたらよいでしょうか。
皆さんに考えていただくために、
30行下に答えを示します。


















044
の座標を見ると
(1,4),(2,3),(3,2),(4,1)
の実現
  For i = 1 To 4
    Cells(i, 5 - i) = *
  Next

For文は0から始めた方がよいので、
043
044
それぞれのコードを書き直してみると
  For i = 0 To 3
    Cells(1 + i, 1 + i) = *
  Next
  For i = 0 To 3
    Cells(1 + i,
4 - i) = *
  Next
となります。
0からはじめると、
  For i = 1 To 4
    Cells(i, i) = *
  Next
  For i = 1 To 4
    Cells(i, i) = *
  Next
よりすっきりしていませんか。
今は4次魔方陣を例にしていますが、
汎用性を考えれば4の部分をnにした方がよいので、
  For i = 0 To n - 1
    Cells(1 + i, 1 + i) = *
  Next
  For i = 0 To n - 1
    Cells(1 + i,
n - i) = *
  Next
0から始めた方がすっきりするのはピンクです。
4次のときは4ですし、6次なら6、n次ならnです。
ですが、本当は
  For i = 0 To n - 1
    Cells(1 + i,
n - i) = *
  Next

  For i = 0 To n - 1
    Cells(1 + i,
1 + (n - 1) - i) = *
  Next
と考えた方がよりすっきりします。
For文の最後が(n - 1)ですから。
044
  For i = 0 To n - 1
    Cells(
1 + i, 1 + (4 - 1) - i) = *
  Next
がわかれば、
011
051
と動かすことも簡単です。
先頭の位置が(
)から(13)になるだけですから、
  For i = 0 To 3
    Cells(
13 + i, 2 + (4 - 1) - i) = *
  Next
(※色対応に注意!
  
   For i = 0 To n - 1
     Cells(1 + i, 1 + (4 - 1) - i) = *
   Next
  13
   For i = 0 To 3
     Cells(13 + i, 2 + (4 - 1) - i) = *
   Next
してください。)
すなわち
  For i = 0 To 3
    Cells(13 + i, 5 - i) = *
  Next
です。
  For i = 0 To 1 '逆対角線部分を交換する
    w = Cells(16 - i, 2 + i)
    Cells(16 - i, 2 + i) =
Cells(13 + i, 5 - i)
    Cells(13 + i, 5 - i) = w
  Next
部分に対応します。

数独自動生成は魔方陣を応用すればすぐに出来ます。
私が全国でもいち早く数独の自動生成に成功できた理由は、
魔方陣を研究していたからです。

さて、次は6次魔方陣の作成ですが、
これも順を追って実現していきます。
皆さん次の添付ファイル
参考ダウンロード添付ファイル
を開いて
052
Private Sub CommandButton1_Click()
  CommandButton2_Click
  Dim i As Byte, j As Byte, n As Byte
  n = 6 '汎用的にするめにnとした。

End Sub
Private Sub CommandButton2_Click()
  Rows("3:2000").Select
  Selection.ClearContents
  Cells(1, 1).Select
End Sub
VBAの空白部分を埋めて、
081
を実現してください。

第4話へ 第6話へ


トップへ