User Tools

Site Tools


rpl:start

About RPL programming and what not.

The page can grow and then be split in different pages, using this as starting point.

Library of useful commands

See also this thread on the MoHPC: http://www.hpmuseum.org/forum/thread-10271.html

%%HP: T(0)A(D)F(.);
@ alternative found online %%HP: T(3)A(R)F(.);
@ You may edit the T(0)A(D)F(.) parts.
@ The earlier parts of the line are used by Debug4x.

@ in npp, just select language "normal" to get rid of the highlight.

DIR 

  helpTemplate
  "
  url: '-',
  tags: [ 'help', 'template' ],
  description: 
   this is a template for quick use. Feel free to improve it.
   
  Input:
  L3:
  L2:
  L1:
  Output
  L3:
  L2:
  L1:
  
  Example(s):
  "
  
  @##################################
  @# 
  @# vector or matrix operations

  @ url: '-',
  @ tags: [ 'vector operations' ],
  @ description: 
  @  see 50g user manual page 9-20
  @  it transforms a row vector like [1 2 3]
  @  in a column vector that is a matrix
  @  and viceversa
  
  @input:
  @L1: a row vector like [1 2 3]
  rowVtoColV
  \<<
    OBJ\-> 1 + \->ARRY
  \>>
  
  @input:
  @L1: a colum  vector like [[1] [2] [3]] (that is, a matrix)
  colVtorowV
  \<<
    OBJ\->  @explode the matrix
    OBJ\->  @explode the dimension list
    DROP    @keep only the first dimension, the number of rows
    \->ARRY @make a vector.
  \>>
  
  @ url: '-',
  @ tags: [ 'vector operations' ],
  @ description: 
  @  see 50g user manual page 10-11
  infoColVtoRowV
"See also the command RDM that shoudl be more efficient"
  
  @ url: '-',
  @ tags: [ 'vector operations' ],
  @ description: 
  @  see 50g user manual page 9-23
  @  it transforms a list in a vector like [1 2 3]
  listToVector
  \<<
    OBJ\->  1 \->LIST \->ARRY
  \>>
  
  @ url: '-',
  @ tags: [ 'vector', 'angle between vectors' ],
  @ description: 
  @  see 50g user manual page 9-16
  @  and math.stackexchange.com/questions/1047649/distance-and-angle-between-vectors-in-multiple-dimensions
  
  @input
  @L2: row vector
  @L1: row vector
  angleBetweenTwoVectors
  \<<
    
    \->
    @input
    lvVector1
    lvVector2
    
    \<<
      lvVector1 lvVector2 DOT
      
      lvVector1 ABS
      lvVector2 ABS
      *
      
      /
      ACOS
    \>>
  \>>
  
  @ url: '-',
  @ tags: [ 'vector', 'angle between vectors' ],
  @ description: 
  @  see 50g user manual page 9-16
  @  and math.stackexchange.com/questions/1047649/distance-and-angle-between-vectors-in-multiple-dimensions
  
  @input
  @L2: arm of the force vector
  @L1: force vector
  @output
  @L2: moment vector
  @L1: angle used to compute the norm of the moment vector 
  @    between force vector and arm of the force vector
  
  momentOfAForce
  \<<
    0 @lvVectorMoment
    
    \->
    @input
    lvVectorArmForce
    lvVectorForce
    @var
    lvVectorMoment
    
    \<<
      lvVectorArmForce lvVectorForce CROSS
      DUP
      'lvVectorMoment' STO
      "momentVector" \->TAG
      
      @computing the angle X such that
      @ norm(Moment) = norm(Force) * norm(armForce) * sin(X)
      lvVectorMoment ABS
      
      lvVectorArmForce ABS
      lvVectorForce ABS
      *
      /
      ASIN
      "Angle" \->TAG
    \>>
  \>>
  
  @info
  @ url: 'www.hpmuseum.org/forum/thread-3786-post-82450.html#pid82450',
  @ tags: [ 'matrix operations' ],
  @ description: 
  @   interesting link about applying a function to a matrix.
  infoApplyFuncToMatrix
"[[ -9 0 -1 -4 ]
  [ 4 9 3 3 ]
  [ 0 4 -9 9 ]
  [ 5 -1 -6 -4 ]]
  
  'LN(X)' DIAGMAP XNUM
"
  
  @ url: '-',
  @ tags: [ 'vector', 'equation of a plane' ],
  @ description: 
  @  see 50g user manual page 9-17
  @  and math.stackexchange.com/questions/753113/how-to-find-an-equation-of-the-plane-given-its-normal-vector-and-a-point-on-the
  @  Given a normal vector to a plane and a point in it, return a vector that defines
  @  the equation of the plane.
  
  @Remarks:
  @ no input check, the vectors should have 3 components otherwise the program
  @ does not work as intended.
  @input
  @L2: normal vector to the plane
  @L1: point in the plane
  @output
  @L1: a vector defining the coefficients for the axis
  @    X,Y,Z plus a constant.
  @    Say the result will be [4 6 2 -24] if the equation of the plane is
  @    4x+6y+2z-24=0 .
  eqPlaneNormalVandPoint
  \<<
    
    \->
    lvNormalVector
    lvPointInPlane
    
    \<<
      lvNormalVector
      lvNormalVector lvPointInPlane DOT
      4 @remember it works only for 3 dimensional vectors
      COL+
    \>>
  \>>
  
  @ url: '-',
  @ tags: [ 'matrix', 'from a series of list to a matrix' ],
  @ description: 
  @  see 50g user manual page 10-14
  
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as columns
  lists2matrixColumns
  \<<
    DUP
    \-> n
    \<<
      1 SWAP
      FOR j
        OBJ\-> \->ARRY
        IF 
          j n <
        THEN
         j 1 +
         ROLL
        END
      NEXT
      
      IF
        n 1 >
      THEN
        1 n 1 -
        FOR j
          j 1 +
          ROLL
        NEXT
      END
      n
      COL\->
    \>>
  \>>
  
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as rows
  lists2matrixRows
  \<<
    DUP
    \-> n
    \<<
      1 SWAP
      FOR j
        OBJ\-> \->ARRY
        IF 
          j n <
        THEN
         j 1 +
         ROLL
        END
      NEXT
      
      IF
        n 1 >
      THEN
        1 n 1 -
        FOR j
          j 1 +
          ROLL
        NEXT
      END
      n
      ROW\->
    \>>
  \>>
  
  @alternative solution
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as columns
  lists2matrixColumnsNo2
  \<<
    @note that we do not consume as input, immediately,
    @all the lists
    
    0     "lvInputLists"   DROP
  
    \->
    @input
    lvListsNumber
    @var
    lvInputLists
    
    \<<
      lvListsNumber \->LIST 
        @put the lists in one big list
        @ as { 1 } { 2 } 2 \->LIST produces { {1} {2} }
      'lvInputLists' STO
      
      lvInputLists
      1
      \<<
        listToVector @program included before
      \>>
      DOSUBS
      @we have a list of row vectors now
      
      @explode the list and make a matrix
      OBJ\->
      COL\->
    \>>
  \>>
  
  @alternative solution
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as rows
  lists2matrixRowsNo2
  \<<
    @note that we do not consume as input, immediately,
    @all the lists
    
    0     "lvInputLists"   DROP
  
    \->
    @input
    lvListsNumber
    @var
    lvInputLists
    
    \<<
      lvListsNumber \->LIST 
        @put the lists in one big list
        @ as { 1 } { 2 } 2 \->LIST produces { {1} {2} }
      'lvInputLists' STO
      
      lvInputLists
      1
      \<<
        listToVector @program included before
      \>>
      DOSUBS
      @we have a list of row vectors now
      
      @explode the list and make a matrix
      OBJ\->
      ROW\->
    \>>
  \>>
  
  @alternative solution
  @ REMARKS:
  @ - using listExt www.hpcalc.org/details/7971
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as rows
  lists2matrixRowsNo3
  \<<
    @note that we do not consume as input, immediately,
    @all the lists
    
    0     "lvInputLists"       DROP
    0     "lvSingleListSize"   DROP
  
    \->
    @input
    lvListsNumber
    @var
    lvInputLists
    lvSingleListSize
    
    \<<
      @get one list size, presuming equal dimension for all.
      DUP SIZE 'lvSingleListSize' STO
    
      lvListsNumber \->LIST 
        @put the lists in one big list
        @ as { 1 } { 2 } 2 \->LIST produces { {1} {2} }
      'lvInputLists' STO
      
      lvInputLists LXIL @explodes all sublists
      listToVector @program included before

      @we have one row vector now
      lvListsNumber @rows
      lvSingleListSize @columns
      2 \->LIST
      RDM
    \>>
  \>>
  
  @alternative solution
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as columns
  lists2matrixColumnsNo3
  \<<
    lists2matrixRowsNo3
    TRAN
  \>>
  
  @alternative solution
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as rows
  lists2matrixRowsNo4
  \<<
    \->LIST 
      @put the lists in one big list
      @ as { 1 } { 2 } 2 \->LIST produces { {1} {2} }
    AXL    
  \>>
  
  @alternative solution
  @input
  @L2-Ln+1: n lists of the same dimension
  @L1: number of lists to consider on the stack
  @output
  @L1: a matrix with the lists as columns
  lists2matrixColumnsNo4
  \<<
    lists2matrixRowsNo4
    TRAN
  \>>
  
  @input
  @L1: a matrix
  @output
  @L1: list representing the rows of a matrix in sublists
  matrixRows2list
  "just use AXL"
  
  @input
  @L1: a matrix
  @output
  @L1: list representing the columns of a matrix in sublists
  matrixColumns2list
  \<<
    TRAN
    AXL
  \>>
  
  MTRANSPOSEhelp
