List Commands Library for 50g
|
08-18-2018, 06:11 PM
Post: #383
|
|||
|
|||
RE: List Commands Library for 50g
The ListExt library has been updated at hpcalc.org. Release notes for this version (and a previous unreleased one) are provided below.
The library now includes a variety of stack manipulation commands (see the STACK menu category). Those commands can be used to duplicate, rearrange, and delete objects on the stack. The primary use case for these commands is to easily affect a large number of stack items without the need for setting up a loop to achieve the desired results. While they can also be used with minor stack alterations, the overhead required internally to load, initialize, and execute the function may actually take longer than simply executing a couple of built-in stack commands. The built-in stack commands perform extremely well, so they should be used whenever possible for critical sections of code where execution speed is important. Descriptions for the new commands follow the release notes listed below. ______________________________________________________________________________ Version 1.2.1 2018-08-17 - LDDUP bug fixed: sublists weren't handled properly as of the last update. - LDDUP adjusted to better balance performance in cases where lists have mostly duplicates. - LPICK replaced with a faster version, especially for smaller lists. ______________________________________________________________________________ Version 1.2.0 2018-08-01 - Rewrote main menu code and optimized its associated data structures, saving about 200 bytes. - Created work-around for bug in HP49g v1.24 firmware that affected SPLIT/SPLTR when presented with a list and an exact integer (commands inappropriately reported "Bad Argument Type"). - Increased performance of LROLL/LRLLD when using smaller lists. - Lists produced by the following commands now use internal opcodes for numeric values in the -9..9 whole number range: LSEQ, LSEQR, LASEQ, LMSEQ, LDSEQ, I→NL, S→NL. This increases the likelihood of SAME being used successfully to compare the resulting lists to manually entered constants, and also reduces the size of some result lists. - LSWAP now saves the list to HOME temporarily before swapping the identified elements in order to avoid garbage collection issues. - LDDUP has been rewritten as a custom code object instead of simply being a wrapper for COMPRIMext, resulting in a significant performance boost with larger lists. - Minor update for I→BL to overcome rounding error when using real values close to 1E12. - Fixed bug in LXIL/LXILR for some lists that contained empty sublists. - Updates to the Command Description documentation: added installation instructions, reorganized general info, alphabetized detailed command descriptions, added "location" and "see also" references. - Added new STACK submenu in the main menu. - New commands added: NMDUP, NMROT, SWPXY, DRPXY, REVN, REVXY, SLST→, LNRML, LSAME. ______________________________________________________________________________ NMDUP (Duplicate a Group of Stack Items Multiple Times) Location: ListExt > STACK Input: N+2: <object 1> ... 3: <object N> 2: N (the size of the group of objects to replicate) 1: M (the number of replications after execution) Output: <NxM objects on the stack> Using the first N objects at the bottom of the stack as the basis, creates a total of M duplicates of the entire group. Any objects above the identified group when the command is executed are left intact above the replicated output of the command. If N is greater than the current stack depth, only the existing stack entries are duplicated. If M is 0, the identified group is deleted (similar to DROPN). If M is 1, the original group is left in place. Note: NMDUP can easily create more stack objects than the calculator is able to effectively manage. Care should be exercised when creating tens of thousands of objects, as that situation can compromise the stability of the calculator's operation. Examples: 1 2 3 4 5 3 0 NMDUP => 1 2 1 2 3 4 5 3 1 NMDUP => 1 2 3 4 5 1 2 3 4 5 3 2 NMDUP => 1 2 3 4 5 3 4 5 1 2 3 4 5 0 2 NMDUP => 1 2 3 4 5 5 6 7 8 4 4 NMDUP => 5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8 See also: NMROT ______________________________________________________________________________ NMROT (Rotate a Group of Stack Items) Location: ListExt > STACK Input: N+2: <object 1> ... 3: <object N> 2: N (the size of the group of objects to rotate) 1: M (the number of positions to shift) Output: <the same N objects, rotated as indicated> Rotates the lowest N objects on the stack through M positions. Positive M shifts stack levels up, negative M shifts down. A value of 0 for either N or M makes no changes to object positions. If N is greater than the number of objects currently on the stack, the entire stack is assumed to be the group size. If the stack was empty prior to adding N and M, those arguments will simply be dropped upon execution. Note: ROT/UNROT and ROLL/ROLLD can be thought of as special cases of the more generic NMROT. In particular: ROT = 3 1 NMROT UNROT = 3 -1 NMROT <n> ROLL = <n> 1 NMROT <n> ROLLD = <n> -1 NMROT The built-in commands (ROT/UNROT/ROLL/ROLLD) should always be used instead of NMROT if applicable, because they are faster and require fewer explicit arguments than NMROT does. NMROT is most useful with large rotations on large groups of objects, where you would normally need to construct a loop in a program to accomplish the same task. Examples: 1 2 3 4 5 0 0 NMROT => 1 2 3 4 5 1 2 3 4 5 3 0 NMROT => 1 2 3 4 5 1 2 3 4 5 3 1 NMROT => 1 2 4 5 3 (Note: same as ROT or 3 ROLL) 1 2 3 4 5 3 -1 NMROT => 1 2 5 3 4 (Note: same as UNROT or 3 ROLLD) 1 2 3 4 5 6 7 8 9 5 2 NMROT => 1 2 3 4 7 8 9 5 6 See also: NMDUP ______________________________________________________________________________ SWPXY (Swap Two Individual Stack Levels) Location: ListExt > STACK Input: <objects on stack> 2: Y (second stack level to swap) 1: X (first stack level to swap) Output: <same objects that were previously above SL2, with the indicated levels swapped> Swaps two arbitrary stack levels as indicated by the stack level numbers given in SL1 and SL2. The X and Y values are the level numbers before adding X and Y to the stack. The stack must contain enough objects for the given arguments or an error will be generated. If X and Y are equal, no changes to stack items are made. Examples: 5 4 3 2 1 5 5 SWPXY => 5 4 3 2 1 5 4 3 2 1 1 3 SWPXY => 5 4 1 2 3 5 4 3 2 1 3 4 SWPXY => 5 3 4 2 1 5 4 3 2 1 4 2 SWPXY => 5 2 3 4 1 See also: LSWAP ______________________________________________________________________________ DRPXY (Drop a Range of Stack Levels) Location: ListExt > STACK Input: 2: Y (last stack level to drop) 1: X (first stack level to drop) Output: <the same stack data with the indicated levels dropped> Drops the range of stack levels indicated, leaving all others intact. The indicated stack levels are inclusive; they, and all levels in between, will be dropped upon executing the command. The X and Y values are the level numbers before adding X and Y to the stack. Stack level arguments that extend beyond the range of existing stack objects are allowed (both positive and negative). Examples: 5 4 3 2 1 1 1 DRPXY => 5 4 3 2 5 4 3 2 1 5 5 DRPXY => 4 3 2 1 5 4 3 2 1 1 5 DRPXY => <empty stack> 5 4 3 2 1 4 2 DRPXY => 5 1 5 4 3 2 1 -5 0 DRPXY => 5 4 3 2 1 5 4 3 2 1 0 1 DRPXY => 5 4 3 2 5 4 3 2 1 -99 99 DRPXY => <empty stack> See also: DROPN ______________________________________________________________________________ REVN (Reverse Stack Entries) Location: ListExt > STACK Input: N+1: <object 1> ... 2: <object N> 1: N (the size of the group of objects to reverse) Output: <the same objects 1-N as above, reversed> Reverses the order of the lowest N objects on the stack. N of 0 or 1 has no effect on the stack objects. If the stack contains fewer items than N, all of the existing items are reversed. Examples: 1 2 3 4 5 0 REVN => 1 2 3 4 5 1 2 3 4 5 1 REVN => 1 2 3 4 5 1 2 3 4 5 4 REVN => 1 5 4 3 2 1 2 3 4 5 5 REVN => 5 4 3 2 1 See also: REV, REVXY ______________________________________________________________________________ REVXY (Reverse a Range of Stack Levels) Location: ListExt > STACK Input n+2: <object n> ... 3: <object 1> 2: index1 (number) 1: index2 (number) Output n: <object n> ... 1: <object 1> (the order of objects index1 through index2 are reversed) The order of the objects in the given range of stack levels is reversed. Index1 and index2 are both inclusive; those stack levels are included in the sequence of stack levels that are reversed. The order of the indices themselves is not important; the range will go from low to high regardless of which is entered on the stack first. Both index1 and index2 can extend beyond the range of stack levels currently occupied. If they do, the reversal only includes the currently occupied stack levels. Examples: (note that numeric values of input objects below match the initial stack levels) 10 9 8 7 6 5 4 3 2 1 2 5 REVXY => 10 9 8 7 6 2 3 4 5 1 10 9 8 7 6 5 4 3 2 1 -2 -5 REVXY => 10 9 8 7 6 5 4 3 2 1 10 9 8 7 6 5 4 3 2 1 10 99 REVXY => 10 9 8 7 6 5 4 3 2 1 10 9 8 7 6 5 4 3 2 1 -99 99 REVXY => 1 2 3 4 5 6 7 8 9 10 See also: REV, REVN, LSSR ______________________________________________________________________________ SLST→ (Safe LIST→) Location: ListExt > GROUP Input: 1: { list of 0 or more objects } Output: <list objects, 1 per stack level> 1: count of objects in the list SLST→ essentially does the same thing as LIST→, with one major difference: the exploded list objects are no longer embedded in the original list object in the TEMPOB area of the calculator's memory. This means they are no longer subject to causing extended pauses when the calculator processes a Garbage Collection event. SLST→ creates new copies of each element in the list, so it is slower than LIST→ to process. But with large lists, the extra time required to complete SLST→ is trivial when compared to the delay caused by any subsequent Garbage Collection event after the list has been exploded. The Garbage Collection issue can be mitigated by saving the list to a global variable first (ie. put it in a saved variable somewhere in HOME), but that may not always be appropriate. SLST→ can be useful when you don't want to save/delete a list just to process its contents. Examples: 12345 1000 NDUPN →LIST LIST→ « MEM » TEVAL => 33.3s on a 50g 12345 1000 NDUPN →LIST SLST→ « MEM » TEVAL => 0.3s on a 50g See also: LIST→ ______________________________________________________________________________ LNRML (Normalize List) Location: ListExt > TEST Input 1: { a list of 0 or more objects } Output 1: the same list, normalized Returns the given list, with all instances of exact numbers in the range -9..9 having been replaced by an internal opcode representing that same value. All other elements are left intact, including any numeric values that were already represented as opcodes. Note that there is no visible difference in the presentation of the list; the change is limited to the internal binary data format. This has 2 benefits: the amount of storage space needed for the list will be reduced if there were substitutions, and it provides a "common format" for lists that need to be compared for equality with a targeted set of numbers. Examples (exact mode assumed, and not applicable to the 49G): { 1 2 3 } { 2 4 6 } 2 / SAME => 0. { 1 2 3 } { 2 4 6 } 2 / LNRML SAME => 1. { 1 2 3 4 } 2 * BYTES => # 1AA0h 25.5 { 1 2 3 4 } 2 * LNRML BYTES => # 21A0h 15. See also: LSAME ______________________________________________________________________________ LSAME (List SAME) Location: ListExt > TEST Input 2: { list } 1: { list } Output 1: 0. or 1. Performs LNRML for the two lists in stack levels 1 and 2, then SAME. If the two lists have the same content after normalization, the result is 1. Otherwise, the result is 0 (results are always approximate numbers, regardless of mode). Note that LNRML only alters a list which contains exact integer elements, so there's no benefit to using LSAME instead of SAME unless you know in advance that the lists may contain this type of element. Example (exact mode assumed, and not applicable to the 49G): { 1 2 3 } { 2 4 6 } 2 / LSAME => 1. See also: LNRML |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 4 Guest(s)