第6講 4次魔方陣を作ってみよう。
第4話 4次魔方陣プログラムその2
第2話では、交換プログラムを使う4次魔方陣プログラムを考えましたが、
自然配列をExcel上に自然配列を残したまま、
交換プログラムを使わず4次魔方陣のプログラムを作ることもできます。
Private Sub CommandButton1_Click()
Dim i As Integer, j As Integer, w As Integer
For i = 1 To 4
For j = 1 To 4
Cells(i + 4, j + 2) = 4 * (i - 1) + j
Next
Next
For i = 1 To 4
Cells(i + 12, i + 2) = Cells(9 - i, 7 - i)
Cells(i + 12, 7 - i) = Cells(9 - i, i + 2)
For j = 1 To 4
If (i <> j And i <> 5 - j) Then Cells(i + 12, j
+ 2) = Cells(i + 4, j + 2)
Next
Next
Cells(17, 1) = "縦合計"
For i = 1 To 4
w = 0
For j = 1 To 4
w = w + Cells(j + 12, i + 2)
Next
Cells(17, i + 2) = w
Next
Range("g10:g12").Select
Selection.HorizontalAlignment = xlRight
Cells(10, 7) = "横"
Cells(11, 7) = "合"
Cells(12, 7) = "計"
Range("a1").Select
For i = 1 To 4
w = 0
For j = 1 To 4
w = w + Cells(i + 12, j + 2)
Next
Cells(i + 12, 7) = w
Next
Cells(18, 1) = "右斜め対角線合計"
w = 0
For i = 1 To 4
w = w + Cells(i + 12, i + 2)
Next
Cells(18, 5) = w
Cells(19, 1) = "左斜め対角線合計"
w = 0
For i = 1 To 4
w = w + Cells(i + 12, 7 - i)
Next
Cells(19, 5) = w
End Sub
今回の改良はピンクの部分です。
かなり難しいと思いますので、
1行ずつ解説したいと思います。
まず、
Cells(i + 12, i + 2) = Cells(9 - i, 7 - i)
は
3 | 4 | 5 | 6 | |
13 | 16 | 2 | 3 | 13 |
14 |
5 | 11 | 10 | 8 |
15 |
9 | 7 | 6 | 12 |
16 |
4 |
14 | 15 | 1 |
の部分を作り出しています。
i=1のとき右辺は
Cells(8, 6)ですから
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
16です。
そして、i=1のとき左辺は
Cells(13, 3)ですからCells(i + 12, i + 2) = Cells(9 - i, 7 - i)は
Cells(13, 3) = Cells(8, 6)
という命令で
3 | 4 | 5 | 6 | |
13 | 16 | |||
14 |
||||
15 |
||||
16 |
となります。
i=2のときは、
3 | 4 | 5 | 6 | |
13 | 16 | |||
14 |
11 | |||
15 |
||||
16 |
となります。
さらに、i=3で
3 | 4 | 5 | 6 | |
13 | 16 | |||
14 |
11 | |||
15 |
6 | |||
16 |
となります。さらに、i=4で
3 | 4 | 5 | 6 | |
13 | 16 | |||
14 |
11 | |||
15 |
6 | |||
16 |
1 |
となります。
Cells(i + 12, 7 - i) = Cells(9 - i, i + 2)については、
ご自分でトレースしてみてください。
If (i <> j And i <> 5 - j) Then Cells(i + 12, j + 2) = Cells(i
+ 4, j + 2)
の条件(i <> j And i <> 5 - j)は
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
の濃い緑の部分を指定しています。
Andは「かつ」を表します。
<>は≠です。
ですから、条件はi≠jかつi≠5−jを表しています。
Cells(i + 4, j + 2)においてi=jは
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
のピンクの部分を表します。
例えば、i=j=1ならCells(5, 3)ですから
01 |
ですよね。以下i=j=2ならCells(6, 4)で
06 |
i=j=3のときはCells(7, 5)で
11 |
i=j=4のときはCells(8, 6)で
16 |
というわけです。
わかりにくいのは、Cells(i + 4, j + 2)におけるi=5−jの場合だと思います。
この場合は、
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
のピンクの部分になります。
i=5−jでj=1とすると、i=4です。
このときCells(i + 4, j + 2)はCells(8, 3)ですから
13 |
を表します。
以下、j=2ならi=3でCells(i + 4, j + 2)はCells(7, 4)となり、
10 |
を表します。
ようするに、jが1,2,3,4と動いていくと、
Cells(i + 4, j + 2)は右上がりの対角線上に、13,10,7,4と動いていくことになります。
以上まとめると、i=jは
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
のピンクを、i=5−jは
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
のピンクを表しますから、
i=jでもなくi=5−jでもない状態は、
3 | 4 | 5 | 6 | |
5 | 1 | 2 | 3 | 4 |
6 |
5 | 6 | 7 | 8 |
7 |
9 | 10 | 11 | 12 |
8 |
13 |
14 | 15 | 16 |
の濃い緑ということになるわけです。結局、
If (i <> j And i <> 5 - j) Then Cells(i + 12, j + 2) = Cells(i
+ 4, j + 2)は、
上の濃い緑の部分を下へ8つずらしたところにコピーしなさいという命令になるのです。
For i = 1 To 4
Cells(i + 12, i + 2) = Cells(9 - i, 7 - i)
Cells(i + 12, 7 - i) = Cells(9 - i, i + 2)
For j = 1 To 4
If (i <> j And i <> 5 - j) Then Cells(i + 12, j + 2)
= Cells(i + 4, j + 2)
Next
Next
全体では、ピンクのところは逆順で、濃い緑のところは正順で8つ下のところにコピーさせる命令となり、
3 | 4 | 5 | 6 | |
13 | 16 | 2 | 3 | 13 |
14 |
5 | 11 | 10 | 8 |
15 |
9 | 7 | 6 | 12 |
16 |
4 |
14 | 15 | 1 |
ができあがるのです。