List Commands Library for 50g
|
08-08-2018, 03:06 PM
(This post was last modified: 08-08-2018 10:59 PM by DavidM.)
Post: #381
|
|||
|
|||
RE: List Commands Library for 50g
OK, so here's another way to get the distributions (different - not suggesting it's better or worse).
To try it out, place the definition of the die in SL2 (you could simply press the menu key for that die), then the number of dice thrown in SL1: Code: 2: { { 0 0 0 } { 1 0 0 } { 1 0 0 } { 1 0 0 } { 1 0 0 } { 2 1 0 } } Then execute "ThrowDistribution". The output should be: Code: { :64: { 3 0 0 } :48: { 4 1 0 } :48: { 2 0 0 } :24: { 3 1 0 } :12: { 5 2 0 } :12: { 1 0 0 } :3: { 4 2 0 } :3: { 2 1 0 } :1: { 6 3 0 } :1: { 0 0 0 } } Code: dieYellow |
|||
08-08-2018, 09:27 PM
Post: #382
|
|||
|
|||
RE: List Commands Library for 50g
Interesting approach.
Wikis are great, Contribute :) |
|||
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 |
|||
08-25-2018, 12:16 PM
Post: #384
|
|||
|
|||
RE: List Commands Library for 50g
Nice!
Wikis are great, Contribute :) |
|||
09-14-2018, 06:00 PM
(This post was last modified: 09-14-2018 06:00 PM by pier4r.)
Post: #385
|
|||
|
|||
RE: List Commands Library for 50g
Note. In the first post (that is likely the most reachable one) the list 1.1.3 is still listed, instead of 1.2.1
I am not sure if the first post as also the abstract (command summary) of the 1.2.1 or the one of the 1.1.3 Wikis are great, Contribute :) |
|||
09-14-2018, 08:40 PM
Post: #386
|
|||
|
|||
RE: List Commands Library for 50g
(09-14-2018 06:00 PM)pier4r Wrote: Note. In the first post (that is likely the most reachable one) the list 1.1.3 is still listed, instead of 1.2.1 pier4r - see post # 383 above. --Bob Prosperi |
|||
09-14-2018, 10:46 PM
Post: #387
|
|||
|
|||
RE: List Commands Library for 50g
Yes I saw it. Anyway the idea - as far as I understood following the thread - is to have the first post as up to date reference. Therefore I made a post noticing the difference between last release and first post.
Wikis are great, Contribute :) |
|||
09-17-2018, 03:37 PM
Post: #388
|
|||
|
|||
RE: List Commands Library for 50g
(09-14-2018 10:46 PM)pier4r Wrote: Yes I saw it. Anyway the idea - as far as I understood following the thread - is to have the first post as up to date reference. Therefore I made a post noticing the difference between last release and first post. Yes, my intent was to keep the first post updated with the latest release notes/command descriptions -- sorry for the delay. I've updated the post now to include the latest info. I also deleted the old attachment, as the most up-to-date version is now available at hpcalc.org. There's a note to that effect at the top of the first post in the thread. Thanks for pointing it out! |
|||
09-17-2018, 08:28 PM
(This post was last modified: 09-17-2018 08:30 PM by StephenG1CMZ.)
Post: #389
|
|||
|
|||
RE: List Commands Library for 50g
In your documentation/tests, might I suggest adding an example for LMRPT (although perhaps it is not an issue on your platforms):
999 1 LMRPT Implementing a similar function on the Prime, I noticed that 999 3 was forming a list, but 999 once returned a value rather than a list. I assume always returning a list would be preferable. Also, a typo somewhere: "singe" instead of "single". Stephen Lewkowicz (G1CMZ) https://my.numworks.com/python/steveg1cmz |
|||
09-18-2018, 10:47 AM
Post: #390
|
|||
|
|||
RE: List Commands Library for 50g
(09-17-2018 08:28 PM)StephenG1CMZ Wrote: In your documentation/tests, might I suggest adding an example for LMRPT (although perhaps it is not an issue on your platforms): The "singe" typo was found in the description for the LMRPT command; it is now corrected (along with a couple other scattered mishaps here and there). I also added the "999 1 LMRPT" example to the documentation. I agree that the result of LMRPT should always be a list, regardless of the input it is given (LMRPT has always always worked that way). Thanks for spotting the typo and the example suggestion! These changes are now in my master source and will be included in a future update. |
|||
09-18-2018, 03:32 PM
(This post was last modified: 09-20-2018 12:38 PM by John Keith.)
Post: #391
|
|||
|
|||
RE: List Commands Library for 50g
The discussion of LMRPT reminds me of the recently added command LRPC\->. While it is the complement to the command LRPCT which run-length encodes a list, it can be very useful in its own right.
As an example, this simple program Code:
returns the first T(n) terms of A002024, where T(n) is the nth triangular number. The above program is similar to the second Haskell program in the OEIS link. It is also quite fast: given an input of 100, it returns the first 5050 terms in less than 700 milliseconds. A longer (and clunkier) example Code:
returns the nth iteration of the Kolakoski sequence. The program is longer and more involved than the Haskell program in the Kolakoski link because the infinite lists and "lazy" evaluation of Haskell make the explicit calculation of list lengths unnecessary. (Edited to remove the CEIL command following DavidM's comments below) These programs also demonstrate the similarity of LMRPT and LRPC\-> to the Haskell functions cycle and replicate respectively. |
|||
09-19-2018, 10:20 PM
Post: #392
|
|||
|
|||
RE: List Commands Library for 50g
(09-18-2018 03:32 PM)John Keith Wrote: As an example, this simple program Very nice! I had a feeling LRPC→ might be useful for something other than undoing LRPCT, but hadn't yet run into it. Glad to see it put to use! (09-18-2018 03:32 PM)John Keith Wrote: A longer (and clunkier) example... Even after reading the OEIS description, I'm not sure I understand that sequence. It grows rapidly, that's for sure. I believe you should be able to leave out the CEIL function, though, as the result after division by 2 will round up appropriately for LMRPT. This is the same type of handling for counts/indices that most RPL commands apply in similar situations. These are interesting applications of list processing -- thanks for sharing! |
|||
09-20-2018, 12:35 PM
Post: #393
|
|||
|
|||
RE: List Commands Library for 50g
(09-19-2018 10:20 PM)DavidM Wrote: Even after reading the OEIS description, I'm not sure I understand that sequence. It grows rapidly, that's for sure. I believe you should be able to leave out the CEIL function, though, as the result after division by 2 will round up appropriately for LMRPT. This is the same type of handling for counts/indices that most RPL commands apply in similar situations. Ha! you're right. Somehow I had always assumed that RPL commands rounded down, not to the nearest integer. I will try to remember that. The Kolakoski sequence is definitely a head-scratcher. The Wikipedia article has a somewhat more readable description. The first line of the article says it is "an infinite sequence of symbols {1,2} that is its own run-length encoding". That sentence inspired me to try the LRPC\-> command. |
|||
01-26-2019, 11:38 PM
(This post was last modified: 01-26-2019 11:38 PM by pier4r.)
Post: #394
|
|||
|
|||
RE: List Commands Library for 50g
Maybe I already asked it, anyway I don't remember it.
What about "create a list of N random integers (although it being reals) between A and B" ? I know the user rpl is fairly easy, but again my approach is the usual "having it ready made". Wikis are great, Contribute :) |
|||
01-27-2019, 05:15 PM
Post: #395
|
|||
|
|||
RE: List Commands Library for 50g
(01-26-2019 11:38 PM)pier4r Wrote: Maybe I already asked it, anyway I don't remember it. This feels much like the previous discussion that started around post #182. Especially after all of the headache that came from validating LSHUF, I'm leery of diving into the "random pool" again. If you read through the previous posts on this topic (referenced above), you'll find some other pertinent discussion points. Given A, B, and N on the stack, you could always do something like the following. This uses John Keith's suggestion of using LPICK, which is much faster than repeated calls to GET: Code: \<< This assumes that duplicates are allowed, and that you're ok with the built-in RAND distribution. There's lots of variations possible for this kind of application, and the specific needs may vary depending on the problem at hand. |
|||
01-27-2019, 06:44 PM
(This post was last modified: 01-27-2019 07:33 PM by pier4r.)
Post: #396
|
|||
|
|||
RE: List Commands Library for 50g
Understood. (also nice memory about the post #182 . I am going to follow my own advice at the end of my post. Lazy me)
About your example, thanks for reporting the info that John Keith found, I did not remember that, but isn't the list to pick from a bit of overhead? I modified a bit your code (to adapt to my syntax highlighting, see n1), I'll add it here when I can reach the site again, for the moment it is here instead. Code:
n1: for notepad++ https://app.assembla.com/spaces/various-...serrpl.xml edit: adding that some commands of listExt are awesome. KSORT. LLAST (that doesn't complain if I say 'I want more than the list size') Really speeding up thinking time. Wikis are great, Contribute :) |
|||
01-27-2019, 06:52 PM
(This post was last modified: 01-29-2019 06:17 PM by John Keith.)
Post: #397
|
|||
|
|||
RE: List Commands Library for 50g
Here is my version. I have not compared it to David's but it allows a and b to be large integers without excessive memory consumption. The redundant nature of the program is to minimize execution time while returning exact or approximate integers depending on mode.
Edited to fix bug that would cause negative values to be off by 1. Code:
To use the program, level 3 has the number of terms, level 2 has b, and level 1 has a. So if you enter 100 1000 1000000 and execute the program you will get a list of 100 random integers between 1000 and 1000000. The program could be easily shortened and simplified if one wanted to use it only in one mode. |
|||
01-27-2019, 07:07 PM
(This post was last modified: 01-27-2019 07:12 PM by pier4r.)
Post: #398
|
|||
|
|||
RE: List Commands Library for 50g
Thanks John!
About RAND a * b + IP. I used it too at first but it messes up when integers are negative if I am not mistaken. Sure the mode that works also with arbitrary integers is neat. If you fix it I put it in the collection too. Could you ping me if you do it? Also I don't remember where but there was a discussion that RAND a * IP has a micro chance to fail compared to RAND a * CEIL under some edge cases. More links here. http://www.hpmuseum.org/forum/thread-103...l#pid93209 Wikis are great, Contribute :) |
|||
01-27-2019, 07:34 PM
Post: #399
|
|||
|
|||
RE: List Commands Library for 50g
You're right, the random integers can be off by 1 if a is negative. If I can fix it I will post the correction.
As far as IP vs CEIL, the documentation says RANDs have a range of 0<n<1. Even if it was possible for RAND to return a 0, there is only 1 chance in 10^12 of that happening so I don't worry about it. |
|||
01-27-2019, 10:02 PM
Post: #400
|
|||
|
|||
RE: List Commands Library for 50g
The probability of RAND returning zero is exactly zero. It can't happen.
See http://www.hpmuseum.org/forum/thread-9556.html |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 1 Guest(s)