I am trying to duplicate the element of a list before the "rep" element, in a NON-recursive way. For example, I have the list
[1,2,rep,3,4,5]
and I want to end up with
[1,2,2,3,4,5]
or
[rep,1,2,3,4,5]
and want
[1,2,3,4,5]
So far I have:
element_repeat_non(List,Sol):-
findall(X,element_inner(List,X),Sol).
element_inner(List,X):-
member(X,List),
not(X==rep).
This, however, only ignores the rep
element and returns a list without it, giving the desired result in the case of
[rep,1,2,3,4,5]
but not in the case of
[1,2,rep,3,4,5]
I can't figure out how I can keep the previous element so I can replace the "rep" element. If possible, I would like to avoid using a condition check(if_then_else).
Any recommendations are welcome. Thanks in advance!
Considering that there can be at most one occurrence of the atom rep
in the input list (as you have stated in your last comment), a possible solution is as follows:
% repeat_previous(+List, -NewList)
repeat_previous([rep|L], L).
repeat_previous(L, L) :-
not(append(_, [rep|_], L)).
repeat_previous(L, S) :-
append(Xs, [Y,rep|Ys], L),
append(Xs, [Y,Y|Ys], S).
Examples:
?- repeat_previous([1,2,3,4,5], L).
L = [1, 2, 3, 4, 5] ;
false.
?- repeat_previous([rep,1,2,3,4,5], L).
L = [1, 2, 3, 4, 5] ;
false.
?- repeat_previous([1,2,rep,3,4,5], L).
L = [1, 2, 2, 3, 4, 5] ;
false.
?- repeat_previous([1,2,3,4,5,rep], L).
L = [1, 2, 3, 4, 5, 5] ;
false.