第19講 対角線法による魔方陣自動生成ソフトの高速化
第5話 対角線を先に入力する!
を実現するプログラム例
Dim a(10, 10) As Byte, n As Byte, cn As Long, y(100) As Byte, x(100) As Byte
Private Sub CommandButton1_Click()
CommandButton2_Click
cn = 0
n = Cells(4, 2)
Call zy
Call f(0) 'n次魔方陣作成プロシージャ
End Sub
Sub zy()
Dim i As Byte, j As Byte, k As Byte
Dim b(10, 10) As Byte
For i = 0 To n - 1
For j = 0 To n - 1
b(i, j) = n * n + 1
Next
Next
For i = 0 To n - 1
b(i, i) = i
Next
k = n
For i = 0 To n - 1
If b(i, n - 1 - i) = n * n + 1 Then
b(i, n - 1 - i) = k
k = k + 1
End If
Next
For i = 0 To n - 1
For j = 0 To n - 1
If b(i, j) = n * n + 1 Then
b(i, j) = k
k = k + 1
End If
Next
Next
For i = 0 To n - 1
For j = 0 To n - 1
y(b(i, j)) = i
x(b(i, j)) = j
Next
Next
End Sub
Sub f(g As Byte)
Dim i As Byte, j As Byte, w As Byte
For i = 1 To n * n
If g > 0 Then
For j = 0 To g - 1
If i = a(y(j), x(j)) Then GoTo tobi
Next
End If
a(y(g), x(g)) = i
' If x = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(y, j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, x)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If x = 0 And y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, n - 1 - j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
' If x = n - 1 And y = n - 1 Then
' w = 0
' For j = 0 To n - 1
' w = w + a(j, j)
' Next
' If w <> Int(n * (n * n + 1) / 2) Then GoTo tobi
' End If
If g + 1 < n * n Then
Call f(g + 1)
If cn = 1 Then Exit Sub
Else
Call h
If cn = 1 Then Exit Sub
End If
tobi:
Next
End Sub
Sub h()
Dim i As Byte, j As Byte, s As Byte, am As Byte, w As Byte
For i = 0 To n * n - 1
s = Int(i / n)
am = i Mod n
Cells(6 + s + (n + 1) * Int(cn / 5), 2 + am + (n + 1) * (cn Mod 5)) = a(s, am)
Next
cn = cn + 1
tobi:
End Sub
Private Sub CommandButton2_Click()
Rows("5:20000").Select
Selection.ClearContents
Cells(1, 1).Select
End Sub
参考ダウンロード添付ファイル
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
白い数字とy座標(表の赤)とx座標(表の青)が関連づけは、
For i = 0 To n - 1
For j = 0 To n - 1
y(b(i, j)) = i
x(b(i, j)) = j
Next
Next
によってできます。
私には全く思いもおよばない見事な方法です。
例えば、i = 4 j = 1 のときb(4,1)は22です。
ですから、
y(22) = 4
x(22) = 1
で確かに逆対応が出来ていますね。
仮屋崎さん実にお見事です。
では、保留しておいた、
行合計・列合計・対角線合計の各検査を復活させましょう。
検査を行う場所は、
0 | 1 | 2 | 3 | 4 | |
0 | 0 | 9 | 10 | 11 | 5 |
1 | 12 | 1 | 13 | 6 | 14 |
2 | 15 | 16 | 2 | 17 | 18 |
3 | 19 | 7 | 20 | 3 | 21 |
4 | 8 | 22 | 23 | 24 | 4 |
と色のついている部分です。
対角線から先に入れることによって、
大変高速化しますが、
その分プログラムは複雑になってしまいます。
ですが、ここまでついて優秀な皆さんなら、
出来るはずです。
頑張りましょう。
この工夫によって、
5次魔方陣ならおそらく数千倍クラス、
6次魔方陣であれば数万倍クラスの高速化が実現しますが、
それでも、6次魔方陣には歯が立ちませし、
5次魔方陣をすべて生成させようとしたら、
宇宙時間ほどかかります。
ですから、nの入力は5次までとして、
4次のときは100個、
5次のときは50個、
魔方陣が生成できたときには、
プログラムを止めるようにしましょう。
また、時間計測機能も付け加え、
生成された魔方陣個数も表示しましょう。
魔方陣の個数は、終わってから表示するのではなく、
出来る度にリアルタイムに表示して途中経過が分かるようにしましょう。
eclipse c++ 入門
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
vc++講義へ
excel 2013 2010 2007 vba入門へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
専門用語なしの C言語 C++ 入門(Visual C++ 2010で学ぶ C言語 C++ 入門)
専門用語なしの excel vba マクロ 入門 2013 2010 2007 対応講義 第1部
eclipse java 入門へ
excel 2016 vba 入門へ
小学生からエンジニアまでのRuby入門へ
本サイトトップへ