"
url: 'http://www.hpmuseum.org/forum/thread-8209-post-111256.html#pid111256',
tags: [ 'matrix', 'transpose' ],
description: 
 matrix transpose through lists faster than built in TRAN 

Remarks: listExt used. See links collection in this file.

Input:
a matrix.
output:
a matrix transposed.
"
  
  MTRANSPOSE
  \<< 
    AXL DUP LXIL SWAP SIZE LDIST AXL
  \>>
  
  gpArrayPosHelp
  "
    url: '-',
    tags: [ 'array', 'find element' ],
    description: 
     finds the first position of an element in an array. Similar to POS (for list and strings)
     
    Input:
    L2: ARRAY
    L1: Element
    Output
    L1: Position (negative if not found)
    
    Example(s):
  "
  gpArrayPos
  \<<
    2 PICK SIZE 1 GET @takes the array and compute the size
    -1 "lvResult" DROP
    \->
    lvArrayInput
    lvElement
    lvArraySize
    lvResult
    \<<
      1 lvArraySize
      FOR lvPOS
        IF
          lvArrayInput lvPOS GET
          lvElement ==
        THEN
          lvPOS 'lvResult' STO
          lvPOS lvArraySize + 'lvPOS' STO @we quit the FOR
        END
      NEXT
      
      lvResult
    \>>
  \>>

  gpArrayPosFromHelp
  "
    url: '-',
    tags: [ 'array', 'find element' ],
    description: 
     finds the first position of an element in an array strating from a given position. Extension of Pos
     
    Input:
    L2: ARRAY
    L1: starting position
    L1: Element
    Output
    L1: Position (negative if not found or start position too large)
    
    Example(s):
  "
  gpArrayPosFrom
  \<<
    3 PICK SIZE 1 GET @takes the array and compute the size
    -1 "lvResult" DROP
    \->
    lvArrayInput
    lvStartPos
    lvElement
    lvArraySize
    lvResult
    \<<
      1 lvArraySize
      FOR lvPOS
        IF
          lvPOS lvStartPos <
        THEN
          lvStartPos 'lvPOS' STO
        END
        IF
          lvArrayInput lvPOS GET
          lvElement ==
        THEN
          lvPOS 'lvResult' STO
          lvPOS lvArraySize + 'lvPOS' STO @we quit the FOR
        END
      NEXT
      
      lvResult
    \>>
  \>>
  
  JKMAPHelp
  "
  url: 'https://www.hpmuseum.org/forum/thread-19654-post-170122.html#pid170122',
  tags: [ 'array', 'matrix', 'map' ],
  description: 
    Here is a fast replacement for MAP using ListExt commands.
    It works for matrices or vectors but not for lists. It does not change the type of the array.
    The function can be a program, a list or a null-tagged object.
  remarks:
    it requires ListExt https://www.hpcalc.org/details/7971
   
  Input:
  L2: an array or a matrix
  L1: a program, a list or a null-tagged object.
  Output
  L1: the array or the matrix with the elements changed by the application of the function or the program.
  
  Example(s):
  -
  "
  
  JKMAP
  \<< SWAP OBJ\-> DUP \-> s
    \<< LPROD \->LIST SWAP LXEQ s \->ARRY
    \>>
  \>>
  
  @##################################
  @# 
  @# 50g filesystem operations
  
  @ url: 'www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv016.cgi?read=103110',
  @ tags: [ 'directory management', 'sorting variables', 'file manager' ],
  @ description: 'the code orders the contents of a directory and subdirectories',
  @ Download to 49(and 50) series in exact mode.
  @
  @ !!
  @ Recursive program; change ProgName within program to whatever
  @ !!
  @
  @ name is chosen for storing the program.
  @ Results from the BYTES command:
  @ 48G series:
  @   Checksum: # 5394h
  @   Size:         129
  @ 49 series:
  @   Checksum: # C209h
  @   Size:        125.
  orderDirContents
  \<<                     @ Begin program.
      VARS                @ Get list of variables.
      DUP                 @ Copy of variables list.
      IF                  @
        SIZE              @ Variables list not empty?
      THEN
        SORT              @ Sort list to ASCII order.
        ORDER             @ Reorder variables.
        15 TVARS          @ Get list of subdirectories.
        DUP               @ Copy of subdirectories list
        SIZE              @ Number of subdirectories.
        IF                @
          DUP             @ Subdirectories list not empty?
        THEN              @
          OVER            @ Copy of subdirectory list.
          ORDER           @ Move subdirectories to front.
          1               @ Loop begin index.
          SWAP            @ Move down number of subdirectories.
          FOR n           @ For each subdirectory.
            DUP           @ Copy of subdirectory list.
            n GET         @ Get subdirectory name.
            EVAL          @ Make subdirectory current.
            ProgName      @ Call this program recursively.
            UPDIR         @ Return to parent directory.
          NEXT            @
          DROP            @ Discard subdirectories list.
        ELSE              @
          DROP2           @ Discard empty subdirectories list and size 0.
        END               @
      ELSE                @
        DROP              @ Discard empty variables list.
      END
  \>>                     @ End program.
 
 
  @##################################
  @# 
  @# Math operations
  
  @url: 'www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv016.cgi?read=105876',
  @tags: [ 'polar', 'rectangular', 'coordinate system' ],
  @description: 'several userRPL programs to switch from polar to rectangular
  @  representation of numbers',

  @ 2 dimensional P\->R program.
  @ Arguments: 2 reals representing r and theta.
  @ Returns: 2 reals representing x and y.
  polar2rect
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    ROT ROT       @ Move flags list to level 3.
                  @ On 49 series, UNROT may be used
                  @ instead of ROT ROT.
    CYLIN         @ Force cylindrical display mode.
                  @ SPHERE would work as well here.
    \->V2         @ Combine into vector or complex.
    RECT          @ Force rectangular display mode.
    V\->          @ Decompose into reals.
    ROT           @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 2 dimensional R\->P program.
  @ Arguments: 2 reals representing x and y.
  @ Returns: 2 reals representing r and theta.
  rect2polar
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    ROT ROT       @ Move flags list to level 3.
                  @ On 49 series, UNROT may be used
                  @ instead of ROT ROT.
    RECT          @ Force rectangular display mode.
    \->V2         @ Combine into vector or complex.
    CYLIN         @ Force cylindrical display mode.
                  @ SPHERE would work as well here.
    V\->          @ Decompose into reals.
    ROT           @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Cylindrical\->Rectangular program.
  @ Arguments: 3 reals representing r, theta, and z.
  @ Returns: 3 reals representing x, y, and z.
  cylindrical2rectangular
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    CYLIN         @ Force cylindrical display mode.
    \->V3         @ Combine into vector.
    RECT          @ Force rectangular display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Rectangular\->Cylindrical program.
  @ Arguments: 3 reals representing x, y, and z.
  @ Returns: 3 reals representing r, theta, and z.
  rectangular2cylindrical
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    RECT          @ Force rectangular display mode.
    \->V3         @ Combine into vector.
    CYLIN         @ Force cylindrical display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Spherical\->Rectangular program.
  @ Arguments: 3 reals representing rho, phi, and theta.
  @ Returns: 3 reals representing x, y, and z.
  spherical2rectangular
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    SPHERE        @ Force spherical display mode.
    \->V3         @ Combine into vector.
    RECT          @ Force rectangular display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Rectangular\->Spherical program.
  @ Arguments: 3 reals representing x, y, and z.
  @ Returns: 3 reals representing rho, phi, and theta.
  rectangular2spherical
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    RECT          @ Force rectangular display mode.
    \->V3         @ Combine into vector.
    SPHERE        @ Force spherical display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Cylindrical\->Spherical program.
  @ Arguments: 3 reals representing r, theta, and z.
  @ Returns: 3 reals representing rho, phi, and theta.
  cylindrical2spherical
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    CYLIN         @ Force cylindrical display mode.
    \->V3         @ Combine into vector.
    SPHERE        @ Force spherical display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>

  @ 3 dimensional Spherical\->Cylindrical program.
  @ Arguments: 3 reals representing rho, phi, and theta.
  @ Returns: 3 reals representing r, theta, and z.
  spherical2cylindrical
  \<<             @ Begin program.
    RCLF          @ Get current flags.
    4 ROLLD       @ Move flags list to level 4.
    SPHERE        @ Force spherical display mode.
    \->V3         @ Combine into vector.
    CYLIN         @ Force cylindrical display mode.
    V\->          @ Decompose into reals.
    4 ROLL        @ Move flags list back to level 1.
    STOF          @ Restore original flags.
  \>>
  
  @url: 'www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv021.cgi?read=223680',
  @tags: [ 'Euler totient' ],
  @description: 
  @  See oeis.org/A000010 .
  @  Note: the 50g has this function natively implemented.
  @
  eulerTotient
  \<< DUP
    IF 1 \=/
    THEN { } SWAP FACTORS DUP SIZE 1 SWAP
      FOR i DUP i GET ROT + SWAP 2
      STEP { } SWAP DUP SIZE 2 SWAP
      FOR i DUP i GET ROT + SWAP 2
      STEP DROP 1 - OVER SWAP
      \<< ^
      \>> DOLIST SWAP 1 - + \PILIST
    END
  \>>
  @examples: [
  @  'Input: 98765430111
  @   Output: 61497371520',
  @],
  
  @url: 'www.hpmuseum.org/forum/archive/index.php?thread-4162.html',
  @tags: [ 'farey sequence', 'fractions' ],
  @description: '
  @  computes the farey sequence
  @  en.wikipedia.org/wiki/Farey_sequence
  @',
  fareySequence
  \<< \-> n
    \<< { [ 0 1 ] } 0 1 DUP n
        WHILE OVER n <
        REPEAT \-> a b c d
            \<< c d \->V2 +
                c d
                n b + d / IP
                DUP c * a -
                SWAP d * b -
            \>>
        END
        DROP2 DROP2
    \>>
  \>>
  @examples: [
  @  'Input: the wanted <n> terms of the sequence
  @   Output: the farey sequence',
  @],
  
  randIntHelp
