I have been trying to split a given list into two different lists: Unique and Duplicate.
For example, if we have the list [1, 1, 2, 3, 3, 4, 5]
I want the Unique list to be [2, 4, 5]
and Duplicate to be [1, 3]
.
I don't want all the 1's in the list to be in the Duplicate list. I just need one of it.
The code I have right now:
compareL([_|[]], Unique, Dup).
compareL([X3,Y3 | Tail], [X3 | Unique], Dup) :-
X3 =\= Y3,
compareL([Y3 | Tail], Unique, Dup).
compareL([X3,Y3 | Tail], Unique, [X3 | Dup]) :-
X3 = Y3,
skipDups(X3, Tail, Unique, Dup).
skipDups(_, [], Unique, Dup).
skipDups(X3,[Y3 | Tail], Unique, Dup) :-
X3 =\= Y3,
compareL([Y3 | Tail], Unique, Dup).
skipDups(X3,[Y3 | Tail], Unique, Dup) :-
X3 = Y3,
skipDups(X3, Tail, Unique, Dup).
Using the example list given above if I run compareL([1, 1, 2, 3, 3, 4, 5], Unique, Dup).
I get:
Unique = [2, 4|_G1954],
Dup = [1, 3|_G1948].
I can't figure out why towards the end of both lists I am getting '_G1954
' and '_G1948
'. Any help would be appreciated. Thanks.
You can write that :
here is a solution, the key is take/4 that consumes all matching leading items, thus enabling easy testing of the list (
[_|_]
matches any list of at least 1 element )Answer using
(=)/3
Sample queries:
For run length encoding I used
splitlistIfAdj/3
.Query:
I am not sure how to change this so that it works in both directions.
You could then also do:
Sample Q:
We can preserve logical-purity by building upon
if_/3
,(=)/3
, andtpartition/4
!Here's the query the OP gave:
OK! How about the following quite general queries?