Generating long binary lists fast?
Here is an even faster and less procedural method!
First, we'll define a function pack
which will convert your list to the set of numbers {4, 12, 4, 64, 4}
from your example - as you can see, it's enough to uniquely identify the resulting sequence:
pack[l_List] := Module[{counts = Length /@ Split[Reverse@l]},
Riffle[
2^(counts[[;; ;; 2]]),
(Rest[PolygonalNumber[counts]] *
Most[2^Accumulate[counts]])[[;; ;; 2]]]]
It's pretty fast:
RepeatedTiming[pack[{1, 1, 0, 1, 1, 0, 0, 1, 1}]]
(* {0.0000120, {4, 12, 4, 64, 4}} *)
Next, we'll define a function to "unpack" this into an array of 0s and 1s:
join[l_, 1] := l
join[l_, n_] := Join[l, join[l, n - 1]] (* joins l with itself n times *)
unpack[{a_, b_, rest___}, start_] :=
unpack[{rest}, Join[join[start, a], ConstantArray[0, b]]]
unpack[{a_}, start_] := join[start, a]
gen2[l_] := unpack[pack[l], {1}]
Now let's compare and time the results:
gen2[{1, 1, 0, 1, 1, 0, 0, 1, 1}] ==
Elaborate[{1, 1, 0, 1, 1, 0, 0, 1, 1}] ==
gen[{1, 1, 0, 1, 1, 0, 0, 1, 1}, 512]
(* True *)
First@RepeatedTiming[gen2[{1, 1, 0, 1, 1, 0, 0, 1, 1}]]
(* 0.0000264 *)
First@RepeatedTiming[Elaborate[{1, 1, 0, 1, 1, 0, 0, 1, 1}]]
(* 0.0000345 *)
First@RepeatedTiming[gen[{1, 1, 0, 1, 1, 0, 0, 1, 1}, 512]]
(* 0.000052 *)
I think this might work for you:
Elaborate[aList_List] := Block[
{result, splitList, currentPosition},
result = {1};
currentPosition = 0;
splitList = Split[Reverse@aList];
(If[First[#] == 1,
Nest[AppendTo[result, #] &, result, Length[#]];
,
AppendTo[result,
Table[0, {Total[
2^# & /@
Range[currentPosition, currentPosition + Length[#] - 1]]}]]
];
currentPosition += Length[#];
) & /@ splitList;
Flatten[result]
];
If I set
input = {1, 1, 0, 1, 1, 0, 0, 1, 1};
Elaborate[input]
The result matches what you wrote.
Update with Timing:
I checked the timing and found the following:
RepeatedTiming[gen[{1, 1, 0, 1, 1, 0, 0, 1, 1}, 512]]
(* {0.000080,{...}} *)
RepeatedTiming[Elaborate[{1, 1, 0, 1, 1, 0, 0, 1, 1}]]
(* {0.0000523, {...}} *)
The method using a less procedural way is a little faster. Someone can probably think of how to speed up my code somewhat as well. There are different schools of thought on Parallelize, but that could be added if you don't have any concerns about it.