" url: 'http://www.hpmuseum.org/forum/thread-10271-post-93738.html#pid93738',
  tags: [ 'random number', 'statistics' ],
  description:
    returns a random integer number between 1 and the value given
  
  Input: an integer number (as real)
  output: an integer (as real) between 1 and the input inclusive
"
  
  randInt
  \<<
    RAND * CEIL
  \>>
  
  randIntRangeHelp
" url: '-',
  tags: [ 'random number', 'statistics' ],
  description:
    returns a random integer in the specified value
  
  Input:
  L2: min value
  L1: max value
  output: an integer (as real) between min and max value included
"
  randIntRange
  \<<
    \->
    lvMin
    lvMax
    \<<
      lvMax lvMin - @the distance max-min
      1 + @a value that we need to offset CEIL later
      RAND * CEIL
      1 -
      @due to ceil, if the size of the range is, say, 4 large,
      @one would expect values in (0,1,2,3,4) but with ceil 0 is never happening.
      @Thanks to a larger range we have (0,1,2,3,4,5) where 0 is never happening.
      @Thus we have (1,2,3,4,5)
      @Then we need to shift of one value on the left, obtaining (0,1,2,3,4) as wished
      lvMin
      +
    \>>
  \>>
  
  randCoinHelp
" url: '-',
  tags: [ 'random coin number', 'statistics' ],
  description:
    returns a random integer between 0 and 1
  
  Input: -
  output: an integer (as real) between 0 and 1
"

  randCoin
  \<<
    2 RAND * FLOOR
  \>>
  
  
  DEC2FRAChelp
"
url: 'http://www.hpmuseum.org/forum/archive/index.php?thread-7955-13.html',
tags: [ 'best fraction' ],
description:
  Given any decimal fraction in level 2, and a maximum denominator in level 1, it returns the best fraction

