第2講 試行錯誤法でヒント数0数独の解答を作る(1)
第10話 n次魔方陣の生成
を実現させるプログラム例
Dim n As Byte, x(15) As Byte, cn As Integer 'nは魔方陣の次数、x(15)は魔方陣を収納する
Private Sub CommandButton1_Click()
CommandButton2_Click
n = Cells(3, 2)
cn = 0
f (0) 'n次魔方陣作成プロシージャ
End Sub
Sub f(g As Byte)
Dim i As Byte, j As Byte, k As Byte, h As Byte, a As Integer, s As Integer, w As Byte
a = cn Mod 10
s = Int(cn / 10) '以上の2行は生成された魔方陣を適切位置に表示するためのもの。
For i = 0 To n * n - 1
x(g) = i + 1
h = 1
If g > 0 Then '過去との重複を検査して重複がある場合にはhを0として以下の処理を行わせない。
For j = 0 To g - 1
If x(j) = x(g) Then
h = 0
Exit For
End If
Next
End If
If h = 1 And g Mod n = n - 1 Then '横合計検査、合計が1からn*nの合計÷nに等しくない場合にはhを0として以下の処理を行わせない。
w = 0
For j = 0 To n - 1
w = w + x(g - j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
h = 0
End If
End If
If h = 1 And Int(g / n) = n - 1 Then '縦合計検査、合計が1からn*nの合計÷nに等しくない場合にはhを0として以下の処理を行わせない。
w = 0
For j = 0 To n - 1
w = w + x(g - n * j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
h = 0
End If
End If
If h = 1 And Int(g / n) = n - 1 And (g Mod n) = 0 Then '対角線合計検査、合計が1からn*nの合計÷nに等しくない場合にはhを0として以下の処理を行わせない。
w = 0
For j = 0 To n - 1
w = w + x(g - (n - 1) * j)
Next
If w <> Int(n * (n * n + 1) / 2) Then
h = 0
End If
End If
If h = 1 And Int(g / n) = n - 1 And (g Mod n) = n - 1 Then '逆対角線合計検査、合計が1からn*nの合計÷nに等しくない場合にはhを0として以下の処理を行わせない。
w = 0
For j = 0 To n - 1
w = w + x(g - (n + 1) * 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 'ただし、セル(箱)番号がn * n - 1以下のとき
f (g + 1)
Else 'セル(箱)番号がn * n - 1のとき、魔方陣が完成しているので、表示して魔方陣総数をカウント
For j = 0 To n * n - 1
Cells(4 + Int(j / n) + (n + 1) * s, 1 + (j Mod n) + (n + 1) * a) = x(j)
Next
cn = cn + 1
End If
End If
Next
End Sub
Private Sub CommandButton2_Click()
Rows("4:200").Select
Selection.ClearContents
Cells(1, 1).Select
End Sub
参考ダウンロード添付ファイル
x(15)を1次元にしてしまったために、
横合計・縦合計・対角線合計を求めるタイミングが難しくなってしまいました。
本当はx(3, 3)の2次元配列にしておけば、
簡単だったのです。
そこで、2次元配列に変更してn次魔方陣を生成させますが、
講の話は10話以内するのが本サイトの方針ですので、
講を改めて第3講第1話の課題とします。