第10講 プロシージャの再帰的使用による魔方陣の自動生成
第6話 魔方陣の各値を入力する配列を2次元に変更
魔方陣の各値を入力する配列を2次元に変更したコード例
Module Module1
Dim cn, mah(5, 5), n As Integer
Sub Main() '私は社長だ。
Console.WriteLine ("これはすべてのn次方陣を求めるソフトです。")
Console.WriteLine ("何次の方陣を発生させるのかをnに入力し")
Console.WriteLine ("エンターするとn次方陣がすべて生成されます。")
Console.Write ("n=")
n = Console.ReadLine()
cn = 0
Dim hj, ow As Object
hj = Timer
f (0)
ow = Timer
Console.WriteLine("魔方陣生成にかかった時間は{0:f6}秒です。", ow - hj)
Console.WriteLine("生成された{0:d}次方陣は{1:d}個です。", n, cn)
End Sub
Sub f(g As Integer)
Dim i, j, k, h, hh, w, x, y As Integer
y = Int(g / n)
x = g Mod n
For i = 0 To n * n - 1
If g = 0 Then mah(y, x) = i + 1
h = 1
If g > 0 Then
For j = 0 To g - 1
If mah(Int(j / n), j Mod n) = i + 1 Then
h = 0
Exit For
End If
Next
If h = 1 Then mah(y, x) = i + 1
End If
If h = 1 Then
If g + 1 < n * n Then
f (g + 1)
Else
hh = 1
For j = 0 To n - 1
w = 0
For k = 0 To n - 1
w += mah(j, k)
Next
If w <> Int(n * (n * n + 1) / 2) Then
hh = 0
Exit For
End If
Next
If hh = 1 Then
For j = 0 To n - 1
w = 0
For k = 0 To n - 1
w += mah(k, j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
hh = 0
Exit For
End If
Next
End If
If hh = 1 Then
w = 0
For j = 0 To n - 1
w += mah(j, n - 1 - j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
hh = 0
Exit For
End If
End If
If hh = 1 Then
w = 0
For j = 0 To n - 1
w += mah(j, j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
hh = 0
Exit For
End If
End If
If hh = 1 Then
cn += 1
For j = 0 To n - 1
For k = 0 To n - 1
Console.Write("{0:d} ", mah(j, k))
Next
Console.WriteLine()
Next
Console.WriteLine()
End If
End If
End If
Next
End Sub
End Module
実行結果例
これはすべてのn次魔方陣を求めるソフトです。
何次の魔方陣を発生させるのかをnに入力し
エンターするとn次魔方陣がすべて生成されます。
n=3
2 7 6
9 5 1
4 3 8
2 9 4
7 5 3
6 1 8
4 3 8
9 5 1
2 7 6
4 9 2
3 5 7
8 1 6
6 1 8
7 5 3
2 9 4
6 7 2
1 5 9
8 3 4
8 1 6
3 5 7
4 9 2
8 3 4
1 5 9
6 7 2
魔方陣生成にかかった時間は1.031290秒です。
生成された3次魔方陣は8個です。
配列が1次元のときは
魔方陣生成にかかった時間は0.203130秒です。
生成された3次魔方陣は8個です。
でしたから、かえって遅くなっていますが、
配列を2次元に変更したことによって、
4次魔方陣全生成が私の旧式のパソコンでさえ11分程度で出来るようになる途が開かれるのです。
もちろん、1次元配列のままでも可能ですが、
コードがかなり難しくなります。
今話や前話のままではおそらく10時間ぐらいはかかる全生成が11分程度になる改良とは、
なんだかわかりますか。ヒントを次話でお話します。
尚、
w += mah(j, n - 1 - j)
もわかりにくいと思いますので、
トレースしておきましょう。
n = 3 を前提にトレースします。
j = 0 とき、
w += x(0 , 3 - 1 - 0)
w += x(0, 2)
j = 1 とき、
w += x(1 , 3 - 1 - 1)
w += x(1, 1)
j = 2 とき、
w += x(2 , 3 - 1 - 2)
w += x(2, 0)
ですから、
0 | 1 | 2 | |
0 | 0 | 1 | 2 |
1 | 3 | 4 | 5 |
2 | 6 | 7 | 8 |
(色を対応させています。ピンクy座標、紺x座標、白赤はg)
今回も見事に逆対角線上を動いています。
第5話へ 第7話へ
初心者のための excel 2016 マクロ VBA 入門講義 基礎から応用まで
vc** c言語 c** 入門 初心者 基礎から応用まで
eclipse c** 入門
魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C**入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC**による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
本サイトトップへ