第6講 数独を作ろう!
第3話 ラテン方陣解答例
ラテン方陣解答例

プログラムソースは
Sub sakusei(g As Integer)
  Dim i, j, k, l, hh, wa As Integer
  j = g Mod n
  i = Int(g / n)

  For k = 1 To n
    mah(i, j) = k
    
If j > 0 Then
      For l = 0 To j - 1
        If mah(i, l) = mah(i, j) Then GoTo owari
      Next
    End If
    If i > 0 Then
      For l = 0 To i - 1
        If mah(l, j) = mah(i, j) Then GoTo owari
      Next
    End If


    If g + 1 < n * n Then
      sakusei (g + 1)
    Else
      cn = cn + 1
      hyouji
    End If
owari:
  Next
  mah(i, j) = 0
End Sub
今回の改善点はピンクが加えられ、順列方陣の
hh = 0
If tyouhukuhantei(k - 1) = 1 Then GoTo owari
tyouhukuhantei(k - 1) = 1

hh = 1

If g + 1 < n * n Then
  sakusei (g + 1)
Else
  cn = cn + 1
  hyouji
End If
owari:
If hh = 1 Then tyouhukuhantei(k - 1) = 0
の青または紺の部分が削られていることです。
順列方陣では同じ数字が
方陣の中にあってはいけないので、
青の記述が必要でした。
1からnまでの数字は1個ずつしかないのです。
それに対してラテン方陣では、n次なら同じ数字がn個ずつありますから
紺の記述は

hh = 0
If tyouhukuhantei(k - 1) < n Then GoTo owari
tyouhukuhantei(k - 1) = tyouhukuhantei(k - 1) + 1

hh = 1

If g + 1 < n * n Then
  sakusei (g + 1)
Else
  cn = cn + 1
  hyouji
End If
owari:
If hh = 1 Then tyouhukuhantei(k - 1) = tyouhukuhantei(k - 1) ー 1
のように変更しなければならないと思うかも知れませんが、
    If j > 0 Then
      For l = 0 To j - 1
        If mah(i, l) = mah(i, j) Then GoTo owari
      Next
    End If
    If i > 0 Then
      For l = 0 To i - 1
        If mah(l, j) = mah(i, j) Then GoTo owari
      Next
    End If

がありますので、青や紺の部分はいらないのです。
列にも行にも同じ数字が並ばないときは、
1からnまでの各数字は、
n個を超えることはないからです。
例えば、9次ラテン方陣で1から7までは9個ずつで、
8は8個で9は10個あるとすると、
9は必ずどこかの行(または列)において必ず2個出てきてしまうからです。
1から9までの数字が丁度9個ずつあるときのみ、
各列にも各行にも同じ数字が並ばないというラテン方陣の条件を満たすのです。
ですから、ピンクがあれば青または紺の記述は必要なくなります。
したがって、配列tyouhukuhantei(400)も必要なくなり
Sub syokika()
  Dim i As Integer
  For i = 0 To n * n - 1
    tyouhukuhantei(i) = 0
  Next
End Sub
の記述も丸ごと削られています。

さて、いよいよこのラテン方陣解答例を改良して数独を作りましょう。

第2話へ 第4話へ

VB入門講義応用編トップへ

VB入門講義トップへ