第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
となり、
が交換され、
となります。
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
となり、
が交換され
となります。
以上によって4次魔方陣が完成するわけですが、
それでも皆さんの頭には?がたくさん浮かんでいますよね。
の場合の対角線の座標を見ていると
(1,1),(2,2),(3,3),(4,4)
です。
ですから、対角線上を動かしたければ
For i = 1 To 4
Cells(i, i) = *
Next
とすればよいのです。
次に逆対角線の場合
の座標を見ると
(1,4),(2,3),(3,2),(4,1)
です。
この動きをFor文で実現するには、どうしたらよいでしょうか。
皆さんに考えていただくために、
30行下に答えを示します。
の座標を見ると
(1,4),(2,3),(3,2),(4,1)
の実現
For i = 1 To 4
Cells(i, 5 - i) = *
Next
For文は0から始めた方がよいので、
それぞれのコードを書き直してみると
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)ですから。
For i = 0 To n - 1
Cells(1 + i, 1 + (4 - 1) - i) = *
Next
がわかれば、
と動かすことも簡単です。
先頭の位置が(1,1)から(13,2)になるだけですから、
For i = 0 To 3
Cells(13 + i, 2 + (4 - 1) - i) = *
Next
(※色対応に注意!
(1,1)
For i = 0 To n - 1
Cells(1 + i, 1 + (4 - 1) - i) = *
Next
(13,2)
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次魔方陣の作成ですが、
これも順を追って実現していきます。
皆さん次の添付ファイル
参考ダウンロード添付ファイル
を開いて
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の空白部分を埋めて、
を実現してください。
第4話へ 第6話へ