4
$\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$
  • 5
    $\begingroup$ Keeping your approach, what about doing: Cases[IntegerDigits[primes], id : {_, d .., _} :> Count[id, 1]]? $\endgroup$ – user31159 Oct 21 '16 at 19:48
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$
3
$\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$
1
$\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$
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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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