Working on a predicate, rotate(L,M,N)
, where L
is a new list formed by rotating M
to the right N
times.
My approach was to just append the tail of M
to its head N
times.
rotate(L, M, N) :-
( N > 0,
rotate2(L, M, N)
; L = M
).
rotate2(L, [H|T], Ct) :-
append(T, [H], L),
Ct2 is Ct - 1,
rotate2(L, T, Ct2).
Currently, my code returns L
equal to the original M
, no matter what N
is set to.
Seems like when I'm recursing, the tail isn't properly moved to the head.
You can use append
to split lists, and length
to create lists:
% rotate(+List, +N, -RotatedList)
% True when RotatedList is List rotated N positions to the right
rotate(List, N, RotatedList) :-
length(Back, N), % create a list of variables of length N
append(Front, Back, List), % split L
append(Back, Front, RotatedList).
Note: this only works for N <= length(L). You can use arithmetic to fix that.
Edit for clarity
This predicate is defined for List and N arguments that are not variables when the predicate is called. I inadvertently reordered the arguments from your original question, because in Prolog, the convention is that strictly input arguments should come before output arguments. So, List and N and input arguments, RotatedList is an output argument. So these are correct queries:
?- rotate([a,b,c], 2, R).
?- rotate([a,b,c], 1, [c,a,b]).
but this:
?- rotate(L, 2, [a,b,c]).
will go into infinite recursion after finding one answer.
When reading the SWI-Prolog documentation, look out for predicate arguments marked with a "?", as in length
. They can be used as shown in this example.