Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given a list

list = {1,2,2,2,2,5,1,3,2,6,6,6,6,6,6,6,6,6,6,6,10,-3};

how to find the longest constant sublist (or equivalently the element and the number of times it is repeated)?

(in this example, {6,6,6,6,6,6,6,6,6,6,6} or {6,11})

share|improve this question
    
It looks like this question is almost a duplicate of Selecting a sublist based on Length, which shamefully the system had to point out to me. :-o –  Mr.Wizard Apr 14 at 23:48

4 Answers 4

up vote 5 down vote accepted

Concisely and reasonably efficiently:

Last @ Sort @ Split @ list
{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}

More efficiently:

# ~Extract~ Ordering[#, -1] & @ Split @ list
{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}

Multiple longest runs:

longestRuns[x_List] :=
  With[{sp = Split[x]},
    sp ~Extract~ Position[#, Max@#] &[Length /@ sp] & @ x
  ]

{1, 2, 2, 3, 4, 4, 5, 6} // longestRuns
{{2, 2}, {4, 4}}

Less efficiently but having fun with patterns:

list /. {___, seq : Longest[x_ ..], ___} :> {seq}
{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}
share|improve this answer

In Version 10 you can use the new function MaximalBy:

Split@list~MaximalBy~Length

{{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}}

You can also use it in the operator form:

MaximalBy[Length]@Split@list 
share|improve this answer
    
Wow, finally there is MaximalBy. Great! From time to time I need to do it myself before version 10 :) –  Yi Wang Apr 15 at 12:39

I post this somewhat ridiculous answer for 'fun', acknowledging all the given answers directly answer the question, esp Mr. Wizard. I post just ways of 'visualizing' longest run:

list = {1, 2, 2, 2, 2, 5, 1, 3, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
   10, -3};
With[{w = Union@list},
 ArrayPlot[Map[Function[x, Unitize[# - x] & /@ list], w], 
  FrameTicks -> {{Thread[{Range[Length@w], w}], 
     None}, {Range[Length@list], None}}]]

enter image description here

Of course you could ArrayPlot with your own color scheme.

Increasing the overkill:

ind = Range[Length@list];
gg = With[{pt = Partition[ind, 2, 1]}, 
   UndirectedEdge @@@ Pick[pt, Length@Union[list[[#]]] == 1 & /@ pt]];
gp = Graph[ind, gg, 
  VertexLabels -> 
   Thread[ind -> (Placed[
         Framed[#, Background -> Yellow, RoundingRadius -> 4], 
         Center] & /@ list)], 
  GraphLayout -> "HighDimensionalEmbedding", VertexSize -> 0, 
  PlotRangePadding -> {1, 2}, EdgeStyle -> Directive[Thick, Red]]

enter image description here

Note:

comp = ConnectedComponents[gp] /. Thread[ind -> list]

yields:

{{6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6}, {2, 2, 2, 
  2}, {5}, {3}, {1}, {10}, {1}, {2}, {-3}}

or increasing the overkill using CommunityGraphPlot:

CommunityGraphPlot[
 Graph[ind, gg, 
  VertexLabels -> 
   Thread[ind -> (Placed[
         Style[#, White, Bold, FontFamily -> "Kartika", 12], 
         Center] & /@ list)], VertexSize -> 1.5, 
  EdgeStyle -> Directive[Thick, Red]], ConnectedComponents[gp], 
 Method -> "Hierarchical", CommunityRegionStyle -> Green]

enter image description here

or showing the 'chain':

CommunityGraphPlot[
 Graph[UndirectedEdge @@@ Partition[ind, 2, 1], 
  VertexLabels -> 
   Thread[ind -> (Placed[
         Style[#, White, Bold, FontFamily -> "Kartika", 10], 
         Center] & /@ list)], VertexSize -> 1, EdgeStyle -> Thick], 
 ConnectedComponents[gp], CommunityRegionStyle -> Green, 
 ImageSize -> 800]

enter image description here

share|improve this answer
    
+1 , neat answer. –  rasher Apr 15 at 19:04

Faster, properly returns multiple sublists if there are more than one sequence with maximal length:

Module[{l = #, 
        sa = Append[SparseArray[Differences@#]["AdjacencyLists"], Length@#],
        sap, p},

   sap = Prepend[Most@sa + 1, 1];
   p = Pick[Transpose[{sap, sa}], sa - sap, Max[sa - sap]];
   l[[Span @@ #]] & /@ p] &[targetListHere]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.