4
$\begingroup$

I have a sequence given below:

seq = {{1, 2}, {2, 1}, {2, 2}, {3, 2}, {3, 4}, {4, 2}, {5, 1}, {6,2},
{7, 3}, {8, 4}, {9, 2}, {10, 2}, {10, 3}, {10, 4}, {10,5}, {11, 2}}

I split the list according to the first element

splitlist = SplitBy[seq, First]
{{{1, 2}}, {{2, 1}, {2, 2}}, {{3, 2}, {3, 4}}, {{4, 2}}, {{5,1}},
{{6, 2}}, {{7, 3}}, {{8, 4}}, {{9, 2}}, {{10, 2}, {10,3}, {10, 4}, {10, 5}}, {{11, 2}}}

then decreasing the brackets by 1

splitlist //. {x_} :> x

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

Now i wish to find a repeated rule (//.) such that i can group all the consecutive lists of 2 elements together into a single list i.e. {... {{4, 2}, {5, 1}, {6,2}, {7, 3},{8, 4}, {9,2}} ....}

{{1, 2}, {{2, 1}, {2, 2}}, {{3, 2}, {3, 4}}, 

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

{{10, 2}, {10, 3}, {10, 4}, {10, 5}}, {11, 2}} 

Any pattern that can group sublists of elements 2 when they appear consecutively?

$\endgroup$
2
$\begingroup$

So if I understand correctly, you want to group the consecutive pairs ({_Integer, _Integer}) at at the first level. Is that correct? In that case, this should probably do the trick:

FixedPoint[
  Replace[#,
    {x1___, 
     x : Longest @ Repeated[{_Integer, _Integer}, {2, \[Infinity]}], 
     x2___} :> {x1, {x}, x2},
    {0}
  ]&,
  {{1, 2}, {{2, 1}, {2, 2}}, {{3, 2}, {3, 4}}, {4, 2}, {5, 1}, {6, 2},
   {7,3}, {8, 4}, {9, 2}, {{10, 2}, {10, 3}, {10, 4}, {10, 5}}, {11, 2}}
]

If you want to apply this at lower levels, you can change the level spec of the Replace. If you want to find other elements that are not lists (instead of just _Integer), you can go with something like {Except[_List], Except[_List]}

Hope this helps.

$\endgroup$
  • $\begingroup$ Thanks. it works for a larger set. I was making a mistake :) $\endgroup$ – Ali Hashmi Oct 21 '16 at 16:30
  • $\begingroup$ btw, please replace x1__ (two underscores) to x1___ (three underscores) and x2__ to x2___ to take care of end cases because for a list like {{1, 2}, {{2, 1}, {2, 2}}, {{3, 2}, {3, 4}}, {4, 2}, {5, 1}, {6, 2}, {7,3}, {8, 4}, {9, 2}, {{10, 2}, {10, 3}, {10, 4}, {10, 5}}, {11, 2},{12,4}} your current implementation will give trouble $\endgroup$ – Ali Hashmi Oct 21 '16 at 16:36
  • $\begingroup$ Thanks Ali, you're completely correct. I adapted the answer as such. $\endgroup$ – Sjoerd Smit Oct 24 '16 at 8:36
4
$\begingroup$

One step back to go two steps forward:

Split[splitlist, Length @ #1 == Length @ #2 == 1 &] //. {x_} :> x

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


To use PartitionRagged, for fun:

parts = Length /@ Split[Length /@ splitlist, #1 == #2 == 1 &]

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

Internal`PartitionRagged[splitlist, parts] //. {x_} :> x

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

$\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.