Post Reply 
50G Fully new Ver 11 Lists Manipulation REPLACE, SWAP, KEEP, INSERT, DELETE, MOVE
11-26-2024, 11:48 PM (This post was last modified: Yesterday 03:01 PM by Gil.)
Post: #1
50G Fully new Ver 11 Lists Manipulation REPLACE, SWAP, KEEP, INSERT, DELETE, MOVE
Here are, for manipulating lists, 22 basic programs contained in a directory called LIST.

The version 10 was already quite different from previous thread & version 8 that contained only 6 programs but of cumbersome use, thread that I might therefore later delete to avoid confusion.

The version 10 was a corrected and improved version of the versions 9, in particular regarding the speed.

This new version 11 enables now to give several positions — instead of one single position —, look for the corresponding elements and a) insert (with pINS) before them, in one single step, new elements or b) replace (with pRPL) them, in one single step, by new elements.

The list of the 22 programs is the following

NoRPT, e1POS,
nFIRST, e1FIRST,
nLAST, e1LAST,
pKEEP, KEEP, eKall,
pDEL, eDEL, eDall,
pRPL (new version!), e1RPL, e1Rall,
pINS (new version!), e1INS, e1Iall,
pSWAP,
ppMOV, epMOV and ep&MOV

Besides, there are now two variable-program subroutines at the end of the directory: l.test and p1ins. The first one, l.test, is used in many main programs to spare memory space & not to be used separately. The second one, p1.ins, equally not to be used separately, is used in pINS (and pRPL).

Rough explanations about arguments & names

Each main program always takes as first argument the original list to be treated. Then comes the argument "where" to be possibly completed by "what".

pXXX
Program XXX takes as second argument a position p or several positions pi, pk,..., pm.

eXXX
Program XXX takes as second argument an element e or several elements eI, eK,... e.M.
It executes juste once the function KEEP, DELETE, REPLACE or INSERT.

eXXXALL
Contrarily to EXXX, it procedes to all possible KEEP, DELETE, REPLACE or INSERT.

p1XXX or e1XXX
The 1 is to remind that here, as second argument "where" (after the original list), only one position or element can be given.


Dealing with one/many elements or positions

When dealing with a single precise element e, always write that single element e exactly as it appears or should appear in the original list.
So, for instance, if you want to INSERT or DELETE the single element consisting of a list of elements, ie {E1, E2, ..., En}, just enter the corresponding element-argument as {E1, E2, ..., En}.
So original {A, B, C, D} followed by 2 { N1, N2, N3} p1INS will give {A, {N1, N2, N3}, B, C, D}.

Whereas, when dealing, in one step, with several elements E1, E2,..., En, write them as a list {∞∞∞, E1, E2, ..., En}, adding at the first place the element ∞∞∞ (3 times the infinity symbol).
So, for instance, if you want to INSERT or DELETE, in one step, many separate elements E1, E2,..., En, then the corresponding elements-argument should be the list {∞∞∞, E1, E2...En}.
So original {A, B, C, D} followed by 2 {∞∞∞, N1, N2, N3} p1INS will give {A, N1, N2, N3, B, C, D}.

When dealing, in one step, with many positions pi, pk,...pm, no confusion is possible : write simply the corresponding positions-arguments
as the list {pi, pk,...pm}.
If you want to deal with consecutive positions, say position 3, position 4, position 5, position 6, postion 7, instead of writing the single argument {3,4,5,6,7}, which is always possible, just write two argument : 3 (starting position) & 7 (last position), or 7 3 (the order does not matter).

If you want to specify the last position of a list whose size you ignore, just write ∞ (the infinity symbol).


More details

noRPT
1 Arg: original list.
Goal: suppress repeated elements.

e1POS
2 Arg: List
& 1 single-Elem
(as shown in List)
Goal: find all the positions where the element e appears in the original list.

nFIRST
2 Arg: List & n
(n 1st El.
 or ∞ for all El.)
Goal: build a list with the first n elements of the original list.

e1FIRST
3 Arg: List & 1+2
1) Elem.I (1st occurr
in List)
2) 1 (if Elem.I incl.)
or 0 (if I exclud.)
Goal: build a list with the first elements of the original list up to first occurrence of the given element e.

