第2講 試行錯誤法でヒント数0数独の解答を作る(1)
第8話 n次疑似疑似魔方陣の生成

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, 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 Then '重複検査と横合計検査をパスした場合に次のセル(箱)番号の世界に飛ぶ。
      If g + 1 < n * n Then 'ただし、セル(箱)番号がn * n - 1以下のとき
        f (g + 1)
      Else
        For j = 0 To n * n - 1 'セル(箱)番号が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
参考ダウンロード添付ファイル

さて、次は列合計の条件も満たす疑似魔方陣の生成です。
列合計のタイミングは
002
の色のついているところです。
ここには2つ克服すべき課題があります。
1つは、色の場所をいかに見つけるかです。
もう一つは、
8+6+1
3+7+5
4+2+9
をいかに実現するかです。
セル番号の観点でいうと、

0 1 2
3 4 5
6 7 8

いかにして6,7,8を見つけて、
いかにして
6→3→0
7→4→1
8→5→2
と動かすかです。
6,7,8を見つけるにはIntを使います。
6→3→0
7→4→1
8→5→2は3ずつ動いていることがヒントです。
nであればnずつですよ。
003




第7話へ 第9話へ


トップへ