Reputation: 113
I'm trying to write a list inputted by the user to a new list in Prolog. I have figured out how to do it using a reverse method and it works fine. My problem is that I need it to stop at the element the user inputs along with the list (so I can repeat this value again before adding the remainder of the list). For example if I was to input
repeat_nth(3, [a,b,c,d,e], X).
its output should be
X = [a,b,c,c,d,e].
When I try to introduce a variable 'N' to count until the element to be repeated prolog just tells me 'no'. Here is my code:
new_list(N,[H|T],A,L2):- N > 0,
N1 is N - 1,
new_list(N1,T,[H|A],L2).
new_list(0,[],A,A).
repeat_nth(N,L1,L2):- new_list(N,L1,[],L2).
Upvotes: 3
Views: 402
Reputation: 58274
The predicate can be built up from a couple of cases. If you think about them logically first and express them in a sentence or two, it can help determine the clauses.
Base case: the list, [H|T]
with the first element (H
, element number 1) repeated is a list where the head (H
) appears twice. The tail (T
) remains the same:
repeat_nth(1, [H|T], [H,H|T]).
Recursive case: for N > 1, to repeat the Nth term of a list [H|T]
, I copy over the head (H
) and then repeat the (N-1)st term (N1 is N-1
) of the tail (T
) of the first list, and that is the tail of the second (T1
):
repeat_nth(N, [H|T], [H|T1]) :-
N > 1,
N1 is N-1,
repeat_nth(N1, T, T1).
The above two clauses are all that's needed. One of your attempts described in your comments was very close! The error was in that last line of the second clause. You tried:
repeat_nth(N1, [H|T], [H|T1]).
So you carried along the H
which was incorrect. H
is already taken care of in the head of the clause, and the purpose of this new call is to take care of the tails (as the description of the recursive case indicates).
Upvotes: 2
Reputation: 60034
...
Call: (10) new_list(0, [d, e], [c, b, a], _G2728)
Call: (11) 0>0
Fail: (11) 0>0
...
Seems your code is missing the base case. It's fairly clear that [d,e]
cannot match []
.
Upvotes: 0