The title is the required predicate and here are few sample queries
?- splitEvery(2,[a,b,c,d,e,f,g,h],R).
R = [[a, b], [c, d], [e, f], [g, h]] ;
false.
?- splitEvery(4,[a,b,c,d,e,f,g,h],R).
R = [[a, b, c, d], [e, f, g, h]] ;
false.
?- splitEvery(8,[a,b,c,d,e,f,g,h],R).
R = [[a, b, c, d, e, f, g, h]] ;
false.
my code so far is this
splitEvery(N,List,Res):-
splitEveryHelper1(N,List,Res,1,[]).
splitEveryHelper1(_,[],Acc,_,Acc).
splitEveryHelper1(N,[H|T],Res,C,[[H|HT]|AT]):-
C=<N,
C\_new is C+1,
splitEveryHelper1(N,T,Res,C_new,[[HT]|AT]).
splitEveryHelper1(N,List,Res,C,[AH|TR]):-
C>N,
C\_new=1,
splitEveryHelper1(N,List,Res,C_new,AT).
however it is not working properly
This compact fragment satisfies the queries you listed
splitEvery(N,L,R) :-
length(R,_),
maplist({N}/[X]>>length(X,N),R),
append(R,L).
but it has a big flaw (apart requiring library( yall )). Can you spot it?
Edit
About your code: you're doing it more complex than required, and ignoring the messages the compiler gives you about singletons.
Remember that accumulators reverse the list, so you should remove them. Build instead the list in the output argument.
To give you a start:
splitEvery(N,List,Res):-
splitEveryHelper1(N,List,1,Res).
splitEveryHelper1(_,[],_,[]).
splitEveryHelper1(N,[H|T],C,[[H|R]|AT]):-
C=<N,
C_new is C+1,
....
splitEveryHelper1(N,List,C,[[]|TR]):-
C>N,
C_new=1,
....
fill the dots with the proper recursive calls. Then it will be working properly.
It helps to decompose your problem. You want to take a list of things and split it up into a individual sublists of N items, correct?
That is a matter of repeatedly doing the following:
So, you need a predicated to pull no more than N items from the front of the list. There's 3 cases:
The general case: N > 0 and the list is non-empty. Here, we add the head of the list to the prefix that we're building, decrement N, and recurse down on what's left.
Special case #1: N > 0 and the list is empty. Here, we close the prefix and return the empty list as the suffix.
Special case #2: N is 0. Here, We close the prefix and return the source list as the suffix.
first( N , [X|L] , [X|Xs] , Sfx ) :- N > 0 , N1 is N-1 , first( N1, L, Xs, Sfx ) .
first( N , [] , [] , [] ) :- N > 0 .
first( 0 , Xs , [] , Xs ) .
Once we have that, it's an even easier matter of repeatedly invoking first/4
.
split_every( _ , [] , [] ) .
split_every( N , [X|Xs] , [Pfx|LoL] ) :- first(N,[X|Xs],Pfx,Sfx), split_every(N,Sfx,LoL) .
You can, err... fiddle with it in this fiddle: https://swish.swi-prolog.org/p/split-list.pl
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.