Search code examples
prolog

find biggest interval in a list of sublists (these sublists have 2 elements)


i have this exercise where i get a list of sublists like [[X1,Y1],[X2,Y2]...] which represent an interval (Xi-Yi), and i want to return a list with the biggest interval (it can be more than one interval).

this is what i've got so far. i can't see what im doing wrong but when try to run biggest_interval([[1,2],[5,7],[6,10],[12,15]],L). i get true, followed by a false instead of [6,10]

biggest_interval([H|T],Answer):-
biggest_interval(H,T,-1,Answer).

biggest_interval([],_,_,_).
biggest_interval(_,[],_,_).

biggest_interval([X,Y],[H|T],Biggest,Answer):-
Z is Y-X,
Z =:= Biggest,
append(Answer,[X,Y],L),
!,
biggest_interval(H,T,Biggest,L).
biggest_interval([X,Y],[H|T],Biggest,Answer):-
Z is Y-X,
(
    Z > Biggest -> append([],[X,Y],L),
    biggest_interval(H,T,Z,L);
    true 
),
biggest_interval(H,T,Biggest,Answer).

Solution

  • One of the problems with your code is that your predicate biggest_interval/4 does not collect the Answer in the "base case" (it only stops the recursive process).

    One possible solution is:

    biggest_interval(ListOfLists, Answer) :-
        biggest_interval(ListOfLists, -inf, [], Biggest),
        reverse(Biggest, Answer).   % if order of the pairs is important!
    
    
    biggest_interval([], _, Answer, Answer) :- !.       % collect Answer!
    
    biggest_interval([[X,Y]|Lists], Max, Acc, Answer) :-
        Z is Y-X,
        (   Z = Max ->  biggest_interval(Lists, Max, [[X,Y]|Acc], Answer)
        ;   Z > Max ->  biggest_interval(Lists,  Z,  [[X,Y]],     Answer)
        ;               biggest_interval(Lists, Max, Acc,         Answer) ).
    

    Here are some examples:

    ?- biggest_interval([[1,2],[5,7],[6,10],[12,15]],L).
    L = [[6, 10]].
    
    ?- biggest_interval([[1,20],[5,7],[6,10],[12,15]],L).
    L = [[1, 20]].
    
    ?- biggest_interval([[1,2],[5,7],[6,10],[12,15],[3,10]],L).
    L = [[3, 10]].
    
    ?- biggest_interval([[1,2],[5,7],[6,10],[12,15],[8,12]],L).
    L = [[6, 10], [8, 12]].