The following function is based on the Ramp
and Differences
functions, as suggested in a comment by @garej . Its speed and low memory are surprising.
rampDiff[list_] := Ramp@Prepend[Differences[list], First[list]]
It was tested against the following functions from previous answers and comments:
ClearAll["Global`*"]
erode1[list_] :=
Times[list,
Subtract[1, BitAnd[list, PadRight[list, Length@list, 0, 1]]]]
erode2[list_] := BitXor[ArrayPad[list, {1, -1}], list]*list
fcn = Function[{list},
Replace[Split[list],
l : {1, __} :> {1, ConstantArray[0, Length@l - 1]}, 1] //
Flatten];
bruteForce[list_] :=
Join[{list[[1]]},
Table[If[list[[i - 1]] == list[[i]] == 1, 0, list[[i]]], {i, 2,
Length[list]}]];
rep[a_] := a
rep[{1, a___}] := {1, {a} - 1}
repSplit[list_] := rep /@ Split@list // Flatten
shortest[list_] := (list //. {a___, 1, 1, Shortest[b___]} :> {a, 1, 0,
b})
caseDiff[list_] :=
Cases[Prepend[Differences[list], First[list]], x_ :> Boole[x == 1]]
The first test was to see that all of the functions give the same results.
functions = { shortest, bruteForce, repSplit, fcn, caseDiff, erode2,
erode1, rampDiff};
data = RandomChoice[{0, 1}, 10^4];
results = Through[functions[data]];
1 == Length@Union@results
(* True *)
The execution time and memory usage tests were conducted as follows.
Through[(Composition[AbsoluteTiming, MaxMemoryUsed, #] & /@
functions)[data]];
μsecs = Round[Transpose[{1000000, 1} Transpose[%]], 1];
Grid[Prepend[μsecs, {"μ-secs", "Bytes"}],
Alignment -> {Right, Baseline}]
(* μ-secs Bytes
600599 321656
7894 169720
6166 813704
4284 848216
5789 1291216
2737 720384
344 320856
230 160408 *)
In this test the rampDiff
function edged out erode1
in speed and bruteForce
in low memory usage. Thanks to @garej for suggesting it.
list//. {a___, 1, 1, Shortest[b___]} :> {a, 1, 0, b}
$\endgroup$Cases[Prepend[Differences[list], First[list]], x_ :> Boole[x == 1]]
$\endgroup$Ramp
to get a really cool solution. $\endgroup$Ramp
suggestion. It's fast, too. I used it an answer. $\endgroup$