There are many resources on how to remove duplicates and similar issues but I can\'t seem to be able to find any on removing unique elements. I\'m using SWI-Prolog but I don
Using tpartition/4 in tandem with
if_/3 and (=)/3, we define remove_unique/2
like this:
remove_unique([], []). remove_unique([E|Xs0], Ys0) :- tpartition(=(E), Xs0, Es, Xs), if_(Es = [], Ys0 = Ys, append([E|Es], Ys, Ys0)), remove_unique(Xs, Ys).
Here's the sample query, as given by the OP:
?- remove_unique([1,2,2,3,4,5,7,6,7], Xs).
Xs = [2,2,7,7]. % succeeds deterministically
As long as you don't know that the list is sorted in any way, and you want to keep the sequence of the non-unique elements, it seems to me you can't avoid making two passes: first count occurrences, then pick only repeating elements.
What if you use a (self-balancing?) binary tree for counting occurrences and look-up during the second pass? Definitely not O(n²), at least...