2016-03-12 15 views
5

Mam do rozwiązania zagadki sudoku w formacie wektora zawierającego 9 wektorów (o długości 9 każdy). Widząc, że wektory są połączonymi listami w Prologu, pomyślałem, że wyszukiwanie pójdzie szybciej, jeśli najpierw przekształcę puzzle w formacie tablicy 2D.Jak przekonwertować wektory na tablice w ECLiPSe (CLP)? (lub Prolog)

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

Używam Eclipse CLP wdrożyć Solver. Najlepszym Mam wymyślić do tej pory jest napisanie domenę tak:

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

i konwerter do układanki (parametr P jest dany puzzle i Sudoku jest nową definicją siatki z tablicy 2D) . Ale mam problem z powiązaniem wartości z danej początkowej układanki z moją tablicą 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] 
    ) 
). 

Przed tym, próbowałem za pomocą array_list (http://eclipseclp.org/doc/bips/kernel/termmanip/array_list-2.html), ale trzymałem się błędy typu. Jak zrobiłem to wcześniej:

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

Kiedy mój Sudoku wreszcie wyprowadza przykład puzzle P w następującym formacie:

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

wtedy będę szczęśliwy.

aktualizacja

I ponownie próbował z array_list; prawie działa z następującym kodem:

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

Pisze, aby zobaczyć, jak wyglądają wektory/tablice. Z jakiegoś powodu zatrzymuje się przy drugiej iteracji (zamiast 9 razy) i wyprowadza resztę przykładowej układanki jako wektor wektorów. Tylko pierwszy wektor zostanie poprawnie przypisany.

Update2

Choć jestem pewien, że odpowiedź udzielona przez jschimpf jest poprawna, ja też zorientowali się własną realizacji:

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

Dzięki za dodatkową wyjaśnienie dlaczego tak się nie stało pracuj wcześniej!

Odpowiedz

5

Najprostszym rozwiązaniem jest uniknięcie konwersji, zapisując specyfikację puzzli bezpośrednio jako tablicę 2D. Zaćmienie „tablica” to po prostu struktura z funktora '[]'/N, więc można napisać:

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

Następnie można użyć tego 2-D tablicy bezpośrednio jako kontener dla zmiennych domen:

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

Jeśli jednak chcesz zachować specyfikację puzzli list-of-list i przekonwertować ją na format array-of-array, możesz użyć array_list/2.Ale ponieważ działa tylko na tablicach 1-D, trzeba konwertować te poziomy zagnieżdżenia indywidualnie:

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

chodzi o przyczyny własny kod nie działa: wynika to z zapisu indeksem P[I]. Ten

  • wymaga P się tablicę (uzywasz go na listach)
  • działa tylko w kontekstach, gdzie spodziewane jest wyrażenie arytmetyczne, np po prawej stronie is/2, w ograniczeniach arytmetycznych itp.
Powiązane problemy