第3講 第2講の魔方陣を高速化しよう!
第5話 再帰的呼び出しプログラムのソースは?
再帰的呼び出しプロシージャは、第2講で作ったプログラム
魔方陣プログラム1
を少し改善するだけで済みます。
0 | 1 | 2 | 3 | |
0 | 0 | 1 | 2 | 3 |
1 | 4 | 5 | 6 | 7 |
2 | 8 | 9 | 10 | 11 |
3 | 12 | 13 | 14 | 15 |
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 12 |
2 | 11 | 6 | 2 | 14 |
3 | 7 | 13 | 15 | 3 |
3は対角線合計
7は逆対角線合計
9は第0行目合計
11は第0列目合計
12,14は行合計
13,15は列合計
がn×(n×n+1)÷2になっていることを確認すればいいのです。
したがって、プログラムソースは
If i = n - 1 And j = n - 1 Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(l, l)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
If i = n - 1 And j = 0 Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(l, n - 1 - l)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
If j = n - 2 And i = 0 Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(i, l)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
If i = n - 2 And j = 0 Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(l, j)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
If j = n - 1 And g > 2 * n Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(i, l)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
If i = n - 1 And g > 2 * n Then
wa = 0
For l = 0 To n - 1
wa = wa + mah(l, j)
Next
If wa <> Int(n * (n * n + 1) / 2) Then GoTo owari
End If
とすればよいので。以上のようにして改良プログラムができあがります。
魔方陣プログラム2
この改良によって5次まで作成できるようになります。
前作ではPentium4(2.80GHz)で2,3時間かけても1個もできなかったのに対して、
1分で83個ぐらいできるようになります。
5次の時点で作成速度は1万倍を遙かに超えるほど速くなっていると予測することができます。
(実験したことはありませんが、おそらく前作だと10時間かけても1個もできないと思われます。)
ところが、6次だと10万倍を遙かに超えるほど速くなっていると予想できますが、
それでもこのプログラムでは6次を1個作り出すには、
何時間(何十時間?)もかかってしまいます。
このプログラムは5次が限界といえます。
しかし、このプログラムをまたほんの少し改良するだけで、
1個目の6次魔方陣を1秒で作り出せるようになります。
その改良は前回以上に本当に小さな改良です。
次回はそれを語りましょう。