I received this problem and I can't get it done, I don't know what I've done wrong, can someone help me ?
Write a predicate to add a value v after 1-st, 2-nd, 4-th, 8-th, … element in a list.
% add(L:list, E:Number, P:Number, C:number, H:List)
% add(i,i,i,i,o)
add([],_,_,_,[]).
add([_|T],E,P,C,[HR|TR]) :-
P =:= C,
HR is E,
C is C+1,
P is P*2,
add(T,E,P,C,TR).
add([H|T],E,P,C,[H|TR]) :-
P =\= C,
C is C+1,
add(T,E,P,C,TR).
Here's another possibility to define such a predicate. Whenever you are describing lists it is worthwhile to consider using DCGs since they yield easily readable code. First let's observe that there's only need for three arguments, namely the list, the element to be inserted and the list with the element already inserted at the desired positions. The arguments P and C are only needed for bookkeeping purposes so it's opportune to hide them inside the predicate. And since we're already about to redesign the predicates interface let's also give it a more descriptive name that reflects its relational nature, say list_e_inserted/3:
list_e_inserted(L,E,I) :-
phrase(inserted(L,E,1,1),I). % the DCG inserted//4 describes the list I
inserted([],_E,_P,_C) --> % if the list L is empty
[]. % the list I is empty as well
inserted([H|T],E,P,P) --> % if P and C are equal
{P1 is P*2, C1 is P+1}, % P is doubled and C is increased
[H,E], % H is in the list I, followed by E
inserted(T,E,P1,C1). % the same holds for T,E,P1,C1
inserted([H|T],E,P,C) --> % if P and C are
{dif(P,C), C1 is C+1}, % different C is increased
[H], % H is in the list I
inserted(T,E,P,C1). % the same holds for T,E,P,C1
Now let's see the predicate at work:
?- list_e_inserted([],10,I).
I = [].
?- list_e_inserted([1],10,I).
I = [1, 10] ;
false.
?- list_e_inserted([1,2],10,I).
I = [1, 10, 2, 10] ;
false.
?- list_e_inserted([1,2,3],10,I).
I = [1, 10, 2, 10, 3] ;
false.
?- list_e_inserted([1,2,3,4],10,I).
I = [1, 10, 2, 10, 3, 4, 10] ;
false.
The predicate also works in the other direction:
?- list_e_inserted(L,E,[1,10,2,10,3,4,10,5]).
L = [1, 2, 3, 4, 5],
E = 10 ;
false.
And the most general query also yields the desired solutions:
?- list_e_inserted(L,E,I).
L = I, I = [] ;
L = [_G23],
I = [_G23, E] ;
L = [_G23, _G35],
I = [_G23, E, _G35, E] ;
L = [_G23, _G35, _G47],
I = [_G23, E, _G35, E, _G47] ;
L = [_G23, _G35, _G47, _G53],
I = [_G23, E, _G35, E, _G47, _G53, E] ;
.
.
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With