第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 | 
ができあがるのです。