2016-03-12 7 views
5

Devo risolvere i puzzle di Sudoku nel formato di un vettore contenente 9 vettori (di lunghezza 9 ciascuno). Visto che i vettori sono elenchi concatenati in Prolog, ho pensato che la ricerca sarebbe andata più veloce se avessi trasformato i puzzle in un formato di array 2D prima.Come convertire i vettori in array in ECLiPSe (CLP)? (o Prolog)

Esempio di puzzle:

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,_]]. 

sto usando Eclipse CLP per implementare un risolutore. Il migliore che è venuta in mente finora è quello di scrivere un dominio del genere:

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

e un convertitore per il puzzle (parametro P è la data puzzle e Sudoku è la nuova griglia definita con la matrice 2D) . Ma sto avendo problemi a collegare i valori del puzzle iniziale dato al mio array 2D.

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] 
    ) 
). 

Prima di questo, ho provato ad utilizzare array_list (http://eclipseclp.org/doc/bips/kernel/termmanip/array_list-2.html), ma ho continuato a ottenere errori di tipo. Come ho fatto prima:

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]) 
    ) 
). 

Quando il mio Sudoku finalmente uscita l'esempio di puzzle P nel seguente formato:

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

allora sarò felice.

aggiornamento

ho riprovato con l'array_list; quasi funziona con il seguente codice:

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) 
). 

Le operazioni di scrittura sono lì per vedere come i vettori/matrici assomigliano. Per qualche motivo, si ferma alla seconda iterazione (anziché 9 volte) e restituisce il resto del puzzle di esempio come vettore di vettori. Solo il primo vettore viene assegnato correttamente.

Update2

Mentre sono sicuro che la risposta data da jschimpf è corretta, ho anche capito la mia realizzazione:

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

Grazie per la spiegazione aggiunto il motivo per cui non ha lavorare prima però!

risposta

5

La soluzione più semplice è evitare completamente la conversione scrivendo le specifiche del puzzle direttamente come array 2-D. Un "allineamento" Eclipse è semplicemente una struttura con il funtore '[]'/N, in modo da poter scrivere:

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,_)). 

È quindi possibile utilizzare questo array 2-D direttamente come il contenitore per le variabili di dominio:

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

Tuttavia, se si desidera mantenere la specifica del proprio elenco di liste e convertirla in un formato di array di array, è possibile utilizzare array_list/2.Ma dal momento che funziona solo per gli array 1-D, è necessario convertire i livelli di annidamento singolarmente:

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). 

Per quanto riguarda il motivo per il proprio codice non ha funzionato: ciò è dovuto al l'indice di notazione P[I]. Questo

  • richiede P ad essere un array (si sta utilizzando su liste)
  • opere solo in contesti dove si teme un'espressione aritmetica, per esempio il lato destro di is/2, in vincoli aritmetici, ecc.
Problemi correlati