a([],O,O).
a([I|J],K,O):-delete(K,I,F),(K=F->append(K,[I],M),a(J,M,O);a(J,F,O)).
Non-obfuscated version:
append_and_eraze([], Output, Output).
append_and_eraze([I | Input], Interim, Output) :-
delete(Interim, I, Filtered),
( Interim = Filtered ->
append(Interim, [I], Interim1),
append_and_eraze(Input, Interim1, Output)
;
append_and_eraze(Input, Filtered, Output)
).
delete/3
ensures that its third argument unifies with its first argument, with all instances of second argument removed from it.
- If those turn out to be the same, we append the element (it wasn't removed).
append/3
as per its name, appends an element to list.
- We recur on the elements of the input until we hit the
[]
(empty list), at which point the intermediate result will unify with desired result.
Test:
?- append_and_eraze(`ABCDBCCBE`, [], X), string_codes(Y, X).
X = [65, 68, 67, 66, 69],
Y = "ADCBE".
?- append_and_eraze(`ABCXYZCABXAYZ`, [], X), string_codes(Y, X).
X = [65],
Y = "A".
?- append_and_eraze(`aAABBbAbbB`, [], X), string_codes(Y, X).
X = [97, 65, 98, 66],
Y = "aAbB".
?- append_and_eraze(`GG`, [], X), string_codes(Y, X).
X = [],
Y = "".
Some Prologs treat strings in double quotes as lists, SWI can be configured to do the same, but for the sake of simplicity, I used string_codes/2
to format output nicely.