/* Partition a list according to some predicate in Picat. This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. % import cp. main => go. go => L = 1..30, time(partition(L,pred1,Includes, Excludes)), println(includes=Includes), println(excludes=Excludes), time([Includes2,Excludes2] = partition2(L,pred1)), println(includes2=Includes2), println(excludes2=Excludes2), nl. go2 => L = 1..30, Groups = group(L,prime2), foreach(G in Groups) println(G) end, nl. % for partition: pred1(N) => prime(N). % for group/2: mod3(I) = I mod 3. prime2(N) = cond(prime(N), 1, 0). partition([],_, LHS,RHS) => LHS = [], RHS = []. partition([Head|Tail], Pred, HeadLHS, RHS) ?=> HeadLHS = [Head|LHS], call(Pred,Head), partition(Tail, Pred,LHS, RHS). partition([Head|Tail], Pred, LHS, HeadRHS) => HeadRHS = [Head|RHS], not call(Pred,Head), partition(Tail, Pred,LHS, RHS). partition2(L, Pred) = [P1,P2] => P1 = [], P2 = [], foreach(E in L) if call(Pred,E) then P1 := P1 ++ [E] else P2 := P2 ++ [E] end end. % Note: P must be a defined function group(List, F) = G, list(List) => println($group(List, F)), G = new_map(), foreach(E in List) V = apply(F,E), G.put(V, G.get(V,[]) ++ [E]) end.