nLAST
2 Arg: List & n
(n last El.
 or ∞ for all El.)
Goal: build a list with the last n elements of the original list.

e1LAST
3 Arg: List & 1+2
1) Elem.I (last occur
in List)
2) 1 (if Elem.I incl.)
or 0 (if I exclud.)
Goal: build a list starting, backward, with the last element of the original list up to first occurrence (backward) of the given element e.

pKEEP
3/2 Arg: List & a/b/c
a)Pos.beg
Pos.end
(from Posbeg to Posend)
b)or {Pos.i Pos.k... }
(for specif. Pos i k... )
c)or just Pos or {Pos}
∞ means last Pos.
Goal: keep the unknown elements corresponding to positions I, k,...

eKEEP
2 Arg: List & a/b/c
a) If many Elem:
{∞∞∞ El.I El.K... }
(list begin. w/ ∞∞∞)
b) If just 1 Elem: El.
Goal (not very useful): keep just once, in the order of their first appearance in the original list, the given elements.

eKall
2 Arg like eKEEP
Goal (not very useful): keep, in the order of their appearance in the original list, all the occurrences of the given elements.

pDEL
3/2 Arg: List & a/b/c
a)Pos.beg
Pos.end
(from Posbeg to Posend)
b)or {Pos.i Pos.k }
(as a list)
c)or just Pos or {Pos}
∞ means last Pos
Goal: instead of pKEEP, delete the unknown elements corresponding to positions i, k,...

eDEL
2 Arg: List & a/b
a)If many Elem:
 {∞∞∞ Elem.I Elem.K... }
(list begin. w/ ∞∞∞)
b)If just 1 Elem: Elem
Goal: instead of eKEEP, delete —but again just once—, in the order of their first appearance in the original list, the given elements.

eDall
2 Arg like eDEL
Goal: delete all the occurrences of the given elements.

pRPL
3 Arg: List & 1+2
1)PosExact (not after) or list of exact positions
(with ∞ to designate last posit)
2)Replac. by one element or list of elements
NB: If one special element Ei is replaced by many Elements Eia, Eib, Eic..,
write this special replacement in a list {∞∞∞ E.ia Ei.b Eic...  }
(list begin. w/ ∞∞∞)
Goal: replace, at given positions p1, p2..., the corresponding elements E1, E2,... by new elements:
E1—> E1new (or E1—> E1a, E1b, E1c...);
E2—> E2new (or E2—> E2a, E2b, E2c...); etc.

e1RPL
3 Arg: List & 1+2
1)1 single Elem.I
(Elem.I in List)
2)Replac. by many el:
{∞∞∞ El.1 El.2... }
(list begin. w/ ∞∞∞)
or by 1 elem: elem
Goal: replace 1st occurrence of one single given element by one or more elements.

e1Rall
3 Arg like e1RPL
Goal: replace all occurrences of one single given element by one or more elements.

pINS
3 Arg: List 1+2
1)PosExact (not after) or list of exact positions
(with ∞ to insert before last posit)
(with '∞+1' to add/insert after last position)
2)One element or list of elements to be inserted
NB: If, just before one special element Ei, many Elements Eia, Eib, Eic..,
are to be inserted, write this special insertion in a list {∞∞∞ E.ia Ei.b Eic...  }
(list begin. w/ ∞∞∞).

e1INS
4 Arg: List & 1+2+3
1)Single Elem.I (in
List where to insert)
2)1 (if after Elem.I)
or 0 (if before I)
3)Many elem inserted:
{∞∞∞ El.1 El.2 }
(list begin. w/ ∞∞∞)
or 1 elem: elem
Goal: insert, at 1st occurrence of the single given element, after it or before it, one or more elements.

e1Iall
4 Arg like e1INS
Goal: insert, for each occurrence of the single given element, always after it or always before it, one or more elements.

pSWAP
3/2 Arg: List & a/b
a) Pos.i
Pos.k
b) or {Pos.i Pos.k}
(as a list)
Goal: exchange the place of two elements, an element I taking the place of element K, whereas the element K going to initial position of element I.

