How to pick increasing numbers from the list
Just to be different:
Block[{i = -∞}, Select[lst, # > i && (i = #) == i &]]
Note: Alexey Popkov points out that this solution relies on Select
testing each element in turn from left to right, which is not documented.
One can use LongestAscendingSequence
with a small modification (you need to fix the first element)
Prepend[LongestAscendingSequence@Pick[Rest[#], UnitStep[#[[1]] - Rest[#]], 0], #[[1]]] &@
{5, 3, 6, 2, 7, 4, 8}
{5, 6, 7, 8}
It should be fast for a very long list.
Update
After OP's comment I propose
Prepend[Sort@Pick[Rest[#], UnitStep[#[[1]] - Rest[#]], 0], #[[1]]] &@
{5, 3, 2, 4, 2, 7, 5, 6, 3, 8}
{5, 6, 7, 8}
Fold
ing is fine, but Flatten
ing a nested list is faster than repeated Join
ing,
and Compile
ing is more than an order of magnitude faster yet.
upseq = Compile[{{a, _Integer, 1}}, Module[{b = a, n = 1},
Do[If[a[[i]] > b[[n]], b[[++n]] = a[[i]]], {i,2,Length[a]}]; b[[;;n]]]];
a = With[{n = 10^5}, Range@n + RandomInteger[999,n]];
Timing@Length[a1 = Fold[If[#2 > Last@#1, Join[#1,{#2}], #1] &, {First@a}, Rest@a]]
Timing@Length[a2 = Flatten@Fold[If[#2 > Last@#1, {#1,#2} , #1] &, {First@a}, Rest@a]]
Timing@Length[a3 = upseq@a]
SameQ[a1,a2,a3]
{1.19, 3942}
{0.55, 3942}
{0.02, 3942}
True