HHC 2018 Programming Contests
|
10-03-2018, 03:46 PM
Post: #61
|
|||
|
|||
RE: HHC 2018 Programming Contests
Nice way of rounding the result. You can also save a few steps with:
Code: ▸LBL 14 |
|||
10-04-2018, 05:55 AM
Post: #62
|
|||
|
|||
RE: HHC 2018 Programming Contests
And I was so proud of my 3.6 \->HR find!
But this is of course a lot better, thanks Didier! Werner 41CV†,42S,48GX,49G,DM42,DM41X,17BII,15CE,DM15L,12C,16CE |
|||
10-04-2018, 02:48 PM
(This post was last modified: 10-04-2018 05:14 PM by 3298.)
Post: #63
|
|||
|
|||
RE: HHC 2018 Programming Contests
Some optimization applied to my previous solution:
- Instead of this 1. \<< MIN \>> DOLIST trick to get the lowest member of the list (which also needed a big enough initial number on the stack above the list), SORT HEAD does the same slightly more elegantly (and without needing the big number). As a performance-oriented SysRPL coder SORT was simply not on my radar (all that sorting of elements that get dropped by HEAD anyway, what a waste of CPU cycles!), so thanks to Gerson W. Barbosa for bringing it to my attention via his program. - I did use automatic list-based parallel processing already, but there was another DOLIST I could drop by resorting to simple parallel processing: the one calculating and tagging the function values at the end. - The even distribution of E's extrema allowed for further optimization by halving the modulo of each function pair involving E (i.e. P+E and E+I) and dropping two of the four extrema out of their corresponding lists. The remaining function pair had no potential for such an optimization though. Thanks to Werner for pointing that out; the even distribution was obvious, but I failed to realize how I could use it for the program until I read his comment. - The smallest number out of the smallest numbers of three lists is simply the smallest number of the concatenated lists, so the remaining DOLIST no longer reduces its lists to single numbers; instead these lists get flattened into one after DOLIST finishes (EVAL + +), and only then the smallest member is picked out via SORT HEAD. The only remaining DOLIST could unfortunately not be optimized away, because UserRPL's automatic parallel processing when lists are encountered is not recursive. As you can clearly see in the code, I have a list containing three sublists where I apply certain operations to all members of the sublists - automatic parallel processing does not cut it, I have to use DOLIST for explicit parallel processing. I did shorten the subprogram passed to DOLIST a bit though, in addition to the shortening mentioned in the "smallest number out of the smallest numbers" paragraph above - instead of passing the age in via a local variable, it's passed in via an additional list that contains three copies of it, one per run of the subprogram. That and removing the last DOLIST meant I don't need the local variable at all, so I just keep that copy needed for calculating the function values on the stack instead. Code: \<< In terms of performance, this completes in If one wanted to accelerate or shrink it even further, the optimization of baking the first 1. + into the list of extrema distances from day 0 by decrementing them by one (which I mentioned in the notes for my first version already; though I forgot to mention that the other 1. + has to be moved a bit for results to stay correct) is still possible but not used in the name of readability ~= elegance. The tagging parts could be removed (making the output less pretty), and the replacement to SORT HEAD could be undone (this one is actually a tradeoff between size and speed, because SORT HEAD is shorter than what it replaced). If one doesn't care about preserving the user's angle mode, there are four more commands that could be removed by not saving and restoring it. All in all, I could get it down to 301.5 bytes without sacrificing correctness. Not sure if it's possible to get it even smaller. |
|||
10-04-2018, 03:47 PM
(This post was last modified: 10-05-2018 07:20 PM by Gerson W. Barbosa.)
Post: #64
|
|||
|
|||
RE: HHC 2018 Programming Contests
Code:
(04-Oct-2018, 16:41) P.S.: The output has been improved by a little bit at the cost of a few bytes. No tagging, but the order is { P E I } : Code:
444 bytes, CK = # 99F8h 22.021950 -> 30.012019 {-100. 100. 0.} P.P.S.: 1 GET is less elegant than HEAD, but takes a nibble less. Also, on the HP-50g NIP is shorter than SWAP DROP: Code:
441 bytes, CK = # DD4Dh |
|||
10-04-2018, 06:09 PM
Post: #65
|
|||
|
|||
RE: HHC 2018 Programming Contests | |||
10-05-2018, 12:00 AM
Post: #66
|
|||
|
|||
RE: HHC 2018 Programming Contests
Craig Bladow's RPN contest entry can be downloaded from HERE.
My observations about Craig's entry:
<0|ɸ|0> -Joe- |
|||
10-05-2018, 12:11 AM
Post: #67
|
|||
|
|||
RE: HHC 2018 Programming Contests
Benoit Maag's RPN contest entry can be downloaded from HERE.
My observations about Benoit's entry:
<0|ɸ|0> -Joe- |
|||
10-05-2018, 12:36 AM
(This post was last modified: 10-05-2018 12:37 AM by Joe Horn.)
Post: #68
|
|||
|
|||
RE: HHC 2018 Programming Contests
Roger Hill's RPN contest entry can be downloaded from HERE.
My observations about Roger's RPN entry:
<0|ɸ|0> -Joe- |
|||
10-05-2018, 05:07 AM
(This post was last modified: 10-05-2018 05:08 AM by Didier Lachieze.)
Post: #69
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-05-2018 12:00 AM)Joe Horn Wrote: If I'm not wrong, 10/22/2018 is not an answer as the physical extrema (100) happens during 10/21/2018 (day 23074.75) and the intellectual extrema (100) during 10/22/2018 (day 23075.25), while the emotional value is at 62. For 8/19/1955 my PPL program returns 4/12/2019 as the next extrema Date. |
|||
10-05-2018, 06:22 AM
Post: #70
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-05-2018 05:07 AM)Didier Lachieze Wrote:(10-05-2018 12:00 AM)Joe Horn Wrote: Biorhythm values are calculated only on a whole number of days since birth (not fractions of days) and are then rounded to the nearest integer. On day 23075, both the Physical and Intellectual biorhythm is 100, so it is a Maxima Day. <0|ɸ|0> -Joe- |
|||
10-05-2018, 07:45 AM
Post: #71
|
|||
|
|||
RE: HHC 2018 Programming Contests
OK, so this makes my PPL program a little bit simpler:
Code: EXPORT EXTREMA(BD) Do you have a list of test dates and results to check? Here are some results from the program above: Code: Birthday : 1955.0819 |
|||
10-05-2018, 12:26 PM
(This post was last modified: 10-05-2018 01:19 PM by Joe Horn.)
Post: #72
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-05-2018 07:45 AM)Didier Lachieze Wrote: Do you have a list of test dates and results to check? Your results are all correct. Here are some of the inputs & expected outputs that were used to test the contest entries on 30 Sept 2018. All dates below are shown in MM/DD/YYYY format. Input Date --> Next Extrema Date { P E I } 05/18/1975 --> 04/14/2019 { 100 -100 -19 } 05/19/1975 --> 10/01/2018 { -100 -100 19 } 02/12/2007 --> 10/01/2018 { -100 -100 -100 } 10/29/1989 --> 02/03/2019 { -100 -100 -54 } 03/02/1969 --> 03/31/2019 { 100 100 99 } 05/09/1968 --> 10/11/2018 { -100 -100 54 } 01/23/1921 --> 02/03/2019 { -100 -100 0 } 08/07/1921 --> 03/31/2019 { -82 -100 -100 } *** 09/19/1920 --> 11/27/2018 { 100 -90 -100 } *** That's the only input which I've found which your program gets a different result for (after changing "Date" in your program to "2018.0930" of course). EDIT: Oh, now I see why. Your program starts looking for the "next" Maxima Date TODAY. The contest specified "not including today". That's an easy program adjustment. <0|ɸ|0> -Joe- |
|||
10-05-2018, 02:25 PM
Post: #73
|
|||
|
|||
RE: HHC 2018 Programming Contests
After the conference and before checking the forum, I worked on an RPL solution using the MOD tricks that others have also found. Recognizing that the maximum days of the E cycle (days 7 and 14) are the same as a 14 days cycle with maximum on day 7 and using the ICHINREM command on the 50g, I found that the extreme days occur on:
[ 91 371 ] MOD 462 [ 190 305 454 569 ] MOD 759 [ 63 259 ] MOD 322 My contribution to the thread is in how, given a number that's less than the modulus, I find the first value in the array after the number. For example, given 100, I want to find 371 in the first list, or 190 in the second, or 259 in the third. You can almost find the next value in the array with: Code: @ Level 2 is array There are two problems with this code. First, if you find the last value then GETI will go back to 1, so the final "1 - GET" won't work. I solve this by adding an extra dummy number at the end of the list. Second, what if the value you're looking for is larger than the largest value? For example, with [ 91 371 ] MOD 462, what if you're looking for 400? In that case, you need to find the value that's 91 MOD 462 in the next cycle (553). So the trick is to feed this code with an array that contains (1) the first number in the next cycle, and (2) an extra dummy entry at the end: For modulus 462, search [ 91 371 553 0] For modulus 759, search [ 190 305 454 569 949 0] For modulus 322, search [ 63 259 385 0] My code (again, not my conference entry, but developed before looking at the forum) runs in about .87 seconds on a 50g, including pretty tagging of the results. I can probably shorten that using some of the list processing techniques that others have used. I'll post the full code when I'm done. Dave |
|||
10-05-2018, 07:23 PM
Post: #74
|
|||
|
|||
RE: HHC 2018 Programming Contests
HP-48G/GX version:
Code:
476.5 bytes, # 7FDEh |
|||
10-05-2018, 08:26 PM
Post: #75
|
|||
|
|||
RE: HHC 2018 Programming Contests
Gerson, I just stepped through your code to get a feeling of how it works; I couldn't help but notice some less-than-optimal pieces in there.
- In the condition part of your WHILE loop, you use HEAD. That's the optimal solution. - Right after the END of the WHILE loop, you use 1. GET. Same thing, but slower, bulkier, and most likely less elegant. - In the long final line of code, you use OBJ\-> DROP DROP2 on a three-element list. Again, the same result, but also slower, bulkier, and most likely less elegant than the dedicated command. In the 50g version you also used 3. NDUPN \->LIST in one place and DUPDUP \->V3 AXL in another for the same purpose. (The first one is shorter, by the way. Concerning elegance, it's probably a wash, but the lack of consistence doesn't quite sit right with me. I'm not the judge though.) In the 48GX version they became more similar, 1. 2. START DUP NEXT 3. \->LIST for the first one and DUP DUP 3. \->LIST for the second one. (I'd prefer the second one there.) The 48GX version has another instance of START DUP NEXT, but with four iterations this time. I realize that it's part of a simple replacement for NDUPN, but just writing DUP DUP DUP DUP would shorten it by 2.5 bytes without a significant impact on readability ≃ elegance. (Erm, wait a minute. Tilde as dead key followed by = on Linux produces the "approximately equal" symbol? Awesome! Didn't even know it was mapped on the keyboard.) |
|||
10-05-2018, 09:32 PM
Post: #76
|
|||
|
|||
RE: HHC 2018 Programming Contests
Here is Eddie Shore's winning PPL entry:
Code: sub1(); // elegant background screen When run, it shows this splash screen: The code seems to indicate that Eddie intended this screen to also say "Find your fate", but the position specified for that text is off the screen... a minor cosmetic bug. Eddie, where did you intend those three lines of text to appear? The program then uses an input form to get the user's birthdate, with proper prompts: It then outputs the next Extrema Date in elegant fashion: Congrats to Eddie! <0|ɸ|0> -Joe- |
|||
10-05-2018, 09:51 PM
Post: #77
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-05-2018 08:26 PM)3298 Wrote: - In the condition part of your WHILE loop, you use HEAD. That's the optimal solution. Points taken. “1 n-1 START DUP NEXT n” as a replacement for NDUPN was done mechanically when I realized the HP-48 lacked it. Your advice not to use that for small n is correct. By replacing those with DUP DUP sequences I’ve manage to save ten bytes. HEAD takes one additional nibble when compared to “1 GET”, but I didn’t know the former was more efficient as I haven’t timed both options. Yes, there are really some inconsistencies here and there, mainly because sometimes I am after smaller code and sometimes I want to be more clear. At this point I am glad my program works. Optimizations and improvements should be the next step, but I tend to stick with my first ideas, even though when are better ones around, so mine will not evolve much from here. |
|||
10-06-2018, 10:14 AM
(This post was last modified: 10-06-2018 10:21 AM by Thomas Klemm.)
Post: #78
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-05-2018 07:23 PM)Gerson W. Barbosa Wrote: “1 n-1 START DUP NEXT n” as a replacement for NDUPN was done mechanically when I realized the HP-48 lacked it. You don't even need that since lists can handle that: Code: \<< RCLF RAD Cheers Thomas Just noticed that: Code: SORT OBJ\-> DROP DROP2 Code: SORT HEAD |
|||
10-06-2018, 11:42 AM
Post: #79
|
|||
|
|||
RE: HHC 2018 Programming Contests
(10-06-2018 10:14 AM)Thomas Klemm Wrote:(10-05-2018 07:23 PM)Gerson W. Barbosa Wrote: “1 n-1 START DUP NEXT n” as a replacement for NDUPN was done mechanically when I realized the HP-48 lacked it. This saves 47 bytes overall. 429.5 bytes on the 48G/GX and 422 bytes on the 50g (using UNROT for ROT ROT and NIP for SWAP DROP). Thank you very much! Gerson. |
|||
10-06-2018, 12:07 PM
Post: #80
|
|||
|
|||
RE: HHC 2018 Programming Contests
Further improvement: DUP DATE DUP ROT ROT DDAYS can be DATE DUP2 DDAYS instead. Also applies to the 50g version where the new UNROT was used in place of ROT ROT.
Later in the program there's DUP ROT ROT which can be SWAP OVER. In SysRPL there's a command that is named both DUPUNROT and SWAPOVER because these operations are equivalent, but since UNROT is not a thing in the 48 version of UserRPL, the latter translates to a shorter UserRPL command sequence. On the 50g it's irrelevant of course. (10-05-2018 09:51 PM)Gerson W. Barbosa Wrote: HEAD takes one additional nibble when compared to “1 GET”, but I didn’t know the former was more efficient as I haven’t timed both options.Wait, HEAD is a romptr? HP, why!? I didn't actually check the length because I just assumed that such a basic command would be part of the command set which are merely simple pointers. Now I did, and you're right. HEAD is indeed a romptr, which makes it bigger than the more flexible (as in: can be changed to use other indices) 1 GET. At least on my 50g it's still slightly faster, so there's that (even though romptrs take a few milliseconds to resolve; I guess GET spends that time converting the real number to a system binary integer). |
|||
« Next Oldest | Next Newest »
|
User(s) browsing this thread: 32 Guest(s)