User Tools

Site Tools


rpl:start

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
rpl:start [2018/05/13 01:35]
pier4r added possible useful links related to passing data to a virtual calculator and anti identity matrix
rpl:start [2018/08/08 04:16] (current)
pier4r
Line 1: Line 1:
 +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
 +
 +<​file>​
 +%%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 
 +  ​
 +  @##################################​
 +  @# 
 +  @# 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
 +  \>>
 +  ​
 +  @##################################​
 +  @# 
 +  @# 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
 +  \>>
 +  ​
 +  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
 +  \>>
 +  ​
 +  @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
 +    \>>
 +  \>> ​
 +  ​
 +  ​
 +  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 /
 +  \>>
 +
 +  ​
 +  @##################################​
 +  @# 
 +  @# 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 \>>
 +  \>>
 +
 +  @url: '​www.hpmuseum.org/​forum/​thread-8209-post-81657.html#​pid81657',​
 +  @tags: [ 'list processing'​ ],
 +  @description:​
 +  @    increment an element in a list given the increment and the position
 +
 +  @input:
 +  @L3: list to increment
 +  @L2: position
 +  @L1: increment (or decrement with a negative number)
 +  @output: a list with the element in position incremented (or decremented
 +  @  by the specified amount)
 +  incrListElement
 +  \<<
 +     PICK3 PICK3
 +     GET + PUT
 +  \>>
 +
 +
 +  @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
 +    \>>
 +  \>>
 +  ​
 +  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
 +    \>>
 +  \>>
 +
 +  @##################################​
 +  @# 
 +  @# 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 ​
 +  \>>
 +
 +  ​
 +  @##################################​
 +  @# 
 +  @# 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)
 +  ​
 +- 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.
 +  ​
 +- http://​www.hpmuseum.org/​cgi-sys/​cgiwrap/​hpmuseum/​archv021.cgi?​read=243170
 +  Nice short idea how to keep a library of equations and to extensively use the
 +  SD card for text files.
 +
 +  doneTodos
 +- http://​www.hpmuseum.org/​forum/​thread-8555-post-94235.html#​pid94235
 +    (list min, list max)
 +"
 +
 +  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</​file>​
 +