2

my problem is: While learning Prolog i wanted to make a NxN Sudoku solver. This solver will get the input like

    [[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]]

Where some of them might be variables. The solver has to solve that Sudoku. The problem is way smaller:

    firstElementsOf([],_).
    firstElementsOf([[X|_]|Rest2],Y) :-
      firstElementsOf(Rest2,Y2),
      append([X],[Y2],NotFlat),
      flatten(NotFlat,Y).

This should be the beginning of checking, if every column has distinct numbers. The Y from firstElementsOf should contain only the first elements of the given rows. In the Example:

    [1,3,2,4]

Sadly, thanks to append, it always adds another empty space to the Y list. It gives:

    [1,3,2,4,_1320]

Question1: Is there a way to get rid of that _1320?

Question2: Is this even right? Will there be a way to get the 2nd and 3rd elements of the Input with that?

max66
  • 65,235
  • 10
  • 71
  • 111
Shuumi
  • 76
  • 8

1 Answers1

0

For question 1: I suppose the error is in

firstElementsOf([],_).

I think should be

firstElementsOf([],[]).

Off topic: are you sure that you can't simply write the other clause as follows?

firstElementsOf([[X|_]|Rest2],[X|Y]) :-
  firstElementsOf(Rest2,Y).

For question 2: I propose a more general predicate: the following getPosList/3 with support of getPosElem/3

getPosElem([H | _], 1, H).

getPosElem([_ | T], Pos, H) :-
  Pos > 1,
  Pm1 is Pos - 1,
  getPosElem(T, Pm1, H).

getPosList([], _, []).

getPosList([H | T], Pos, [E | L]) :-
  getPosElem(H, Pos, E),
  getPosList(T, Pos, L).

It extract a list of all elements in position Pos, so

getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 1, L),

it's equivalent to firstElementOf([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], L) and extract [1, 3, 2, 4],

getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 2, L),

extract [2, 4, 3, 1],

getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 3, L),

extract [3, 1, 4, 2],

getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 4, L),

extract [4, 2, 1, 3] and

getPosList([[1,2,3,4],[3,4,1,2],[2,3,4,1],[4,1,2,3]], 5, L),

or a number greather than 5, return false

max66
  • 65,235
  • 10
  • 71
  • 111
  • For the first... it trully works... i don't even understand why. – Shuumi Dec 26 '16 at 18:42
  • For the second... i can do that too... but i also don't get it :) Let me look at it later:) – Shuumi Dec 26 '16 at 18:43
  • @Shuumi ; answer improved (with a point (2) proposal; for the "why" in point (1), take in count that `[]` is "empty list" and `_` is "a value"; if you write `firstElementsOf([],_)` you impose the extraction of "a value" (so an unbounded variable, `_1320` in your example) from the empty list – max66 Dec 26 '16 at 19:05
  • That is wonderful! Of course i will try to understand every little bit of the text you have wrote, but at the first glance i see, that your work is exacly what i need, to finish that solver. Thank you very much! – Shuumi Dec 26 '16 at 19:41
  • 1
    @shuumi - a little of topic: sudoku is a tipical constraint satisfaction problem; in some prolog environments (gprolog and swi-prolog, by example) it's available a CLP library; I suggest to search and give a look at it. – max66 Dec 26 '16 at 19:52