Access で数独を解く

  1. 初めに
  2. 概要
  3. 準備
    1. 「世界」と「要素」の構築
    2. まず、「要素」のテーブルを作成する。
      CREATE TABLE [要素](num integer primary key)
       値は1〜9の値はテーブルを開いて代入する。 続いて、「世界」を構築するが、そのためにまず軸を用意する。 1〜9なので手を抜いて。。。
      SELECT num as H INTO [縦軸] FROM [要素] CREATE INDEX [PK_縦軸] ON [縦軸](H) WITH PRIMARY SELECT num as V INTO [横軸] FROM [要素] CREATE INDEX [PK_横軸] ON [横軸](V) WITH PRIMARY
      エリアテーブルも作っておく。
      CREATE TABLE エリア(a integer PRIMARY KEY,hb integer,vb integer)
       エリアの a フィールドに1〜9の値をテーブルを開いて代入して ブロック分けをする。
      UPDATE エリア SET hb = (a-1)\3+1, vb = ((a-1) mod 3)+1
       そして「世界」を構築する。
      SELECT H, V, HB, VB, A INTO 世界 FROM エリア AS AR INNER JOIN [SELECT 縦軸.H, 横軸.V, (横軸.H+2)\3 AS HB, (縦軸.V+2)\3 AS VB FROM 横軸, 縦軸]. AS AX ON (AR.HB = AX.HB) AND (AR.VB = AX.VB); CREATE INDEX [PK_世界] ON [世界](H,V) WITH PRIMARY
      Subquery の表記が Access 独特になっている。入力は一般的な () で記述していたが、 保存したら ACCESS独特の [] になっていた。
      123
      123456789
      11            
      2  1   2   3 
      3            
      24            
      5  4   5   6 
      6            
      37            
      8  7   8   9 
      9            

    3. 「可能世界要素」と「可能世界表示」「可能世界要素マスタ」作成
    4.  可能世界要素の構成は単に「世界」と「要素」の外結合を行えば良い。
      SELECT 世界.*, 要素.num INTO 可能世界要素 FROM 世界, 要素; CREATE INDEX [PK_可能世界要素] ON [可能世界要素](H,V,num) WITH PRIMARY
      「可能世界要素」テーブルは解析をすすめるに従ってデータを削除するトランザクションテーブルである。  「可能世界要素」テーブルでは状態が分かりにくいので表示用のビューを作成する。 そのために「可能世界要素」とは別に「世界」×「要素」のマスタテーブル「可能世界要素マスタ」が必要となるので作成する。
      SELECT 世界.*, 要素.num INTO 可能世界要素マスタ FROM 世界, 要素; CREATE INDEX [PK_可能世界要素マスタ] ON [可能世界要素マスタ](H,V,num) WITH PRIMARY
       そして ACCESS の SQL の機能「クロス集計クエリ」を利用して「可能世界表示」の元になるクエリ「可能世界要素クロス表示」を作成する。
      TRANSFORM CStr(Nz(Max(可能世界要素.Num),'')) AS NumChar SELECT 可能世界要素マスタ.H, 可能世界要素マスタ.V FROM 可能世界要素マスタ LEFT JOIN 可能世界要素 ON (可能世界要素マスタ.H = 可能世界要素.H) AND (可能世界要素マスタ.V = 可能世界要素.V) AND (可能世界要素マスタ.num = 可能世界要素.num) GROUP BY 可能世界要素マスタ.H, 可能世界要素マスタ.V PIVOT 'N_' & [可能世界要素マスタ].[num];
      クロス集計クエリはサブクエリとして直接SQL に埋め込めないので上記のクエリを「可能世界要素クロス表示」で保存しておく。
       クロス集計クエリは横軸にくるフィールドがレコードに依存する。 それを固定するために「可能世界要素」を「可能世界要素マスタ」と結合する必要がある。
       「可能世界要素クロス表示」を基にして「可能世界表示」を作成する。
      TRANSFORM Max([:].NumList) AS NumListの最大 SELECT [:].H AS H\V FROM [SELECT 可能世界要素クロス表示.H, 可能世界要素クロス表示.V, N_1 & N_2 & N_3 & N_4 & N_5 & N_6 & N_7 & N_8 & N_9 AS NumList FROM 可能世界要素クロス表示 ]. AS [:] GROUP BY [:].H PIVOT [:].V;
      サブクエリのエイリアスは勝手につけられたものである。
       最新の RDB(Relational Database) はこういった MDB (Multidimensional Database) の機能を持っているが Access では比較的昔から「クロス集計クエリ」を実装していた。

      初期の「可能世界表示」は次のようになる。
      H\V 1 2 3 4 5 6 7 8 9
      1 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      2 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      3 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      4 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      5 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      6 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      7 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      8 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      9 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789

       「可能世界要素」テーブルの初期化のために二つのクエリを用意する。 まずは「可能世界要素クリア」。
      DELETE * FROM 可能世界要素;
       そして「可能世界要素初期化」。
      INSERT INTO 可能世界要素 SELECT * FROM 可能世界要素マスタ;

    5. 「問題入力」と「問題反映」処理
    6.  「可能世界要素」の準備ができたので問題を入力するインターフェースと それを可能世界要素に反映する仕組みを作成する。  まず「問題入力」テーブルの作成。
      CREATE TABLE 問題入力( H INTEGER PRIMARY KEY, V_1 INTEGER, V_2 INTEGER, V_3 INTEGER, V_4 INTEGER, V_5 INTEGER, V_6 INTEGER, V_7 INTEGER, V_8 INTEGER, V_9 INTEGER )
      「問題入力」テーブル初期化。
      INSERT INTO 問題入力 ( H ) SELECT 縦軸.H FROM 縦軸;
      そして「問題入力」テーブルクリア。
      DELETE * FROM 問題入力;
      さて、この「問題入力」テーブルを「可能世界要素」テーブルに反映させる。
      DELETE 可能世界要素.* FROM 問題入力 INNER JOIN 可能世界要素 ON 問題入力.H=可能世界要素.H WHERE (V=1 And V_1 Is Not Null And V_1<>num) Or (V=2 And V_2 Is Not Null And V_2<>num) Or (V=3 And V_3 Is Not Null And V_3<>num) Or (V=4 And V_4 Is Not Null And V_4<>num) Or (V=5 And V_5 Is Not Null And V_5<>num) Or (V=6 And V_6 Is Not Null And V_6<>num) Or (V=7 And V_7 Is Not Null And V_7<>num) Or (V=8 And V_8 Is Not Null And V_8<>num) Or (V=9 And V_9 Is Not Null And V_9<>num)
      例えば、問題入力に次のように作成する。
      H V_1 V_2 V_3 V_4 V_5 V_6 V_7 V_8 V_9
      1         6 7     9
      2   2              
      3     3            
      4 4                
      5 5                
      6 6                
      7                  
      8 8                
      9                  
       すると、「可能世界表示」は次のようになる。
      H\V 1 2 3 4 5 6 7 8 9
      1 123456789 123456789 123456789 123456789 6 7 123456789 123456789 9
      2 123456789 2 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      3 123456789 123456789 3 123456789 123456789 123456789 123456789 123456789 123456789
      4 4 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      5 5 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      6 6 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      7 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      8 8 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
      9 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
       これで解く準備は整った。 次は解析のロジックの実装を行う。

  4. 解析
先頭
コメントはこちらにでも
NaruTo の 計算機譜表工房
NaruTo の御家