Search code examples
listprolog

Prolog: searching for sublists of length>=3


I'd like to produce a predicate which is able to check whether a list will divide into sublists each containing at least three atoms.

For example:

findgroups([1,2,3,4,5,6,7,8,9],L1).

Has solutions such as:

L1=[[1,2,3],[4,5,6],[7,8,9]]
L1=[[1,2,3,4],[5,6,7,8,9]]
L1=[[1,2,3,4,5],[6,7,8,9]]
L1=[[1,2,3,4,5,6],[7,8,9]]

However, the following will fail:

findgroups([1,2,3,4,5]).

I have written a few predicates based on splitting lists into two sub terms using append, but I'm confused about handling multiple sublists.

Thank you very much for your help

With Best wishes J


Solution

  • Maybe this very simple solution could do

    findgroups([], []).
    findgroups(L, [[A,B,C|D]|Gs]) :-
        append([A,B,C|D], R, L),
        findgroups(R, Gs).
    

    The last one solution is not requested, but it's correct, since you don't rule out a group of only 1 element

    ?- findgroups([1,2,3,4,5,6,7,8,9], Gs).
    Gs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] ;
    Gs = [[1, 2, 3], [4, 5, 6, 7, 8, 9]] ;
    Gs = [[1, 2, 3, 4], [5, 6, 7, 8, 9]] ;
    Gs = [[1, 2, 3, 4, 5], [6, 7, 8, 9]] ;
    Gs = [[1, 2, 3, 4, 5, 6], [7, 8, 9]] ;
    Gs = [[1, 2, 3, 4, 5, 6, 7, 8|...]] ;
    false.
    

    To match exactly the examples, I would write

    findgroups(L, Gs) :- findgroups_(L, Gs), Gs = [_,_|_].
    findgroups_([], []).
    findgroups_(L, [[A,B,C|D]|Gs]) :-
        append([A,B,C|D], R, L),
        findgroups_(R, Gs).