第16講 全セルリスト構造解析(全体リスト構造解析)によって数独(ナンプレ)を解く
第9話 別解の存在を確認するプログラム

プログラム訂正箇所
Sub f(g As Byte)
  
  Dim i As Byte, j As Byte, k As Byte
  Dim y As Byte, x As Byte
  
  y = Int(g / 9)
  x = g Mod 9
  
  If mah(y, x) > 0 Then
    If g + 1 < 81 Then
      f (g + 1)
    Else
      cn = cn + 1
      hyouji
      If cn = 1 Then Exit Sub  (2014/12/07訂正)
    End If
    Exit Sub
  End If
  If mah(y, x) = 0 Then
    For i = 0 To mx(y, x) - 1
      mah(y, x) = lst(y, x, i)
      For j = 0 To 8
        If j <> x Then
          If mah(y, x) = mah(y, j) Then GoTo tobi
        End If
      Next
      For j = 0 To 8
        If j <> y Then
          If mah(y, x) = mah(j, x) Then GoTo tobi
        End If
      Next
      For k = 0 To 2
        For l = 0 To 2
          If y <> 3 * Int(y / 3) + k And x <> 3 * Int(x / 3) + l Then
            If mah(y, x) = mah(3 * Int(y / 3) + k, 3 * Int(x / 3) + l) Then GoTo tobi
          End If
        Next
      Next
      If g + 1 < 81 Then
        f (g + 1)
      Else
        cn = cn + 1
        hyouji
      End If
tobi:
    Next
  End If
  mah(y, x) = 0
  
End Sub

訂正箇所は、
         ・
  If mah(y, x) > 0 Then
    If g + 1 < 81 Then
      f (g + 1)
      
If cn = 1 Then Exit Sub
    Else
      cn = cn + 1
      hyouji
      If cn = 1 Then Exit Sub
    End If
    Exit Sub
  End If
  If mah(y, x) = 0 Then
    For i = 0 To mx(y, x) - 1
      mah(y, x) = lst(y, x, i)
      For j = 0 To 8
        If j <> x Then
          If mah(y, x) = mah(y, j) Then GoTo tobi
        End If
      Next
      For j = 0 To 8
        If j <> y Then
          If mah(y, x) = mah(j, x) Then GoTo tobi
        End If
      Next
      For k = 0 To 2
        For l = 0 To 2
          If y <> 3 * Int(y / 3) + k And x <> 3 * Int(x / 3) + l Then
            If mah(y, x) = mah(3 * Int(y / 3) + k, 3 * Int(x / 3) + l) Then GoTo tobi
          End If
        Next
      Next
      If g + 1 < 81 Then
        f (g + 1)
        
If cn = 1 Then Exit Sub
      Else
        cn = cn + 1
        hyouji
      End If
tobi:
    Next
  End If
  mah(y, x) = 0
        ・
3カ所If cn = 1 Then Exit Subを削っただけです。


参考ファイル7


実行画面
数独


別解がないかを確認すると、確認しない場合よりかなり時間がかかります。
市販されている数独(ナンプレ)は、別解のない適正な問題ですから、
If cn = 1 Then Exit Subは入れておきましょう。
If cn = 1 Then Exit Subを削らなければならない場面は、
数独の問題作成ソフトの開発において現れます。
数独(ナンプレ)のルールに基づいて、適当に数字を配置していっても、
ほとんどの場合は、解が存在しないか、複数解が存在するものになってしまいます。
作った問題が適正なものであるか調べるために、
解が複数個存在しないかのチェックは必然です。

ところで、皆さん実は適正な数独の問題を解くときには、
Sub syokika()

  Dim i As Byte, ja As Byte, k As Byte
  
  cn = 0
  For i = 0 To 8
    For j = 0 To 8
      For k = 0 To 8
        h(i, j, k) = 1
        
lst(i, j, k) = k + 1
      Next
    Next
  Next
  
End Sub
lst(i, j, k) = k + 1には、
全く意味がなかったことにお気づきだったでしょうか。
2つのcellskaiseki
Sub cellkaiseki1(i As Byte, j As Byte)
  
  Dim k As Byte, l As Byte
  
  For k = 0 To 8
    If mah(i, k) > 0 Then h(i, j, mah(i, k) - 1) = 0
  Next
  
  For k = 0 To 8
    If mah(k, j) > 0 Then h(i, j, mah(k, j) - 1) = 0
  Next
  
  
For k = 0 To 2
    For l = 0 To 2
      If 3 * Int(i / 3) + k <> i And 3 * Int(j / 3) + l <> j Then
        If mah(3 * Int(i / 3) + k, 3 * Int(j / 3) + l) > 0 Then h(i, j, mah(3 * Int(i / 3) + k, 3 * Int(j / 3) + l) - 1) = 0
      End If
    Next
  Next
   (2014/12/07訂正)


End Sub

Sub cellkaiseki2(i As Byte, j As Byte)
  
  Dim k As Byte, w As Byte
  
  w = 0
  For k = 0 To 8
    If h(i, j, k) = 1 Then
      lst(i, j, w) = k + 1
      w = w + 1
    End If
  Next
  mx(i, j) = w
  For k = 0 To 8
    If h(i, j, k) = 0 Then
      lst(i, j, w) = k + 1
      w = w + 1
    End If
  Next
  
End Sub
で結局最初から、リストを作り直しているからです。
リストを{1,2,3,4,5,6,7,8,9}とする作業は、
全く無意味な作業でした。
では、何故入れてあるのでしょうか。
理由は、2つあります。
数独自動生成ソフトには、2つの方式があります。
1つ目の方式は、すでにこの話において説明した方式です。
もうひとつの方式は、ヒント数0の状態から答えを1つ作り、
空欄を作っていく方式です。
この2番目の方式のときに、
lst(i, j, w) = k + 1で初期化しておく必要があるのです。

第16講最後の課題です。
  If mah(y, x) = 0 Then
    For i = 0 To mx(y, x) - 1
      mah(y, x) = lst(y, x, i)
の部分を
  If mah(y, x) = 0 Then
    For i = 1 To 9
      mah(y, x) = i
と変更するとどうなるか、確認してみて下さい。
つまり、全セル構造解析を使わないとどうなるかという確認作業です。




第8話へ 第10話へ



トップ

初心者のためのc++ vc++ c言語 入門 基礎から応用までへ
初心者のための excel 2007 2010 2013 vba マクロ 入門 基礎から応用まで
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
vb講義トップへ
VB講義基礎へ
専門用語なしのC++入門へ
専門用語なしのJava入門へ
専門用語なしのVBA入門

数独のページ
魔方陣のページ
数学研究室に戻る
本サイトトップへ