Grouping and repeating the grouped rows inside a matrix

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

Flatten[ConstantArray[#, #[[1, 1]]] & /@ Split[m, #2[[1]] == 0 &], 2]

$\left( \begin{array}{ccc} 3 & 1 & 2 \\ 0 & 5 & 1 \\ 3 & 1 & 2 \\ 0 & 5 & 1 \\ 3 & 1 & 2 \\ 0 & 5 & 1 \\ 1 & 4 & 2 \\ 0 & 6 & 9 \\ 0 & 4 & 7 \\ 2 & 6 & 8 \\ 2 & 6 & 8 \\ \end{array} \right)$

Here is the explanation for the above one-line code:

Flatten[ConstantArray[#, #[[1, 1]]] & /@ Split[m, #2[[1]] == 0 &], 2]

  1. First, Split function scans through the matrix m by taking two consecutive rows (#1, #2) and checks for the condition such that the 2nd row's first element is equal to zero (#2[[1]] == 0&), if it is True then it will add it to the group, otherwise it will add a split and start a new group, thereby grouping the matrix as show in the above example figure in the question section.
  2. Then, ConstantArray function is mapped (/@) onto the grouped (split) matrix such that it will replicate the grouped rows inside the matrix, "1st row's first element" (#[[1, 1]]) number of times, thereby replacing grouped rows with repeated rows.
  3. Finally, Flatten function flattens out the resultant list by removing all the unwanted curly braces up to the 2nd level, thereby creating the final resultant matrix.

This could be a starter for discussions:

A = RandomInteger[{0, 3}, {6, 3}];
idx = Pick[Range[Length[A]], Unitize[A[[All, 1]]], 1];
B = Join @@ MapThread[
    Join @@ ConstantArray[A[[#1 ;; #2]], A[[#1, 1]]] &,
    {
     idx,
     Append[Rest@idx - 1, Length[A]]
     }
    ];

Hm. Building the list of rows first and to read from A only once seems to be slightly faster.

idx = Pick[Range[Length[A]], Unitize[A[[All, 1]]], 1];
B2 = A[[
   Join @@ Join @@ MapThread[
      ConstantArray[Range[#1, #2], #3] &,
      {idx, Append[Rest@idx - 1, Length[A]], A[[idx, 1]]}
      ]
   ]];

m = {{3, 1, 2}, {0, 5, 1}, {1, 4, 2}, {0, 6, 9}, {0, 4, 7}, {2, 6, 8}}
SequenceReplace[m, seq : {{x_ /; x > 0, __}, 
                   Repeated[{0, __}, {0, Infinity}]} :> Table[seq, x]]
Flatten[%, 2]