ppMOV
3/2 Arg: List & a/b
a) Pos.i (init)
(to new) Pos.k
b) or {Pos.i Pos.k}
(as a list)
i, k greater or equal to 1
∞ means at the end
Goal: move an unknown element I in position i to position k.

epMOV
3 Arg: List & 1 + 2
1) 1 single Elem
(as shown in List)
2) new posit.i
i greater or equal to 1
∞ means at the end
Goal: move the first occurrence of the given element to position i.

ep&MOV
3 Arg: List & 1+2
1) 1 single Elem
(as shown in List)
2) n (El moved to pos
'unknown pos.El'+n)
'unknown pos.El'+n greater or equal to 1
∞ means at the end
Goal: move the first occurrence of the given element to new position = "old position of that element +n".


Example
Initial list in stack level 3: { 10 20 30 40 50 60 70 }
Replace 2nd element, 4th element, 5th element, last element (, here for last/7th element)
Put then in stack level 2: { 2 4 5 } (or {2 4 5 7}, if you know the size of the initial list).
Replace the 2nd element (ie 20) by the list {21 22} —> list {21 22}.
Replace the 4th element (ie 40) by the 2 elements 41 and 42—> list { ∞∞∞ 41 42}
Replace the 5th element (ie 50) by 55 —> 55
Replace the 7th element (ie 70) by 77 —> 77
Put then in stack level 1 the above elements in a list: { { 21 22} { ∞∞∞ 41 42 } 55 77 }
Pressing pRPL will give { 10 { 21 22 } 30 41 42 55 60 77 }.

Codes

Code:

DIR
  noRPT
  \<< "1 Arg: List
(to get 0 RePeTition)
" DROP DUP SIZE \-> L S
    \<< { } 1 S
      FOR i L i GET DUP2 POS 0 ==
        IF
        THEN 1 \->LIST +
        ELSE DROP
        END
      NEXT DUP SIZE S SWAP - R\->I "Deleted" \->TAG
    \>>
  \>>
  e1POS
  \<< "2 Arg: List 
   & 1 single-Elem
   (as shown in List)
" DROP DUP2 DTAG \-> L e
    \<< { } 1 L SIZE
      FOR i L i GET e SAME
        IF
        THEN i +
        END
      NEXT :: R\->I MAP "In Pos" \->TAG DUP DTAG SIZE R\->I "x" + ROT SWAP \->TAG SWAP
    \>>
  \>>
  nFIRST
  \<< "2 Arg: List & n
    (n 1st El.
     or \oo for all El.)
" DROP OVER SIZE MIN 1 SWAP SUB
  \>>
  e1FIRST
  \<< "3 Arg: List & 1+2
1) Elem.I (1st occurr
           in List)
2) 1 (if Elem.I incl.)
   or 0 (if I exclud.)
" DROP NOT UNROT OVER SWAP POS ROT - 1 SWAP SUB
  \>>
  nLAST
  \<< "2 Arg: List & n
    (n last El.
     or \oo for all El.)
" DROP OVER SIZE DUP ROT - 1 + 1 MAX SWAP SUB
  \>>
  e1LAST
  \<< "3 Arg: List & 1+2
1) Elem.I (last occur
           in List)
2) 1 (if Elem.I incl.)
   or 0 (if I exclud.)
" DROP ROT REVLIST UNROT e1FIRST REVLIST
  \>>
  pKEEP
  \<< "3/2 Arg: List & a/b/c
a)\|>Pos.beg \|>Pos.end
(from Posbeg \-> Posend)
b)or \|>{Pos.i Pos.k }
(for specif. Pos i k)
c)or just Pos or {Pos}

\oo means last Pos.
" DROP 1 \-> \<-keep
    \<< pDEL
    \>>
  \>>
  eKEEP
  \<< "2 Arg: List & a/b/c
a) If many Elem:
   {\oo\oo\oo El.I El.K }
  (list begin. w/ \oo\oo\oo)
b) If just 1 Elem: El.
" DROP 1 \-> \<-keep
    \<< eDEL
    \>>
  \>>
  eKall
  \<< "2 Arg: like eKEEP
