Search code examples
prolog

Prolog: Is there a way to find the longest consecutive number sequence in a list and get its length?


Given a list of 5 random natural numbers (the number's range is from 1 to 13), i.e. [1,6,11,12,13], how can I find out the longest consecutive number sequence (i.e. [11,12,13]) that its length must be larger or equal to 3, and also get its length?


Solution

  • You can traverse the list keeping track of the current sequence and its length along with the maximum sequence and length found so far.

    After processing all the list you can check whether the maximum length is >= 3 and select the proper output:

    longest_sequence([First|L], Len1, Seq) :-
        longest_sequence(L, 1, [First], 0, [], Len, RSeq),
        (   Len>=3
        ->  reverse(RSeq, Seq),
            Len1=Len
        ;   Seq=[],
            Len1=0
        ).
      
    longest_sequence([], CurLen, CurSeq, MaxLen, MaxSeq, Len, Seq):-
      (CurLen > MaxLen -> Len-Seq=CurLen-CurSeq ; Len-Seq=MaxLen-MaxSeq).
    longest_sequence([CurItem|L], CurLen, [LastItem|CurSeq], MaxLen, MaxSeq, Len, Seq):-
      (
       succ(LastItem, CurItem) ->
        (
          succ(CurLen, CurLen1),
          CurSeq1=[CurItem,LastItem|CurSeq],
          MaxLen1-MaxSeq1=MaxLen-MaxSeq
        ) ;
        (
          (CurLen > MaxLen -> MaxLen1-MaxSeq1=CurLen-[LastItem|CurSeq] ; MaxLen1-MaxSeq1=MaxLen-MaxSeq),
          CurLen1=1,
          CurSeq1=[CurItem]
        )
       ),
       longest_sequence(L, CurLen1, CurSeq1, MaxLen1, MaxSeq1, Len, Seq).
    

    Sample runs:

    ?- longest_sequence([1,6,11,12,13], Len, Seq).
    Len = 3,
    Seq = [11, 12, 13].
    
    ?- longest_sequence([1,6,11,12,13,2,3,4,5], Len, Seq).
    Len = 4,
    Seq = [2, 3, 4, 5].
    
    ?- longest_sequence([1,2], Len, Seq).
    Len = 0,
    Seq = [].