6
$\begingroup$
a = 4;
primes = Prime[Range[PrimePi[10^(a - 1)] + 1, PrimePi[10^a]]];
d = 1;
Cases[IntegerDigits[primes], {_, d .., _}]

This gets me the list of the numbers from my list of primes that have more than one 1 in a row.

{{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 1},
{5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}}

Is there a way to get the length of the repeating digits? For instance, I'd rather get an output of

{3,3,2,2,3,2,2,2,3,2}

My goal is to get the count of the ones with the maximum length.

$\endgroup$
1
  • 5
    $\begingroup$ Keeping your approach, what about doing: Cases[IntegerDigits[primes], id : {_, d .., _} :> Count[id, 1]]? $\endgroup$
    – user31159
    Commented Oct 21, 2016 at 19:48

8 Answers 8

4
$\begingroup$

I emphasize that the OP wanted the longest sequence of 1s in a row.

Consider

it = {{1, 1, 1, 2, 2, 2, 2, 1, 1}}

Then, xavier's comment gives

Cases[it, id : {_, 1 .., _} :> Count[id, 1]]

{}

and Wouter's answer:

Max[Last /@ Tally[#]] & /@ it

{5}

which is incorrect.


This works:

Max /@ (Length /@ Select[#, MemberQ[#, 1] &] & /@ Split /@ it)

{3}

and on the exemplary

it = {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 1},
 {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}}

gives

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}


If 1 is dominant in all sublists (i.e., for sure the longest subsequence of repeating numbers consists of 1s), like in the case of the last it, this will also work:

Length /@ Last /@ Sort /@ Split /@ it
$\endgroup$
4
$\begingroup$

Using Longest

dat = {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 
    1, 1}, {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8,
     1, 1, 7}};
fun[lst_, d_] := 
 Cases[lst, {___, Longest[x__?(# == d &)], ___} :> Length@{x}]

So, fun[#, 1] &@dat yields:

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}
$\endgroup$
2
$\begingroup$
it={{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 1},
 {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}};    

now use:

Max[Last /@ Tally[#]] & /@ it

to get

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}
$\endgroup$
2
$\begingroup$

MaximalBy + Split + Length + Count

In versions 10.0+, you can use MaximalBy in combination with Split:

list = {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 1},
   {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}};

Composition[Length, First, MaximalBy[Count[#, 1]&], Split] /@ list

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}

Composition[Length, First, MaximalBy[Count[#, 1]&], Split]/@ {{1, 1, 1, 2, 2, 2, 2, 1, 1}}

{3}

$\endgroup$
2
$\begingroup$
list =
  {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 
    1}, {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}};

Using SequenceCount (new in 10.1) - short, but slow with long lists

SequenceCount[#, {1}] & /@ list

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}

Max[%]

3

$\endgroup$
2
$\begingroup$

Using SequenceCases:

list = {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1,
    1, 1}, {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8,
    1, 1, 7}};

Max[SequenceCases[#, {p : Repeated[1]} :> Length[{p}]]] & /@ list
(*{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}*)
$\endgroup$
1
$\begingroup$

One possibility is to use LongestCommonSubsequence:

longestRepeat[list_] := Length @ LongestCommonSubsequence[
    ConstantArray[1, Length[list]],
    list
]

On the OP example:

longestRepeat /@ list

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}

If speed is an issue, here is a simple Compile approach:

fc = Compile[{{l, _Integer, 1}}, 
    Module[{best=0, cur=0},
        Do[
            If[i==1,cur++; best=Max[best,cur], cur=0],
            {i,l}
        ];
        best
    ],
    RuntimeAttributes->{Listable}
];

We get the same result as before:

fc[list]

{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}

Let's compare the suggested answers on a larger example:

data = RandomInteger[1, {10^4, 100}];

r1 = longestRepeat /@ data; //AbsoluteTiming
r2 = fc[data]; //AbsoluteTiming
r3 = fun[data, 1]; //AbsoluteTiming
r4 = Max/@(Length/@Select[#,MemberQ[#,1]&]&/@Split/@data); //AbsoluteTiming (* corey979 *)
r5 = Composition[Length,First,MaximalBy[Count[#,1]&],Split]/@data; //AbsoluteTiming (* kglr *)

r1 === r2 === r3 === r4 === r5

{0.308581, Null}

{0.011777, Null}

{66.2261, Null}

{0.506145, Null}

{0.943818, Null}

True

$\endgroup$
1
$\begingroup$
list = {{1, 1, 1, 7}, {2, 1, 1, 1}, {2, 1, 1, 3}, {3, 1, 1, 9}, {4, 1, 1, 1},
        {5, 1, 1, 3}, {5, 1, 1, 9}, {6, 1, 1, 3}, {8, 1, 1, 1}, {8, 1, 1, 7}};

Using Split and Cases:

f = Length@First@Cases[{1 ..}]@Split@# &;

f /@ list

(*{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}*)

Max[%]

(*3*)

Or a slower version using Sequenceplit, only for didactic purposes:

f[l_] := Length@First@Cases[{1 ..}]@SequenceSplit[l, s : {x_} /; x != 1 :> s]

f /@ list

(*{3, 3, 2, 2, 3, 2, 2, 2, 3, 2}*)

Max[%]

(*3*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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