" DROP 0 1 \-> \<-L \<-l \<-keep \<-q
    \<< l.test '\<-l' STO { } 1 \<-L SIZE
      FOR i \<-l \<-L i GET POS 0 \=/
        IF
        THEN \<-L i GET DUP TYPE 5 == { 1 \->LIST } IFT +
        END
      NEXT
    \>>
  \>>
  pDEL
  \<< "3/2 Arg: List & a/b/c
a)\|>Pos.beg \|>Pos.end
(from Posbeg \-> Posend)
b)or \|>{Pos.i Pos.k }
      (as a list)
c)or just Pos or {Pos}

\oo means last Pos.
" DROP OVER SIZE
    IFERR \<-keep
    THEN 0
    END \-> L l S \<-keep
    \<<
      CASE L TYPE 5 \=/ l TYPE 5 \=/ AND
        THEN { } L EVAL l EVAL DUP2 > { SWAP } IFT 4 PICK SIZE MIN
          FOR i i +
          NEXT SWAP DUP SIZE 'S' STO 'L' STO
        END l TYPE 5 \=/
        THEN l EVAL S MIN 1 \->LIST
        END l
      END SORT 1. * 'l' STO { } 1 L SIZE
      FOR i l i POS 0 \<-keep { \=/ } { == } IFTE
        IF
        THEN L i GET DUP TYPE 5 == { 1 \->LIST } IFT +
        END
      NEXT
    \>>
  \>>
  eDEL
  \<< "2 Arg: List & a/b
a)If many Elem:
  {\oo\oo\oo Elem.I Elem.K}
  (list begin. w/ \oo\oo\oo)

b)If just 1 Elem: Elem
" DROP
    IFERR \<-keep
    THEN 0
    END 1 \-> \<-L \<-l \<-keep \<-q
    \<< l.test '\<-l' STO \<-L { } 1 \<-l SIZE
      FOR i \<-L \<-l i GET POS +
      NEXT
      IF \<-keep 1 ==
      THEN pKEEP
      ELSE pDEL
      END
    \>>
  \>>
  eDall
  \<< "2 Arg: like eDEL
" DROP 0 1 \-> \<-L \<-l \<-keep \<-q
    \<< l.test '\<-l' STO { } 1 \<-L SIZE
      FOR i \<-l \<-L i GET POS 0 ==
        IF
        THEN \<-L i GET DUP TYPE 5 == { 1 \->LIST } IFT +
        END
      NEXT
    \>>
  \>>
  pRPL
  \<< "3 Arg: List & 1+2
1)Pos.i
or {Pos.i Pos.k }
(for specif. Pos i k)
2)El.I
or {El.I El.K }

El.I (El.K) can be
a) 1 single El: El.
   or {El.I1 El.I2}
b) many new El:
  {\oo\oo\oo El.I1 El.I2}
  (list begin. w/ \oo\oo\oo)

\oo means last Pos.
" DROP 1 \-> \<-rep
    \<< pINS
    \>>
  \>>
  e1RPL
  \<< "3 Arg: List & 1+2
1)1 single-Elem.I
  (Elem.I in List)
2)Replac. by many el:
  {\oo\oo\oo El.1 El.2 } 
  (list begin. w/ \oo\oo\oo)

  or by 1 elem: elem
" DROP PICK3 ROT POS SWAP p1RPL
  \>>
  e1Rall
  \<< "3 Arg: like eRPL
" DROP SWAP 1 \->LIST 0 0 \-> \<-L \<-l e \<-keep \<-q
    \<< l.test '\<-l' STO { } 1 \<-L SIZE
      FOR i e \<-L i GET POS 0 \=/
        IF
        THEN \<-l
        ELSE \<-L i GET DUP TYPE 5 == { 1 \->LIST } IFT
        END +
      NEXT
    \>>
  \>>
  pINS
  \<< "3 Arg: List & 1+2
1)Pos.i
or {Pos.i Pos.k }
(for specif. Pos i k)
2)El.I
or {El.I El.K }

