0
votes

I was wondering if there's any way to remove repeating elements in prolog only if they're nearby eachother.

At the moment I could only do this:

Input:

([z,z,z,z,z,x,x,x,c,c,c,z,z,z], R)

And i get output:

R = [x,c,z].

But i wanna see output like this:

R = [z,x,c,z].

Is there any way to do that?

2
How did you implement the predicate? (L, R) does not remove elements from a list.Willem Van Onsem
how do you define nearby? Next to each other?DuDa
There is a smiliar question and answer already asked a few days ago.DuDa
yes, nearby is next to each other. I don't need to delete them every time I see them I wanna do like that: Input: [z,z,z,x,x,x,z,z,z,x,x,x,z,z,z] Output: [z,x,z,x,z]Jannie

2 Answers

0
votes

This is essentially run length encoding, where you might compress [a,a,a,b,c,c,c,c,c] to [a:3,b,c:5] or a similar representation. Except that we don't care about the length of the run (or do we?)

collapse([],[]).
collapse([X|Xs], Ys ) :- collapse(X,Xs,Ys).

collapse( X , []     , [X]    ) .
collapse( Y , [X|Xs] , [Y|Ys] ) :- Y \= X , collapse(X,Xs,Ys) .
collapse( Y , [X|Xs] , Ys     ) :- Y  = X , collapse(Y,Xs,Ys) .

[computation of run length is left as an exercise for the reader].

0
votes

You can each time look if the next element can be unified with the current element. If that is the case we skip the element, otherwise we start a new "group", so:

uniqs([], []).
uniqs([H|T], R) :-
    uniqs(T, H, R).

uniqs([], X, [X]).
uniqs([X|T], X, R) :-
    uniqs(T, X, R).
uniqs([Y|T], X, [X|R]) :-
    dif(X, Y),
    uniqs(T, Y, R).

For the given sample input, this gives us:

?- uniqs([z,z,z,z,z,x,x,x,c,c,c,z,z,z], R).
R = [z, x, c, z] ;
false.