input
L2: number to approximate
L1: max denominator
Example:
pi, 1000, DEC2FRAC --> 355/113 in 0.39 seconds
pi, 100000, DEC2FRAC --> 312689/99532 in 0.43 seconds
"

  DEC2FRAC
  \<< DUP2 @ Must be two arguments.  Exit now if max denominator < 2,
    IF 1 > SWAP FP AND @ or if decimal fraction is an integer.
    THEN \-> f c @ Store decimal fraction, and max denominator.

      \<< 0 1 f @ Calculate only denominators.  Do numerator only at end.
        WHILE OVER c < OVER AND @ Do until bigger than max denominator
        REPEAT INV DUP FP 4 ROLLD IP OVER * ROT + ROT @ This is the
        END DROP DUP2 c @ recursion formula continued fraction expansion.

        IF DUP2 > @ Is there a possible "missing" fraction?
        THEN - OVER / CEIL * - @ This is the new, fast "jump backwards".
        ELSE 3 DROPN @ (Sometimes there's no need to jump.)
        END DUP2 1 2 @ Take the new denominator & the previous one, and

        START DUP f * 0 RND SWAP / f - ABS SWAP @ turn into fractions.
        NEXT @ See which one's closest to the original decimal fraction.

        IF > @ Compare the two solutions, and
        THEN SWAP @ pick the better one.
        END DROP DUP f * 0 RND SWAP @ Calculate the numerator.
      \>> @ End of real work; now clean up the output.

      IF DUP ABS 1 > @ Is the denominator greater than 1?
      THEN -3 CF R\->I SWAP R\->I SWAP / @ If so, make output into 'A/B' form.
      ELSE DROP @ Otherwise, get rid of extraneous denominator,
      END @ and exit program.

    ELSE DROP @ If bad arguments, do nothing to "decimal fraction", but
    END @ get rid of "maximum denominator" and exit program.
  \>>

  iterateContFracHelp
"
url: 'http://www.hpmuseum.org/forum/thread-2025.html',
tags: [ 'continous fraction' ],
description:
  algorithm for converting a decimal into a fraction without storing the partial quotients of the expanded continued fraction.
  
Instructions:
(1) Clear the stack. Put calculator in exact mode.
(2) Place on level 1 of the stack either a decimal number, 
    or an algebraic ratio of two integers, e.g. '123/234'.
(3) Run the program repeatedly. Stop when level 4 shows infinity.

Each iteration will display the following on the stack:

4: Current value of N. Stop when it's infinity.
3: Previous Convergent p/q in the form of { p q }
2: Current Convergent a/b in the form { a b }
1: Decimal evaluation of a/b

Warning: Program must be loaded and run in exact mode.
"

  iterateContFracHelp
  \<<
    IF DEPTH 1. SAME
    THEN
      IF DUP TYPE 0. ==
      THEN 1.E50 * R\->I 50 ALOG /
      END PROPFRAC { 0 1 } { 1 0 }
    ELSE DROP 3. ROLL EVAL FXND SWAP OVER IDIV2 ROT SWAP / PROPFRAC 4. ROLLD OVER 4. ROLLD * ADD
    END DUP EVAL SWAP \->NUM SWAP /
  \>>
  
  LOGBXhelp
" url: 'http://www.hpmuseum.org/forum/thread-10271-post-110396.html#pid110396',
  tags: [ 'logarithms' ],
  description:
    logarithm of X in base b
  
  Input:
  L2: base
  L1: number
  output: 
  log_b(x)
"

  LOGBX
  \<< \-> b x \<< x LN b LN / \>> \>>
  
  DoubleFactorialHelp
  "
  url: 'https://www.hpmuseum.org/forum/thread-12900-post-115878.html#pid115878',
  tags: [ 'factorial' ],
  description: 
   this computes the double factorial on a number
   
  Input:
  L1: the input number
  Output
  L1: the double factorial
  
  Example(s):
  "
  
  DoubleFactorial
  \<< 
    \pi EVAL DUP2 * COS 1. - .25 * SWAP .5 * SWAP ^ SWAP .5 * DUP 2. SWAP ^ SWAP 1. + GAMMA * *
  \>>
  
  
  ItoSTRHelp
  "
  url: 'https://www.hpmuseum.org/forum/thread-19384.html',
  tags: [ 'list', 'base change' ],
  description: 
   The first program ItoSTR take an integer n on level 2 and an integer b on level 1 and returns a string representing n in base b.
   It requires ListExt
   
  Input:
  L1: integer value
  L1: base
  Output
  L1: the integer in base b
  
  Example(s):
  257175174
  62
  ItoSTR

  returns HP50g 
  "

  ItoSTR
  \<< I\->BL NL\->S
      { 36. 61. 61. } CHR+
      { 10. 35. 55. } CHR+
      { 0. 9. 48. } CHR+
  \>>

  STRtoIHelp
  "
  url: 'https://www.hpmuseum.org/forum/thread-19384.html',
  tags: [ 'list', 'base change' ],
  description: 
   The next program STRtoI does the inverse, taking a string on level 2 and b on level 1.
   It requires ListExt
   
  Input:
  L1: integer value
  L1: base
  Output
  L1: the integer in base b
  
  Example(s):
  257175174
  62
  ItoSTR

  returns HP50g 
  "
  STRtoI
  \<< SWAP
      { 48. 57. -48. } CHR+
      { 65. 90. -55. } CHR+
      { 97. 122. -61. } CHR+
      S\->NL SWAP BL\->I
  \>>

  nBASEHelp
  "
  url: 'HP 50g Advanced User Guide v2 page 2-22',
  tags: [ 'base change' ],
  description: 
   nBASE converts a positive decimal number (x) into a tagged string representation of the equivalent value 
   in a different number base (b). Both x and b must be real numbers. 
   nBASE automatically rounds both arguments to the nearest integer.
   
  Input:
  L1: integer value
  L1: base
  Output
  L1: the integer in base b
  
  Example(s):
  1000
  23
  nBASE

  returns 1KB
  "
  
  nBASE
  \<<
    1 CF 0 RND SWAP 0 RND RCLF
      @Clear flag 1, round both arguments to integers and recall flag settings.
    \-> b n f
      @Store the base, number and flag settings in local variables.
      \<<
        @Begin the outer local variable structure.
        STD n LOG b LOG /
          @Sets “standard” display mode and computes the ratio of the common logarithms of number and base.
        10 RND
          @Rounds result to remove imprecision in last decimal place.
        IP n 0
          @Find the integer part of log ratio, recall the original number, and initialize the counter variable k for use in the DO...UNTIL loop.
        \-> i m k
          @Store the values in local variables.
        \<<
          ""
          DO
            'm' EVAL b i
            'k' EVAL - ^
              @Begin inner local variable structure, enter an empty string and begin the DO...UNTIL...END loop.
              @Compute the decimal value of the
              @(i – k) th position in the string.
            DUP2 MOD
            @Makes a copy of the arguments and computes the decimal value still remaining that must be accounted for by other positions.
            IF DUP 0 ==
              'm' EVAL b ≥
              AND
                @Is the remainder zero and m≥b?
            THEN 1 SF
              @If the test is true, then set flag 1.
            END 'm' STO
            / IP
              @Store the remainder in m. Compute the number of times the current position-value goes into the remaining decimal value. This is the “digit” that belongs in the current position.
            IF DUP 10 ≥
              @Is the “digit” ≥ 10?
            THEN 55
            ELSE 48
            END + CHR
              @Then convert the digit into a alphabetic digit (such as A, B, C, …).
            + 'k' 1 STO+
              @Append the digit to the current result string and increment the counter variable k.
  
          UNTIL 'm' EVAL 0 ==
              @Repeat the DO...UNTIL loop until m = 0 (i.e. all decimal value have been accounted for).
          END
          
          IF 1 FS?C
            @Is flag 1 set? Clear the flag after the test.
          THEN "0" +
            @Then add a placeholding zero to the result string.
          WHILE i 'k' EVAL
          - 0 \=/
            @Begin WHILE...REPEAT loop to determine if additional placeholding zeros are needed.
            @Loop repeats as long as i≠k.
          REPEAT "0" +
            1 'k' STO+
            @Add an additional placeholding zero and increment k before repeating the test-clause.
          END
        END
      \>>
        @End the WHILE...REPEAT...END loop, the IF...THEN...END structure, and the inner local variable structure.
      " base" b +
      n SWAP + \->TAG @End the outermost IF...THEN...ELSE...END structure and create the label string and tag the result string using the original arguments.
      f STOF @Restore original flag settings.
    \>>
  \>>
  
  @##################################
  @# 
  @# list operations and math on list
 
  @url: 'www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv016.cgi?read=103417',
  @tags: [ 'geometric mean', 'statistics' ],
  @description: '
  @  computes the geometric mean
  @',
  geometricMean
  \<< 
    \-> 
    list 
    
    \<< 
      list \PILIST list SIZE XROOT 
    \>> 
  \>>
  @examples: [
  @  'Input: a list of numbers
  @   Output: the geometric mean',
  @],
  
  @url: '-',
  @tags: [ 'harmonic mean', 'statistics' ],
  @description: '
  @  computes the harmonic mean
  @  See also official hp 50g user guide (the large one with 800+ pages) page 8-15
  @',
  @examples: 
  @ - See official hp 50g user guide (the large one with 800+ pages) page 8-15
  
  @Input:
  @L1: a list of samples of which we want the harmonic mean.
  @Output: the harmonic mean
  harmonicMean
  \<< 
    
    DUP SIZE
    \-> 
    @input
    lvInputList 
    lvInputListSize
    
    \<< 
      lvInputList INV \GSLIST
      lvInputListSize /
      INV
    \>> 
  \>>
  
  @url: '-',
  @tags: [ 'weighted average', 'statistics' ],
  @description: '
  @  See also official hp 50g user guide (the large one with 800+ pages) page 8-17
  @',
  @examples: 
  @ - See official hp 50g user guide (the large one with 800+ pages) page 8-17
  
  @Input:
  @L2: A list of samples
  @L1: A list of weights
  @Output: the weighted average
  weightedAverage
  \<< 

    \-> 
    @input
    lvSampleList
    lvWeightList
    
    \<< 
      lvSampleList lvWeightList * \GSLIST
      lvWeightList \GSLIST
      /
    \>> 
  \>>
  
  @url: 'www.hpmuseum.org/forum/archive/index.php?thread-4138.html',
  @tags: [ 'average', 'moving average', 'statistics', 'list processing' ],
  @description: '
  @  computes the moving average and the average of a list
  @average
  @Input: a list of numbers
  @Output: the average 
  average
  \<< DUP \GSLIST SWAP SIZE / \>>

  @moving average
  @input: 
  @ L2: a list 
  @ L1: a number of elements to consider to compute the moving average
  @output:
  @ L1: the list with moving averages
  movingAverage
  \<< \-> N
    \<< N \<< N \->LIST average \>> DOSUBS \>>
  \>>
  
  gpPSDEVlistHelp
  "
  url: '-',
  tags: [ 'list', 'population variance deviation' ],
  description: 
   compute the standard deviation of a list instead of relying on PSDEV and \GSDAT variable in a matrix form
   
  remarks:
    - it can be surely improved in speed (not sure about readability)
   
  Input:
  L3:
  L2:
  L1: a non-empty list of number
  Output
  L3:
  L2:
  L1: sqrt( 1/n * sum_1_n( (x_i -avg)^2 ) )
  
  Example(s):
  
  "
  
  gpPSDEVlist
  \<<
    @input
    "lvListInput" DROP
    
    @localVar
    0 "lvListSize" DROP
    
    \->
    @input
    lvListInput
    
    @localVar
    lvListSize
    \<<
      @size of the list
      lvListInput SIZE 'lvListSize' STO
      
      @compute the average and make it a list
      lvListInput \GSLIST lvListSize / lvListSize NDUPN \->LIST
      @suptract from the input list
      lvListInput -
      
      @now we have a list of avg-x , we need to square the list
      SQ @list of (x_i -avg)^2 (the squaring makes the subtraction order irrelevant)
      
      @sum the values: sum_1_n( (x_i -avg)^2 )
      \GSLIST
      
      @divide by the size: 1/n * sum_1_n( (x_i -avg)^2 )
      lvListSize /
      
      @then we need to take the root of it and that is it.
      \v/
    \>>
  \>>


  @url: 'www.hpmuseum.org/forum/thread-8209-post-81657.html#pid81657',
  @tags: [ 'list processing' ],
  @description: 
  @  create a list of zero elements except one in a particular position
  @input:
  @L3: value to put in the list
  @L2: position
  @L1: list size
  @output: a list of zeroes with the specified value in the given position
  listRowIdentity
  \<<
     0 SWAP
     NDUPN \->LIST
     SWAP ROT PUT
  \>>
  @url: 'www.hpmuseum.org/forum/thread-8209-post-81669.html#pid81669',
  @tags: [ 'stack processing' ],
  @description: '
  @ reverse the order of the last 3 stack elements.
  
  @ url: 'www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv021.cgi?read=238006',
  @ tags: [ 'list processing' ],
  @ description: 'take a list in input and split it in a list of
  @   sublists in output where a sublists first element would be
  @   the last element of the previous sublists. Sublists of size 3',
  @ userrpl : '
  @   ,
  @ examples: [
  @   'Input: {1 2 3 4 5 }
  @    Output: {{ 1 2 3} {3 4 5}}',
  @ ],
  splitList
  \<<
    3 
    \<< 3 \->LIST NSUB 2 MOD NOT DROPN \>>
    DOSUBS
  \>>
  
  @url: 'www.hpmuseum.org/forum/thread-8209-post-81669.html#pid81669',
  @tags: [ 'list processing' ],
  @description: '
  @  create a list of n equal objects
  @input:
  @L2: object to replicate
  @L1: number of replications
  @output
  @a list with the replicated object 
  nreplication2list
  \<<
    NDUPN \->LIST
  \>>
    
  @url: 'www.hpmuseum.org/forum/thread-8209-post-82417.html#pid82417',
  @tags: [ 'list processing' ],
  @description: 
  @  remove all entries of an element in a list.
  @  Requires the listExt of DavidM.
  
  @input:
  @L2: a list
  @L1: an object to match
  removeElementFromList
  \<<
     OVER SWAP MPOS LRMOV
  \>>
  @output
  @L1: the list in input without the entries that matched the object
  
  
  shufListHelp
"
url: 'hpmuseum.org/forum/thread-8209-post-74271.html#pid74271',
tags: [ 'list processing', 'randomize list' ],
description: 
  randomize a list in input
  also check. www.hpmuseum.org/forum/thread-7955-post-71223.html#pid71223
  www.hpmuseum.org/forum/thread-2889-post-25163.html#pid25163

input:
L1: a list to randomize
output:
L1: the randomized list.
"
  
  shufList
  \<<
    @ explode the list onto stack and save the size (sz)
    OBJ\-> \-> sz

    \<<
      @ loop: for list item positions 1 to (sz-1), choose a
      @ random item from the remaining candidates and move it
      @ to the target position

      @ note: stack positions (sz...1) are numbered inversely to
      @ list positions (1...sz)

      @ x represents the current target position
      sz 2 FOR x

        @ pick a random item position from the remaining pool
        x RAND * CEIL

        @ move the chosen item to stack level 1
        ROLL

        @ move the chosen item to the current target position
        x ROLLD

      @ update target to the next position
      -1 STEP

      @ implode the resulting list data
      sz \->LIST
    \>>
  \>>
  
  @url: 'groups.google.com/d/msg/comp.sys.hp48/mK0ywSIJ5Ho/5lP9xux0CAAJ',
  @tags: [ 'random integer list' ],
  @description:
  @  random integer list without duplicates
  
  @input
  @L2: max positive integer (from 1)
  @L1: number of integers to get
  @example:
  @L2: 10 (we want the integers between 1 and 10)
  @L1: 5 (we want 5 integers)
  randIntListNoDUP
  \<< \-> t n
    \<< 1 t
      FOR x x DUP RAND * CEIL ROLLD
      NEXT t n - DROPN n \->LIST
    \>>
  \>> 
  
  listRandSeqHelp
"
url: 'http://www.hpmuseum.org/forum/thread-8209-post-111195.html#pid111195',
tags: [ 'list processing', 'create list', 'list sequence', 'random' ],
description: 
  given a min and max value in input, creates a random list with N elements from the range [min, max] € N.

input:
L3: min value (integer)
L2: max value (integer)
L1: number of elements
output:
list of random integers in the range.
"
  
  listRandSeq
  \<<
    \-> 
    lvMin
    lvMax
    lvCount
    \<<
       1. lvCount 
       START
          lvMax lvMin - @the distance max-min
          1 + @a value that we need to offset CEIL later
          RAND * CEIL
          1 -
          @due to ceil, if the size of the range is, say, 4 large,
          @one would expect values in (0,1,2,3,4) but with ceil 0 is never happening.
          @Thanks to a larger range we have (0,1,2,3,4,5) where 0 is never happening.
          @Thus we have (1,2,3,4,5)
          @Then we need to shift of one value on the left, obtaining (0,1,2,3,4) as wished
          lvMin
          +
       NEXT
       lvCount \->LIST
    \>>
  \>>
    
  listRandSeqJKHelp
  "
url: 'http://www.hpmuseum.org/forum/thread-8555-post-111199.html#pid111199',
tags: [ 'list processing', 'create list', 'list sequence', 'random' ],
description: 
  given a min and max value in input, creates a random list with N elements from the range [min, max] € N.
  It works for approximate and exact mode.

input:
L3: number of elements
L2: min value (integer)
L3: max value (integer)
output:
list of random integers in the range.
  "
  
  listRandSeqJK
  \<< 3. \->LIST I\->R EVAL OVER - 1. + \-> s b a
  \<<
    IF -105. FS?
    THEN 1. s
      START RAND a * b + FLOOR
      NEXT
    ELSE 1. s
      START RAND a * b + FLOOR R\->I
      NEXT
    END s \->LIST
  \>>
\>>
  
  listMaxHelp
"
url: 'http://www.hpmuseum.org/forum/thread-8555-post-94249.html#pid94249',
tags: [ 'list processing', 'max min' ],
description: 
  find max in a list

input:
L1: a list of numbers
output:
L1: the max value
"

  listMax
  \<<
    \<< MAX \>>
    STREAM
  \>>
  
  listMinHelp
"
url: 'http://www.hpmuseum.org/forum/thread-8555-post-94249.html#pid94249',
tags: [ 'list processing', 'max min' ],
description: 
  find min in a list

input:
L1: a list of numbers
output:
L1: the min value
"

  listMin
  \<<
    \<< MIN \>>
    STREAM
  \>>

  lCumSumHelp
"
url: http://www.hpmuseum.org/forum/thread-8209-post-91682.html#pid91682
tags: [ 'list processing', 'cumulative sum' ],
description: 
  cumulative sum of elements in a list. author: DavidM

input:
L1: a list of numbers
output:
L1: the list with the comulative sum

example(s):
- input: { 1 2 3 4 5}
  output: { 1 3 6 10 15 }
"
  
  lCumSum
  \<<
    1
    \<<
      NSUB 1 -
      { OVER + }
      IFT
    \>>
    DOSUBS
  \>>
  
  listOneConstantHelp
  "
  url: http://www.hpmuseum.org/forum/thread-8209-post-81657.html#pid81657
  tags: [ 'list processing', 'list of zeroes with constant' ],
  description: 
    list of zeroes with constant

  input:
  L3: constant
  L2: position
  L1: list size
  output:
  L1: list of 0 with the constant in position

  example(s):
  input:
    5
    3
    5
  output: { 0 0 5 0 0 }
  "
  
  listOneConstant
  \<<
    0 SWAP
    NDUPN →LIST
    SWAP ROT PUT
  \>>
  
  listIncrDecrElementHelp
  "
  url: http://www.hpmuseum.org/forum/thread-8209-post-81657.html#pid81657
  tags: [ 'list processing', 'list increase decrease element' ],
  description: 
    given a list increments or decrements an element in position.
    author: DavidM

  input:
  L3: list
  L2: position
  L1: increment / decrement
  output:
  L1: list with the element in position modified

  example(s):
  input:
    { 3 3 3 }
    2
    -5
  output: { 3 -2 3 }
  "
  
  listIncrDecrElement
  \<<
    PICK3 PICK3
    GET + PUT
  \>>
  
  listFrequencyElements
  @using ListEXT
  \<<
    \->
    lvInputList
    
    \<<
      lvInputList LDDUP @results without duplicates
      1
      \<<
        DUP @duplicate L1
        lvInputList SWAP @bring the single element on L1
        LCNT @count the value
        \->TAG @tag the element with its frequency 
      \>>
      DOSUBS
      
      @output:
      @results without duplicates and their frequency in a list
    \>>
  \>>
  
  ListPickLastHelp
"
url: -
tags: [ 'list processing', 'last element' ],
  description: 
    given a list picks the last element.

input:
a list

output:
the last element
"
  ListPickLast
  \<<
    REVLIST HEAD
  \>>
  
  listSumSubListHelp
"
url: -
tags: [ 'list processing', 'sum of sublist' ],
description: 
  given a list picks the last element.

Input: a list with sublists of the same dimension

Output: the sum of the sublists.
"
  
  listSumSubList
  \<<
    IF
      @ if the list is large enough
      DUP SIZE 1 >
    THEN
      \<< ADD \>>
      STREAM
    ELSE
      @otherwise the list itself.
      HEAD
    END
  \>>
  
  LTRANTKHelp
"
url: http://www.hpmuseum.org/forum/thread-8209-post-111264.html#pid111264
tags: [ 'list processing', 'transpose list' ],
description: 
  given a list of sublists of the same size, transposes its elements.
  As if it was a matrix.
Author
Thomas Klemm

Input: a list with sublists of the same dimension

Output: the list with the sublists with elements transposed.

Example(s):
{ { 1 2 3 } { 3 4 5 } } -> { { 1 4 } { 2 4 } { 3 5 } }
"
  LTRANTK
  \<< 
    OBJ\->
    \-> 
    n
    \<< 
      n
      \<< 
        n \->LIST
      \>> 
      DOLIST
    \>>
  \>>
  
  LTRANJKhelp
"
url: http://www.hpmuseum.org/forum/thread-8209-post-111256.html#pid111256
tags: [ 'list processing', 'transpose list' ],
description: 
  given a list of sublists of the same size, transposes its elements.
  As if it was a matrix.
Requires:
  ListExt . See in this file the links.
Author
John Keith

Input: a list with sublists of the same dimension

Output: the list with the sublists with elements transposed.

Example(s):
{{ 1 2 3 }{4 5 6 }{ 7 8 9 }} -> {{ 1 4 7 }{ 2 5 8 }{ 3 6 9 }}
"
  
  LTRANJK
  \<< 
    DUP LXIL SWAP SIZE LDIST 
  \>>
  
  L2OVERLAPSUBHelp
"
url: http://www.hpmuseum.org/forum/thread-8209-post-111278.html#pid111278
tags: [ 'list processing', 'list overlapping sublists' ],
description: 
  given a list it creates a list of sublists with each sublists having the first and
  last element in common with adjacent sulists.
Author
John Keith

Input: 
L2: a list
L1: a number to decide the size of the sublists.

Output: a list of sublists with each sublists having the first and
  last element in common with adjacent sulists.

Example(s):
 { 1 2 3 4 5 } 2 -> {{ 1 2 }{ 2 3 }{ 3 4 }{ 4 5 }}
"
  
  L2OVERLAPSUB
  \<< 
    \-> n
    \<< n
       \<< n \->LIST
       \>> DOSUBS
    \>>
  \>>
  
  LPercentileTKHelp
  "
  url: 'http://www.hpmuseum.org/forum/thread-11435-post-104441.html#pid104441',
  tags: [ 'list', 'percentile', 'quartile', 'median' ],
  description: 
   Modified by Thomas Klemm based on a program in the 48 (or 50g) advanced user reference.
   
  Input:
  L2: inputList
  L1: percentile (integer 0 to 100)
  Output
  L3: the percentile
  
  Example(s):
  { 6 7 15 36 39 40 41 42 43 47 49 }
  25: 25.5
  50: 40
  75: 42.5
  "
  
  LPercentileTK
  \<< 
    SWAP SORT DUP SIZE 1 - ROT % 1 + 
    \-> p
    \<< 
      DUP p FLOOR GET SWAP p CEIL GET + 2 /
    \>>
  \>>
  
  
  LREPLPOS2021Help
  "
  url: '',
  tags: [ 'list', 'replace element' ],
  description: 
    When one has a list of replacements for original list
  remarks:
    Not much input checks at first, example: giving positions that they don't exists
   
  Input:
  L3: originalList
  L2: list of position to replace
  L1: elements to insert (length should be identical to the list of positions to replace)
  Output
  L1: the original list with the elements replaced
  
  Example(s):
  { 9 8 7 6 5 4 3 2 1 } { 7 8 } { 11 22 } -> { 9 8 7 6 5 4 11 22 1 }
  "

  LREPLPOS2021
  @ LREPL from ListExtworks works with matching the elements to replace, if one wants to replace
  @ with positions one need another routine
  \<<
    \->
    @input
    lvOriginList
    lvPositionList
    lvReplacementsList
    @variables
    \<<
      1 lvPositionList SIZE
      FOR lvInd
        lvOriginList
        lvPositionList lvInd GET @the postion
        lvReplacementsList lvInd GET @the replacement
        PUT 'lvOriginList' STO @replaced
      NEXT
      lvOriginList @result
    \>>
  \>>
  
  LREPLPOS3298Help
  "
  url: 'https://www.hpmuseum.org/forum/thread-8555-post-149845.html#pid149845',
  tags: [ 'list', 'replace element' ],
  description: 
    When one has a list of replacements for original list
  remarks:
    Not much input checks at first, example: giving positions that they don't exists
   
  Input:
  L3: originalList
  L2: list of position to replace
  L1: elements to insert (length should be identical to the list of positions to replace)
  Output
  L1: the original list with the elements replaced
  
  Example(s):
  { 9 8 7 6 5 4 3 2 1 } { 7 8 } { 11 22 } -> { 9 8 7 6 5 4 11 22 1 }
  "

  LREPLPOS3298
  \<< 2. \<< PUT \>> DOLIST \>>

  @##################################
  @# 
  @# Stack operations
  
  @that is from L3 L2 L1
  @one obtains L1 L2 L3
  rev3stack
  \<<
    SWAP ROT
  \>>
  
  @info snippet
  @url: 'www.hpmuseum.org/forum/thread-8209-post-81686.html#pid81686',
  @tags: [ 'stack processing', 'rule of thumb' ],
  @description:
  infoSingleArgStackOp
"
stack operations that take a numeric argument (DUPN, ROLL, PICK, etc.) 
take about 7 times as long to execute as simple operations 
(SWAP, DUP, ROT, etc.)
"
  
  @##################################
  @# 
  @# user input operations
  
  @url: 'groups.google.com/forum/#!original/comp.sys.hp48/o4XwzdSzWhc/-TZrBqVzgcEJ',
  @tags: [ 'input forms', 'inform' ],
  @description: '
  @  There are alternatives to good old INFORM or INPUT,
  @such as INLIST, INMENU, and INPROMPT
  @
  @INLIST is an INFORM replacement, having all these same features:
  @
  @o Editing (including a CALC mode for stack calculations)
  @o Optional "reset values"
  @o Optional object type restriction
  @
  @
  @But INLIST is not limited
  @to what can be crammed into one small form,
  @because its "form" is open-ended and *scrolls* vertically.
  @
  @The INLIST arguments are similar to INFORM:
  @
  @
  @"Title" { prompts } { initial values }
  @-OR-
  @"Title" { prompts } { reset values } { initial values }
  @
  @
  @Note: Lists other than "prompts"
  @may be empty or shorter than the "prompts" list.
  @
  @Each "prompt" in the list of prompts is:
  @
  @o "Any string" (or any word)
  @-OR-
  @o A list: { "Prompt" type1 type2 .. } for object type restriction
  @
  @How to enter data using INLIST:
  @Highlight any item; press OK or ENTER to edit.
  @
  @Individual value "reset" is invoked
  @by a blank edit area (press ON once if not yet blank).
  @
  @Individual value CALC mode is invoked
  @by typing only an "equal" command [=3D] into the edit area
  @(left-shifted zero on 48G, right-shifted W on 49G/50G);
  @return from CALC mode via CONT (left-shifted ON).
  @
  @
  @Also use CALC mode to see the list of valid object TYPES.
  @
  @"Reset All" is invoked
  @by an item at the very end of the form.
  @
  @
  @"<DONE>" provides the normal exit from INLIST;
  @ON or "Cancel" (from the form level) aborts.
  @
  @
  @Level | Stack at normal exit:  |    Stack after abort:
  @2:      { final values }       |
  @1:      1.                     |    0.
  @
  @
  @The use of a full-screen CHOOSE program can improve INLIST,
  @by displaying a full line for each item,
  @and by using the full height of the screen.
  @
  @
  @Full-screen CHOOSE for any HP48G/49G/50G series calculator:
  @groups.google.com/group/comp.sys.hp48/msg/8888908f27145901?dmode=3Ds=
  @ource
  @www.hpcalc.org/details.php?id=3D6431 (ROLDXJ, contains binaries)
  @
  @
  @A program INFORML is also provided below,
  @which accepts the exact same five arguments as INFORM,
  @but calls INLIST instead, so that you may merely
  @change INFORM to INFORML in your existing programs that use INFORM.
  @
  @
  @A program INLISTF is also provided below,
  @which accepts the fewer arguments needed by INLIST,
  @but calls INFORM instead, so that you may merely
  @change INLIST to INLISTF in existing programs that use INLIST.
  @
  @
  @If you require all form fields to be filled in,
  @to avoid any skipped fields returning NOVAL as their value,
  @programs INLISTN and INFORMN are also provided,
  @which accept the identical arguments, but automatically
  @repeat INLIST or INFORM until the results are free of any NOVAL.

      @ Sample program for INPROMPT:
  tinp
  \<< "Enter X" INPROMPT "X" \->TAG
    "Enter Y" INPROMPT "Y" \->TAG 
  \>>

  @ INPROMPT (all HP48/49/50)
  INPROMPT
  \<< 10. CHR + "then press menu key" + @ optional hint
    { { "OK"  \<< 0. MENU CONT \>> }
    { "(AN(L" \<< 0. MENU KILL \>> } }
    TMENU PROMPT 
  \>>

  @ ---

  @ Sample program for INMENU:
  tinm
  \<< "Value [menu key]" { X Y } INMENU
    X "X" \->TAG  Y "Y" \->TAG
    'X+Y' EVAL "X+Y" \->TAG
    'X*Y' EVAL "X*Y" \->TAG 
  \>>

  @ INMENU (48G/49G/50G) store input to variables instead of stack
  @ Args: "Title" { labels }      Nothing returned on stack.
  @ "One touch" to store, DONE returns, LeftShift DONE aborts,
  @ RightShift recalls, RightShift CursorDown reviews values.
  @ "Real" numbers stored into "unit" objects preserve the units!
  INMENU
  \<< { @ the next line is an optional tweak for up to 5 variables
    { "SHOW"  \<< #A300Eh RCLF SIZE 3. < 2. * + LIBEVAL \>> }
    { "DONE" { \<< 0. MENU CONT \>> \<< 0. MENU KILL \>> } } } +
    TMENU RCLF SIZE 3. > #25EFFh #151A6h IFTE SYSEVAL PROMPT 
  \>>
  @ Caution: First back up memory! Incorrect SYSEVALs are harmful!
  @ Also note the difference between LIBEVAL and SYSEVAL

  @ ---

  @ Test program for INLIST[N]:
  tinl
  \<< "Test INLIST"
    { { "Set VX to" 6. } { "Any Number" 0. 28. } "Required field" }
    { X 123 } DUP INLIST 
  \>> @ or INLISTN to avoid NOVAL
  @ Note that INFORM would throw an error on type code 28

  @ Complete INLIST (in UserRPL) for HP48G/49G/50G
  INLIST
  \<< 3. PICK TYPE 2. == { { } SWAP } IFT @ Omitted resets?
    3. PICK 1. \<< DROP NOVAL \>> DOSUBS @ Pad values lists
    1. DUP2 6. ROLL REPL 4. ROLLD ROT REPL @ To match prompts
    0. RCLF { GET DUP TYPE 2. == { 34. CHR SWAP OVER + + }
    IFT DUP NOVAL SAME { DROP "" } IFT \->STR } RCLMENU \-> h.
    p. b. a. n. f. c. m. \<< -55. SF 64. STWS STD DO IF h. p.
    @ Build a new CHOOSE list (showing current values):
    1. \<< { } + 1. GET "=" + a. NSUB c. EVAL + NSUB 2. \->LIST
    \>> DOSUBS { "<DONE>" "[Reset All]" } + 'n.' INCR
    @ Exit or "reset all" if either was selected:
    CHOOSE THEN DUP 'n.' STO IF TYPE THEN IF n. " " POS THEN
    b. 'a.' STO 0. DUP 'n.' STO ELSE a. 1. 1. END ELSE
    @ Get the prompt and current value for INPUT (editor):
    p. n. GET { } + 1. GET \->STR a. n. c. EVAL 28. MENU
    IFERR INPUT "{" SWAP + STR\-> DUP SIZE 1. > { DROP 7. DOERR }
    @ Reset if null input, halt for CALC if "equal" command:
    IFT LIST\-> NOT { b. n. GET } IFT { = } OVER POS { DROP
    DEPTH \->LIST a. n. GET RCLF \-> s. v. g. \<< p. n. GET
    { } + TAIL DUP SIZE NOT { { ALL } + } IFT "Types" \->TAG
    f. STOF v. HALT g. STOF DEPTH NOT { v. } IFT DEPTH ROLLD
    DEPTH 1. - DROPN s. LIST\-> DROP DEPTH ROLL \>> } IFT
    @ Object type restrictions:
    DUP NOVAL SAME NOT { p. n. GET { } + TAIL DUP SIZE
    { 0. ADD OVER TYPE POS NOT { DROP 7. DOERR } IFT }
    { DROP } IFTE } IFT @ Okay @ 'a.' n. ROT PUT THEN
    ERRN B\->R { "Invalid object or type" MSGBOX } IFT
    'n.' DECR DROP END m. TMENU 0. END
    ELSE 0. 1. END UNTIL END f. STOF \>> 
  \>>

  @ Auxiliary programs:

  @ Loop on INLIST until no undefined value (NOVAL) in results
  @ [takes the same args as INLIST]
  INLISTN
  \<< 3. PICK TYPE 2. == { { } SWAP } IFT 4. ROLLD \->
    t. p. b. \<< 1. DO DROP t. p. b. 4. ROLL INLIST DUP DUP
    { DROP OVER NOVAL POS } IFT UNTIL NOT END \>> 
  \>>

  @ Loop on INFORM until no undefined value (NOVAL) in results
  @ [takes the same args as INFORM]
  INFORMN
  \<< 5. ROLLD \-> t. p. f. b. \<< 1. DO DROP t. p. f. b.
    5. ROLL INFORM DUP DUP { DROP OVER NOVAL POS } IFT
    UNTIL NOT END \>> 
  \>>

  @ This takes args for INFORM, but calls INLIST instead
  INFORML
  \<< ROT DROP ROT 1. \<< { } + DUP SIZE { DUP HEAD SWAP TAIL TAIL
    + } { DROP } IFTE \>> DOSUBS ROT ROT INLIST 
  \>>

  @ This takes args for INLIST, but calls INFORM instead
  INLISTF
  \<< 3. PICK TYPE 2. == { { } SWAP } IFT ROT 1. \<< { } +
    DUP HEAD "" + { "" } + SWAP TAIL + \>> DOSUBS DUP SIZE
    DUP 4. MIN / CEIL 4. ROLL 4. ROLL INFORM 
  \>>

  @#############################################################################
  @#
  @#
  @#
  @ some expanding data structures speed test
  @ as expanding lists is costly
  
  gpListExp
  \<< @on an emu48 emulator on a pentium M 1.73ghz , 741 seconds. Woah.
    \<< @always expand a list
      {}
      1 1000
      FOR lvK
        lvK +
      NEXT
    \>>
    TEVAL
    "listExp"
  \>>
  
  gpListRepl
  \<< @on an emu48 emulator on a pentium M 1.73ghz , 917 seconds. Woah.
    \<< @preallocate list and replace elements
      0 1000 NDUPN \->LIST
      1 1000
      FOR lvK
        lvK lvK PUT
      NEXT
    \>>
    TEVAL
    "listRepl"
  \>>
  
  gpVectRepl
  \<< @on an emu48 emulator on a pentium M 1.73ghz , 11.43 seconds. that's fast
    \<< @preallocate list and replace elements
      0 1000 NDUPN \->ARRY
      1 1000
      FOR lvK
        lvK lvK PUT
      NEXT
    \>>
    TEVAL
    "vectRepl"
  \>>
  
  @##################################
  @# 
  @# Links and todo
  
  linksAndTodo
"
- For programs that are not yet ported in this library (including some testing)
  at least links to the source may help, as long as the link is valid
  and the source is reachable (that, as experience shows, is better not to take
  for granted on internet)
  
- when expanding large lists (over 100 elements) the execution become stuck in the mud.
  How is it with arrays? (although arrays are less expressive than lists)
  How is it with pre allocated large lists where elements gets replaced from their
  dummy value and how it is with pre allocated attays?
  
  Is there some gain in speed?
  
- arguments check
  http://www.hpmuseum.org/forum/thread-7955-post-92718.html#pid92718
  
- An example of thousands separator
  http://www.hpmuseum.org/forum/thread-8555-post-92731.html#pid92731
  
- displaying long text in a 'page'
  http://www.hpmuseum.org/forum/thread-4635-post-41692.html#pid41692
  
- quicksort
  ftp://www.hpmuseum.org/lif/swap/swap10/hp28v6n7.txt
  
- mirror bits
  http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv018.cgi?read=144896
  
- digits not in a number
  http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv019.cgi?read=171632
  
- add also a list to a list, without exploding the added list
  http://www.hpmuseum.org/forum/thread-8555-post-93881.html#pid93881
  
- list processing and commands missing from goferlist / listExt and discussion about
  list / vector data structures
  http://www.hpmuseum.org/forum/thread-8209.html
  http://www.hpmuseum.org/forum/thread-8555.html
  http://www.hpmuseum.org/forum/thread-8555-post-94028.html#pid94028
    (the above about multiple PUTs)
    
- http://www.hpmuseum.org/forum/thread-8853.html
  how many divisors of X. sum of divisors. Sum of proper divisors.
  Product of all the divisors.
  
    
- improving the angle between vectors
  http://www.hpmuseum.org/forum/thread-10271-post-93744.html#pid93744
  
- program to convert ascii text in usrpl for SD card programs and emulators
  https://groups.google.com/forum/#!msg/comp.sys.hp48/loZFVECTxpY/QhzxPAvZfk4J
  also on the emu48 official page.
  http://hp.giesselink.com/emu48.htm
  (can be that there are other alternatives around, would be nice to at least list them)
  workaround: using com0com for the emulator and conn4x as the virtual calculator
  would be a real one.
  http://www.hpmuseum.org/forum/thread-7955-post-96874.html#pid96874
  
- create a so called 'anti identity matrix' 
  http://www.hpmuseum.org/forum/thread-10735.html
  
- http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv019.cgi?read=159351
  some programs about housekeeping directories.

  doneTodos
- http://www.hpmuseum.org/forum/thread-8555-post-94235.html#pid94235
    (list min, list max)
    
- need is the main source of motivation to expand one's set of available solutions.
  Too long it took to include percentile functions.
"

  linkAndChallenges
  "
- in general the various online discussion places (see http://www.wiki4hp.com/doku.php?id=resources:start) are full of
  math and  programming challenges that are hard to be found, though. So collecting them in a list
  (thing that is missing since years) wouldn't be bad.  
  
  - How many integers (from 1 to 9999) are evenly divisible by the number of letters in their name?
    http://www.hpmuseum.org/forum/thread-2882.html
    
  - sum of squares given a fixed list of values
    http://www.hpmuseum.org/forum/thread-9962.html
  "
END
rpl/start.txt · Last modified: 2023/03/13 14:07 by pier4r