第2講 試行錯誤法でヒント数0数独の解答を作る(1)
第7話 n次順列をSubプロシージャで自動生成させる

001

を実現させるプログラム例
Dim n As Byte, x(15) As Byte, cn As Integer 'nは順列次数 x(15)は順列を収納する配列 cnは生成された順列総数
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, h As Byte, a As Integer, s As Integer
  a = cn Mod 10 '生成された順列総数を10で割った余り
  s = Int(cn / 10) '生成された順列総数を10割った商
  For i = 0 To n - 1
    x(g) = i + 1 'セル(箱)番号gのセル(箱)に1からnまでを代入、i + 1が箱の中身に相当
    h = 1
    If g > 0 Then 'セル(箱)番号が0より大きいときに、過去と重複がないかを調べ、重複があるときは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 Then 'hが1のときは重複がないので、次のセル(箱)番号の世界へ飛ぶ。
      If g + 1 < n Then 'ただし、g + 1がn - 1以下の範囲内のとき
        f (g + 1)
      Else 'g + 1 = n - 1のときは、順列が完成しているので表示して、順列総数を1つ加えている。
        For j = 0 To n - 1
          Cells(4 + s, 1 + (n + 1) * a + j) = 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
参考ダウンロード添付ファイル

次の課題は、3次魔方陣や4次魔方陣を生成することですが、
いきなりでは難しいので行合計(横合計)の同じものだけを生成させるという課題に限定しましょう。
ここでもあたらい言葉を導入しておきます。
行合計の条件だけ満たすものを疑似疑似魔方陣、
列合計の条件も満たすものを疑似魔方陣と呼ぶことにします。
つまり、今回の課題は疑似疑似魔方陣を生成することです。
002
開発のためのヒントは、n次魔方陣であればn*nを使うということです。
つまり、
  For i = 0 To n - 1

      If g + 1 < n Then
の2文には変更が必要となります。
さらに、横合計を求めさせるタイミングは、
003
色の塗ってあるところです。
これをいかに実現するかです。
modをうまく使ってこのタイミングで横合計をさせてください。
n次魔方陣の横合計は
n*(n*n+1)/2
です。
なぜなら、1からn*nまでの和(1+2+3+・・・+n*n)が
n*n*(n*n+1)/2
であるからです。
全体の合計を行数のnで割っているわけです。






第6話へ 第8話へ


トップへ