4

We have a vector of zeros and other numbers, f.e:

vector = {0, 0, 0, 9, 0, 2, 0, 5, 0, 4, 0, 5, 6, 2, 0};

The two rules:

Partition the vector in such a way that (1) at most two zeros are in one bin and (2) no bin should contain more than five elements.

The correct result for the above vector would be:

{{0, 0}, {0, 9, 0}, {2, 0, 5, 0}, {4, 0, 5, 6, 2}, {0}}

Doesn't sound too difficult, but I was only able to find a procedural solution:

Baskets[dt_] :=
 Module[{rl = {}, sl = {}, n = 1, le = Length[dt]},
  While[n < le,
   While[Length[sl] < 5 && Count[sl, 0] < 2 && n <= le,
    AppendTo[sl, dt[[n++]]]];
   AppendTo[rl, sl];
   sl = {}];
  If[Length @ Flatten[rl] < le, AppendTo[rl, {dt[[-1]]}]];
  rl]

Baskets[{0, 0, 0}]

{{0, 0}, {0}}

Baskets[{0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0}]

{{0, 0}, {1, 0, 0}, {1, 0, 1, 0}, {0, 0}, {0}}

What would a functional solution look like?

eldo
  • 67,911
  • 5
  • 60
  • 168
  • Would this not be a correct solution: {{0, 0}, {0, 9, 0, 2}, {0, 5, 0, 4}, {0, 5, 6, 2, 0}}? This related post can solve such tasks. – Syed Aug 10 '23 at 14:21
  • Almost - if the last bin would be {0, 5, 6 , 2, 0}. I think it is easier to run from left to right and stop when one of the two rules is fulfilled, in this case, when a 2nd zero is found. – eldo Aug 10 '23 at 14:22
  • My bad, I corrected this after deleting the previous comment, you are right. I am using cSplit3[vector, Length[#] <= 5 && Count[#, 0] <= 2 &] – Syed Aug 10 '23 at 14:24

2 Answers2

6

Here's one way

SequenceCases[vector, _?(Count[#, 0] <= 2 && Length[#] <= 5 &)]
lericr
  • 27,668
  • 1
  • 18
  • 64
  • Thank you, this really motivates me to learn more about the Sequence-functions (I only recently upgraded) – eldo Aug 10 '23 at 16:24
4
ClearAll[f]
f[val_, maxcount_, binlength_] := Module[{$s = 0, $l = 0}, 
   Split[#, 
    Or[($s += Boole[# == val]) < maxcount && ++$l < binlength, 
       $s = 0; $l = 0] &]] &

f[0, 2, 5] @ vector
{{0, 0}, {0, 9, 0}, {2, 0, 5, 0}, {4, 0, 5, 6, 2}, {0}}
kglr
  • 394,356
  • 18
  • 477
  • 896