El.I (El.K) can be
a) 1 single El: El.
   or {El.I1 El.I2}
b) many new El:
  {\oo\oo\oo El.I1 El.I2}
  (list begin. w/ \oo\oo\oo)
    \oo before last Pos.
'\oo+1' after last Pos.
" DROP
    IFERR \<-rep
    THEN 0
    END 0 0 0 \-> L l l2 \<-rep s lh ls
    \<< l DUP TYPE 5 \=/ { 1 \->LIST } IFT DUP SIZE 's' STO \->STR "'\oo+1'" L SIZE 1 + \->STR SREPL DROP "\oo" L SIZE \->STR SREPL DROP OBJ\-> DUP SORT 'ls' STO 'l' STO { } 1 s
      FOR i l ls i GET POS +
      NEXT 'lh' STO
      IF s 1 ==
      THEN l2 1 \->LIST 'l2' STO
      END { } 1 s
      FOR i l2 lh i GET GET 1 \->LIST +
      NEXT 'l2' STO
      IF s 1 >
      THEN ls HEAD 1 \->LIST 2 s
        FOR i l2 i 1 - GET \-> e
          \<< e TYPE 5 == e SIZE 1 > AND
            IF
            THEN e HEAD '\oo\oo\oo' SAME
              IF
              THEN e SIZE 2 - 1 \<-rep NOT * +
              ELSE 1 \<-rep NOT *
              END
            ELSE 1 \<-rep NOT *
            END
          \>> ls ADD DUP 'ls' STO i GET +
        NEXT
      ELSE ls
      END 'ls' STO L 1 s
      FOR i ls i GET l2 i GET p1ins
      NEXT
    \>>
  \>>
  e1INS
  \<< "4 Arg: List & 1+2+3
1)Single Elem.I (in
 List where to insert)
2)1 (if after Elem.I)
   or 0 (if before I)
3)Many elem inserted:
  {\oo\oo\oo El.1 El.2 } 
  (list begin. w/ \oo\oo\oo)

   or 1 elem: elem
" DROP 0 \-> L e p01 l p
    \<< L e POS DUP 'p' STO 0 ==
      IF
      THEN e "In List, no " \->TAG
      ELSE L p p01 + l p1ins
      END
    \>>
  \>>
  e1Iall
  \<< "4 Arg: like eINS
" DROP ROT 1 \->LIST \-> L p l e
    \<<
      CASE l TYPE 5 \=/
        THEN l 1 \->LIST
        END l SIZE 0 ==
        THEN l 1 \->LIST
        END l SIZE 1 == l HEAD TYPE 5 \=/ AND
        THEN l 1 \->LIST
        END l SIZE 1 == l HEAD DUP TYPE 5 == SWAP SIZE 1 \<= AND AND
        THEN l 1 \->LIST
        END l
      END 'l' STO { } 1 L SIZE
      FOR i L i GET DUP TYPE 5 == { 1 \->LIST } IFT e L i GET POS 0 \=/
        IF
        THEN l p NOT { SWAP } IFT +
        END +
      NEXT
    \>>
  \>>
  pSWAP
  \<< "3/2 Arg: List & a/b
a) \|>Pos.i \|>Pos.k
b) or \|>{Pos.i Pos.k}
       (as a list)
\oo means at the end
" DROP 0 0 \-> p1 p2 L S
    \<< p2 TYPE 5 == p2 SIZE 2 == AND
      IF
      THEN p1 p2 OBJ\-> DROP
      ELSE p1 p2
      END ROT DUP SIZE 'S' STO UNROT S MIN SWAP S MIN 3 \->LIST { L p1 p2 } STO L p1 GET L p2 GET L p1 ROT PUT p2 ROT PUT
    \>>
  \>>
  ppMOV
  \<< "3/2 Arg: List & a/b
a) \|>Pos.i (init)
   (to new) \|>Pos.k
b) or \|>{Pos.i Pos.k}
       (as a list)

