Splitting a list into 2 lists on a rod in the prolog

I want to split the list into 2 lists with a point P, if the number is less than P, it goes to L1, and if it is more than P, then it goes to L2.

This is what I still have, I can split the list L into L1 = [[], []] in this form. But I want to split the list into 2 lists L1 and L2, how would I do it?

split(L,P,L1):-
   split(L,P,[],L1).

split([],_,[],[]).
split([],_,X,[X]) :- X \= [].
split([P|T],P,[],L1) :- split(T,P,[],L1).
split([P|T],P,L,[L|L1]) :- L \= [], split(T,P,[],L1).
split([H|T],P,S,L1) :- H \= P, append(S, [H], S2), split(T,P,S2,L1).
+4
source share
1 answer

To implement this predicate, you only need three rules:

:- use_module(library(clpfd)).

split([], _, [], []).
split([H|T], P, L1, [H|T2]) :-
    H #>= P,
    split(T, P, L1, T2).
split([H|T], P, [H|T1], L2) :-
    H #< P,
    split(T, P, T1, L2).

The code is pretty simple

Note that because of library(clpfd)this predicate also works, for example. when the start list and vault are not known:

?- split(L,P,[5,47],[101]).
L = [101, 5, 47],
P in 48..101 ;
L = [5, 101, 47],
P in 48..101 ;
L = [5, 47, 101],
P in 48..101 ;
false.

Using partition/4

As stated in the comment, you can use partition/4to do this:

split(L, P, L1, L2) :-
    partition(zcompare(>,P), L, L1, L2).

However, this will not show as many different actions as the first implementation.

+3
source

All Articles