Search code examples
prologprolog-dif

How do I skip an element that already have been printing prolog


Im trying to do an exercise in Prolog like this: i introduce this list [10,20, 10, 20, 30], and the program shows :

10 - 2 time; 20 - 2 times; 30 - 1 times.

Here is my code:

conta(_,[], 0).
conta(X, [X|T], N) :-   conta(X,T, N2), N is N2 + 1 . 
conta(X, [Y|T], N) :-  X \= Y,   conta(X,T,N).  

aux([],[]).
aux([X|L],L1):-conta(X,L1,C),write(X),write(C), write('vezes'),aux(L,L1).

But the result is this:

10 - 2times  20 -2time 10-2times 20-2times 30-1 time
false.

He shows the element the number of time that the element is in the list. Any help, Please!!


Solution

  • In your problem statement you are interspersing the pure relation with side-effects. While you might solve the problem in this manner you will see only very few of Prolog's interesting properties. Instead, try to formulate your problem as a pure relation. So imagine, you have it already implemented, and formulate some queries for it:

    ?- list_vezes([10,20, 10, 20, 30], [10-2,20-2,30-1]).
       true.
    

    The following solution counts and removes the corresponding elements. It has some n2 runtime.

    list_vezes([], []).
    list_vezes([E|Es1], [E-N|Vezes]) :-
       n_occ(E, Es1,Es2, 1,N),
       list_vezes(Es2, Vezes).
    
    n_occ(_, [],[], N,N).
    n_occ(E, [E|Es0],Es, N0,N) :-
       N1 is N0+1,
       n_occ(E, Es0,Es, N1,N).
    n_occ(E, [F|Es0],[F|Es], N0,N) :-
       dif(F,E),
       n_occ(E, Es0,Es, N0,N).
    

    In many Prolog systems is a built-in. See the link what to do if you do not have it.

    Now, if you still want to print out the text you said, you might do this with this new list:

    printitem(E-N) :-
       writeq(E-N), write(' times\n').
    
    
    compter_et_imprimer(L) :-
       list_vezes(L, Vezes),
       maplist(printitem, Vezes).