i, k \>= 1
\oo means at the end
" DROP DUP TYPE 5 == { OBJ\-> DROP } IFT EVAL PICK3 SIZE MIN SWAP PICK3 SIZE MIN SWAP UNROT DUP2 GET \-> p2 L p1 e
    \<< L p1 '\oo\piei\oo' PUT p1 pDEL p2 '\oo\piei\oo' p1ins p2 e PUT
    \>>
  \>>
  epMOV
  \<< "3 Arg: List & 1 + 2
1) 1 single-Elem
   (as shown in List)
2) new posit.i

i \>= 1
\oo means at the end
" DROP UNROT OVER SWAP POS ROT ppMOV
  \>>
  ep&MOV
  \<< "3 Arg: List & 1+2
1) 1 single-Elem
   (as shown in List)
2) n (El moved to pos
   'unknown pos.El'+n)

'unknown pos.El'+n \>= 1
\oo means at the end
" DROP UNROT OVER SWAP POS ROT OVER + ppMOV
  \>>
  l.test
  \<<
    IFERR \<-q
    THEN 0
    END 0 \-> q l
    \<< \<-l DUP DUP TYPE 5 == SWAP SIZE 0 \=/ AND
      IF
      THEN DUP HEAD '\oo\oo\oo' SAME
        IF
        THEN \<-L SWAP POS 0 == q 0 == OR
          IF
          THEN \<-l TAIL
          ELSE "Below exact string
" \<-l \->STR + "
is already in List!
" + "Use it this way (1)
or rather the " + \<-l TAIL DUP 'l' STO SIZE R\->I DUP 2 \>= { + } { DROP } IFTE " el. in
" + l \->STR + " (2)" + "" INPUT OBJ\-> 1 ==
            IF
            THEN \<-l 1 \->LIST
            ELSE l
            END
          END
        ELSE 1 \->LIST
        END
      ELSE 1 \->LIST
      END
    \>>
  \>>
  p1ins
  \<< "3 Arg: List 1+2a/b
1)PosExact (not after)
 or \oo \->add at the end

2)Insertion many el.:
  {\oo\oo\oo El.1 El.2 } 
  (list begin. w/ \oo\oo\oo)

  or 1 elem: elem
" DROP PICK3 SIZE
    IFERR \<-rep
    THEN 0
    END 0 \-> \<-L p \<-l S \<-rep \<-keep
    \<< l.test '\<-l' STO
      CASE p 1 ==
        THEN \<-l \<-L \<-rep { TAIL } IFT +
        END p \<-rep + S >
        THEN \<-L \<-rep
          IF
          THEN REVLIST TAIL REVLIST
          END \<-l +
        END \<-L 1 p 1 - SUB \<-l + \<-L p \<-rep + S SUB +
      END
    \>>
  \>>
END


Attached File(s)
.hp  LIST11.hp (Size: 7.98 KB / Downloads: 0)
Find all posts by this user
Quote this message in a reply
Yesterday, 02:41 PM (This post was last modified: Yesterday 03:01 PM by Gil.)
Post: #2
RE: 50G Fully new Ver 11 Lists Manipulation REPLACE, SWAP, KEEP, INSERT, DELETE, MOVE
New version 11

This new version 11 enables now to give several positions — instead of one single position —, look for the corresponding elements and a) insert (with pINS) before them, in one single step, new elements or b) replace (with pRPL) them, in one single step, by new elements.


Example
Initial list in stack level 3: { 10 20 30 40 50 60 70 }
Replace 2nd element, 4th element, 5th element, last element (, here for last/7th element)
Put then in stack level 2: { 2 4 5 } (or {2 4 5 7}, if you know the size of the initial list).
Replace the 2nd element (ie 20) by the list {21 22} —> list {21 22}.
Replace the 4th element (ie 40) by the 2 elements 41 and 42—> list { ∞∞∞ 41 42}
Replace the 5th element (ie 50) by 55 —> 55
Replace the 7th element (ie 70) by 77 —> 77
Put then in stack level 1 the above elements in a list: { { 21 22} { ∞∞∞ 41 42 } 55 77 }
Pressing pRPL will give { 10 { 21 22 } 30 41 42 55 60 77 }.


Attached File(s)
.hp  LIST11.hp (Size: 7.98 KB / Downloads: 1)
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)