第14講 末項確定法による魔方陣自動生成ソフトの高速化
第8話 魔方陣末項確定法自動生成ソフトの完成
コード全文
Private Sub CommandButton1_Click()
Dim n As Byte, cn As Integer, x(10, 10) As Byte
Dim iz(100) As Byte, jz(100) As Byte
Dim hajime As Variant, owari As Variant
Rows("5").Select
Selection.ClearContents
Range("A1").Select
hajime = Timer
n = Cells(3, 11)
cn = 0
Call zahyousakusei(n, iz(), jz())
' hyouji (n) '番号付けが上手くいっているかの確認 上手くいっていることが確認できたら'をつけて注釈文に変更する。
Call f(0, cn, n, x(), iz(), jz())
Cells(5, 14) = n '時間計測のため100個で止めるように変更してあるので、総数表示は意味がないので外している。
Cells(5, 15) = "次魔方陣は"
Cells(5, 20) = cn
Cells(5, 23) = "個存在しました。"
owari = Timer
Cells(5, 30) = "100個制作にかかった時間は"
Cells(5, 40) = owari - hajime
Cells(5, 44) = "秒です。"
End Sub
'Sub hyouji(n As Byte)
' Dim i As Byte, j As Byte, a(10, 10) As Byte
' For i = 0 To n * n - 1
' a(iz(i), jz(i)) = i
' Next
' For i = 0 To n - 1
' For j = 0 To n - 1
' Cells(6 + i, 2 + j) = a(i, j)
' Next
' Next
'End Sub
Sub zahyousakusei(n As Byte, iz() As Byte, jz() As Byte)
Dim i As Byte, j As Byte, a(10, 10) As Byte, c As Byte
For i = 0 To n - 1
For j = 0 To n - 1
a(i, j) = 128
Next
Next
For i = 0 To n - 1
a(i, i) = i
Next
c = n
For i = 0 To n - 1
If a(i, n - 1 - i) = 128 Then
a(i, n - 1 - i) = c
c = c + 1
End If
Next
For i = 0 To n - 1
For j = i To n - 1
If a(i, j) = 128 Then
a(i, j) = c
c = c + 1
End If
Next
For j = i To n - 1
If a(j, i) = 128 Then
a(j, i) = c
c = c + 1
End If
Next
Next
For i = 0 To n - 1
For j = 0 To n - 1
iz(a(i, j)) = i
jz(a(i, j)) = j
Next
Next
End Sub
Sub f(g As Byte, cn As Integer, n As Byte, x() As Byte, iz() As Byte, jz() As Byte)
Dim h As Byte, i As Byte, j As Byte, k As Byte, a As Byte, s As Integer, gi As Byte, gj As Byte
Dim ji As Byte, jj As Byte, hh As Byte, w As Byte
Dim ii As Byte, iii As Byte
a = cn Mod 10
s = Int(cn / 10)
gi = iz(g)
gj = jz(g)
ii = Int(n * n * Rnd)
If gi = 0 And gj = n - 2 Then
w = 0
For i = 0 To n - 3
w = w + x(0, i)
Next
w = w + x(0, n - 1)
w1 = Int(n * (n * n + 1) / 2) - w
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
For i = 0 To g - 1
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
x(gi, gj) = w1
Call f(g + 1, cn, n, x(), iz(), jz())
Exit Sub
End If
If gi = n - 2 And gj = 0 Then
w = 0
For i = 0 To n - 3
w = w + x(i, 0)
Next
w = w + x(n - 1, 0)
w1 = Int(n * (n * n + 1) / 2) - w
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
For i = 0 To g - 1
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
x(gi, gj) = w1
Call f(g + 1, cn, n, x(), iz(), jz())
Exit Sub
End If
If (gi > 0 And gi < n - 1) And gj = n - 1 Then
w = 0
For i = 0 To n - 2
w = w + x(gi, i)
Next
w1 = Int(n * (n * n + 1) / 2) - w
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
For i = 0 To g - 1
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
x(gi, gj) = w1
Call f(g + 1, cn, n, x(), iz(), jz())
Exit Sub
End If
If (gj > 0 And gj < n - 1) And gi = n - 1 Then
w = 0
For i = 0 To n - 2
w = w + x(i, gj)
Next
w1 = Int(n * (n * n + 1) / 2) - w
If w1 < 1 Then Exit Sub
If w1 > n * n Then Exit Sub
For i = 0 To g - 1
If w1 = x(iz(i), jz(i)) Then Exit Sub
Next
x(gi, gj) = w1
If g + 1 < n * n Then
Call f(g + 1, cn, n, x(), iz(), jz())
'If cn = 100 Then Exit Sub
Else
For j = 0 To n - 1
For k = 0 To n - 1
Cells(7 + j + (n + 1) * s, 2 + k + (n + 1) * a) = x(j, k)
Next
Next
cn = cn + 1
'If cn = 100 Then Exit Sub
End If
Exit Sub
End If
' If n = 4 Then kk = 3
' If n = 5 Then kk = 4
' If n = 6 Then kk = 7
' If n = 3 Then kk = 1
For i = 0 To n * n - 1
' iii = (ii + kk * i) Mod n * n
' x(gi, gj) = iii + 1
x(gi, gj) = i + 1
h = 1
If g > 0 Then
For j = 0 To g - 1
ji = iz(j)
jj = jz(j)
If x(ji, jj) = x(gi, gj) Then
h = 0
Exit For
End If
Next
End If
If h = 1 Then
If gj = n - 2 And gi = 0 Then
w = 0
For j = 0 To n - 1
w = w + x(gi, j)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If gj = n - 1 And gi > 0 And g > n Then
w = 0
For j = 0 To n - 1
w = w + x(gi, j)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If gi = n - 2 And gj = 0 Then
w = 0
For j = 0 To n - 1
w = w + x(j, gj)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If gi = n - 1 And gj > 0 And g > 2 * n Then
w = 0
For j = 0 To n - 1
w = w + x(j, gj)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If gi = n - 1 And gj = 0 Then
w = 0
For j = 0 To n - 1
w = w + x(j, n - 1 - j)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If gi = n - 1 And gj = n - 1 Then
w = 0
For j = 0 To n - 1
w = w + x(j, j)
Next
If w <> Int(n * (n * n + 1) / 2) Then h = 0
End If
End If
If h = 1 Then
If g + 1 < n * n Then
Call f(g + 1, cn, n, x(), iz(), jz())
'If cn = 100 Then Exit Sub
End If
End If
Next
End Sub
Private Sub CommandButton2_Click()
Rows("5:20000").Select
Selection.ClearContents
Range("A1").Select
End Sub
参考ファイル
魔方陣末項確定法自動生成ソフト
実験結果
第12講完成版
魔方陣末項確定法自動生成ソフト版
11/2.6≒4.2倍加しています。
実は、第15講に進もうと思って準備しているときに気がついたのですが、
まだ、 魔方陣末項確定法自動生成ソフトは完成していませんでした。
皆さんも気がついていましたか。
0 | 1 | 2 | 3 | |
0 | 0 | 8 | 9 | 4 |
1 | 10 | 1 | 5 | 11 |
2 | 12 | 6 | 2 | 13 |
3 | 7 | 14 | 15 | 3 |
0 | 9 | 10 | 11 | 5 |
12 | 1 | 13 | 6 | 14 |
15 | 16 | 2 | 17 | 18 |
19 | 7 | 20 | 3 | 21 |
8 | 22 | 23 | 24 | 4 |
濃紺の部分を忘れていました。
この部分を加えて、本当に完成させましょう。
初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門
数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