Safa'a Kiwan
Safa'a Kiwan

Reputation: 21

Split lists issue

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

Answers (2)

Will Ness
Will Ness

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

user1812457
user1812457

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

Related Questions