6

I have a list of numbers like l1 = (1,2,3,4,8) and clearly, l1 is in order (next number is greater than previous number).

Well, I have a list of l2 = {1,2,4,3,8}. Because 3 is not in order, I want to drop 3 so that I have a new list of l2new = {1,2,4,8} which is now in order.

What is the algorithm to have l2new from l2?

To clarify my purpose, I introduce another example: If I have l3 = {1,2,8,4,5}, then I want to have l3new = {1,2,8}.

creidhne
  • 5,055
  • 4
  • 20
  • 28
cheese.burger
  • 435
  • 2
  • 9

7 Answers7

9

Maybe something like this:

IncreasingSubset[list_] := 
  Fold[If[#2 >= Last[#1], Append[#1, #2], #1] &, {First@list}, Rest@list]

Try it:

IncreasingSubset[l3]
(* {1, 2, 8} *)
lericr
  • 27,668
  • 1
  • 18
  • 64
9

Another way is as follows:

ddlist[lst_] := Tally[lst, #2 <= #1 &][[All, 1]]

Test:

l2 = {1, 2, 4, 3, 8};
l3 = {1, 2, 8, 4, 5};
l4 = {1, 2, 5, 3, 4, 6};
ddlist[l2]
(*{1, 2, 4, 8}*)
ddlist[l3]
(*{1, 2, 8}*)
ddlist[l4]
(*{1, 2, 5, 6}*)
E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
5

One way, probably not the most efficient:

ddb[alist_] := 
 FoldPair[{If[#1[[-1]] <= #2, Join[#1, {#2}], #1], 
    If[#1[[-1]] <= #2, Join[#1, {#2}], #1]} &, alist[[1 ;; 1]], 
  alist[[2 ;;]]]

Checks:

ddb[{1, 2, 3, 4, 8}]
(* {1, 2, 3, 4, 8} *)
ddb[{1, 2, 4, 3, 8}]
(* {1, 2, 4, 8} *)
ddb[{1, 2, 8, 4, 5}]
(* {1, 2, 8} *)
b.gates.you.know.what
  • 20,103
  • 2
  • 43
  • 84
5

Perhaps:

f[u_] := u //. {a___, b_, c_, d___} /; b > c :> {a, b, d}

For, example:

Column[# -> f@# & /@ {{1, 2, 4, 3, 8}, {1, 2, 8, 4, 5, 12}, {1, 2, 8, 
    4, 5, 6, 12}, {2, 1}, {2, 1, 3, 4}}]

enter image description here

ubpdqn
  • 60,617
  • 3
  • 59
  • 148
4

First a test case:

All troughs need to be removed from the sublists. The following will provide a visual feedback.

FixedPointList[
 First /@ Split[#, Greater] &, {1, 2, 4, 3, 8, 6, 10, 11, 7, 10}]
ListLinePlot /@ %

enter image description here


Using FixedPoint:

lists = {{1, 2, 3, 4, 8}, {1, 2, 4, 3, 8}, {1, 2, 8, 4, 5}, {1, 2, 5, 
    3, 4, 6}, {2, 1}, {2, 1, 3, 4}, {1, 2, 4, 8, 5, 12}, {1, 2, 4, 3, 
    8, 6, 10, 11, 7, 10}};

{# -> FixedPoint[First /@ Split[#, Greater] &, #] & /@ lists } // Map[Column]

enter image description here

Syed
  • 52,495
  • 4
  • 30
  • 85
  • lists has elements that have been borrowed from other answers on the page with thanks. – Syed Jun 28 '23 at 11:47
2

A late and simple answer:

list = {1, 2, 4, 3, 8};

Union @ FoldList[Max] @ list

{1, 2, 4, 8}

Example data from earlier answers:

lists = {{1, 2, 3, 4, 8}, {1, 2, 4, 3, 8}, {1, 2, 8, 4, 5}, {1, 2, 5, 
    3, 4, 6}, {2, 1}, {2, 1, 3, 4}, {1, 2, 4, 8, 5, 12}, {1, 2, 4, 3, 
    8, 6, 10, 11, 7, 10}};

-> Union @ FoldList[Max, #] & /@ lists // Column

enter image description here

eldo
  • 67,911
  • 5
  • 60
  • 168
0

You can say:

l2new = Split[l2, Greater][[All,1]]
MeMyselfI
  • 1,116
  • 5
  • 12