2016-03-12 7 views
5

私は9つのベクトル(それぞれ長さ9)を含むベクトルの形式で数独パズルを解かなければなりません。ベクトルがPrologでリンクされたリストであることを見て、パズルを最初に2D配列形式に変換すると、検索が速くなると思った。ECLiPSe(CLP)の配列にベクトルを変換するには? (またはProlog)

例パズル:

puzzle(P) :- P = 
[[_,_,8,7,_,_,_,_,6], 
[4,_,_,_,_,9,_,_,_], 
[_,_,_,5,4,6,9,_,_], 

[_,_,_,_,_,3,_,5,_], 
[_,_,3,_,_,7,6,_,_], 
[_,_,_,_,_,_,_,8,9], 

[_,7,_,4,_,2,_,_,5], 
[8,_,_,9,_,5,_,2,3], 
[2,_,9,3,_,8,7,6,_]]. 

私はソルバーを実装するためにEclipseのCLPを使用しています。私がこれまでに作ってみた最高のは、このようなドメインを作成することです:

domain(P):- 
    dim(P,[9,9]), 
    P[1..9,1..9] :: 1..9. 

とパズルのためのコンバータ(パラメータPが与えられたパズルで、数独は、2次元配列を持つ新しい定義されたグリッドです) 。しかし、最初のパズルから2次元配列に値をリンクする際に問題があります。この前

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     (for(J,1,9), 
      param(Sudoku,P,I) 
     do 
      Sudoku[I,J] is P[I,J] 
    ) 
). 

、私はarray_list(http://eclipseclp.org/doc/bips/kernel/termmanip/array_list-2.html)を使用してみましたが、私は型エラーを取得保管。私は前にそれをやった方法:

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     (for(J,1,9), 
      param(Sudoku,P,I) 
     do 
      A is Sudoku[I], 
      array_list(A,P[I]) 
    ) 
). 

私の数独は、最終的には次の形式での例のパズルPを出力する場合:

Sudoku = []([](_Var1, _Var2, 8, 7, ..., 6), [](4, ...), ...) 

、私は幸せになるでしょう。私はarray_list再び試み

更新

convertVectorsToArray(Sudoku,P):- 
    (for(I,1,9), 
     param(Sudoku,P) 
    do 
     X is Sudoku[I], 
     Y is P[I], 
     write(I),nl, 
     write(X),nl, 
     write(Y),nl, 
     array_list(X, Y) 
). 

書き込みは、ベクター/アレイがどのように見えるか見ています。何らかの理由で2回目の反復(9回ではなく)で停止し、残りのパズルの例をベクトルのベクトルとして出力します。最初のベクトルだけが正しく割り当てられます。

アップデート2

私はjschimpfによって与えられた答えが正しいと確信していますが、私はまた私の独自の実装を考え出した:それはしなかった理由について追加説明のため

convertVectorsToArray(Sudoku,[],_). 
convertVectorsToArray(Sudoku,[Y|Rest],Count):- 
    X is Sudoku[Count], 
    array_list(X, Y), 
    NewCount is Count + 1, 
    convertVectorsToArray(Sudoku,Rest,NewCount). 

感謝を前に仕事!

答えて

5

最も簡単な解決策は、パズル仕様を直接2次元配列として書き込むことによって、変換を完全に回避することです。 ECLIPSE「アレイ」は、単にファンクタ'[]'/Nを持つ構造であるので、あなたが書くことができます。

puzzle(P) :- P = [](
    [](_,_,8,7,_,_,_,_,6), 
    [](4,_,_,_,_,9,_,_,_), 
    [](_,_,_,5,4,6,9,_,_), 

    [](_,_,_,_,_,3,_,5,_), 
    [](_,_,3,_,_,7,6,_,_), 
    [](_,_,_,_,_,_,_,8,9), 

    [](_,7,_,4,_,2,_,_,5), 
    [](8,_,_,9,_,5,_,2,3), 
    [](2,_,9,3,_,8,7,6,_)). 

次に、あなたのドメインの変数のためのコンテナとして直接この2次元配列を使用することができます。

sudoku(P) :- 
    puzzle(P), 
    P[1..9,1..9] :: 1..9, 
    ... 

しかし、あなたのリストのパズルの仕様を保持し、それを配列の配列形式に変換する場合は、array_list/2を使用できます。しかし、それは唯一の1次元配列のために働くことから、あなたは個別のネストレベルを変換する必要があります。自分のコードが機能しなかった理由については

listoflists_to_matrix(Xss, Xzz) :- 
    % list of lists to list of arrays 
    (foreach(Xs,Xss), foreach(Xz,Xzs) do 
     array_list(Xz, Xs) 
    ), 
    % list of arrays to array of arrays 
    array_list(Xzz, Xzs). 

を:これは、添字表記P[I]によるものです。この

  • は、例えば、算術式だけが予想される状況で
  • 作品、(あなたがリストにそれを使用していた)の配列であることをPが必要ですis/2の右辺、算術制約などである。
関連する問題