Reputation: 21
I have a problem in Prolog, I have a list with 81 items and I need to get just 9 items from it in different positions each time, for example if my list is:
L=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
split(L1,2,L) the result will be L1=[10,11,12,13,14,15,16,17,18].
My procedure is
split([X,X1,X2,X3,X4,X5,X6,X7,X8], 0, [X,X1,X2,X3,X4,X5,X6,X7,X8], []).
split([X,X1,X2,X3,X4,X5,X6,X7,X8|Y], 1, [X,X1,X2,X3,X4,X5,X6,X7,X8], Y).
split([X,X1,X2,X3,X4,X5,X6,X7,X8|Y], N, [X,X1,X2,X3,X4,X5,X6,X7,X8|T], Z) :-
N > 0,
N1 is N-1,
split(Y, N1, T, Z).
but it doesn't work.
Upvotes: 1
Views: 92
Reputation: 71065
the minimal edit fix for your code is
split([X,X1,X2,X3,X4,X5,X6,X7,X8], 1, [X,X1,X2,X3,X4,X5,X6,X7,X8|_]).
split(Y, N, [_X,_X1,_X2,_X3,_X4,_X5,_X6,_X7,_X8|Z]):-
N>1, N1 is N-1, split(Y, N1, Z).
This won't work if the length of the original list is smaller than 9*N
, for a call split(Y,N,....)
.
Upvotes: 1
Reputation:
You could use the ability of length/2
to create lists, and append/3
to split lists. Basically:
extract(List, N, Len, E)
is true when E is a list of length Len from position N (0-based indexing) in List
extract(List, N, Len, E) :-
length(E, Len),
length(Before, N),
append(Before, Rest, List),
append(E, _, Rest).
There are many other ways to do it of course, but this is conceptually easy (at least for me).
To your exact question, you could write:
extract_list(List, Len, Nth, E) :-
length(E, Len),
LenBefore is Len*(Nth-1),
length(Before, LenBefore),
append(Before, Rest, List),
append(E, _, Rest).
I have switched the position of the arguments as the convention is input arguments first, output last.
Upvotes: 3