HHC 2018 Programming Contests - Printable Version +- HP Forums (https://www.hpmuseum.org/forum) +-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html) +--- Forum: General Forum (/forum-4.html) +--- Thread: HHC 2018 Programming Contests (/thread-11390.html) |
RE: HHC 2018 Programming Contests - Didier Lachieze - 10-03-2018 03:46 PM Nice way of rounding the result. You can also save a few steps with: Code: ▸LBL 14 RE: HHC 2018 Programming Contests - Werner - 10-04-2018 05:55 AM And I was so proud of my 3.6 \->HR find! But this is of course a lot better, thanks Didier! Werner RE: HHC 2018 Programming Contests - 3298 - 10-04-2018 02:48 PM 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. RE: HHC 2018 Programming Contests - Gerson W. Barbosa - 10-04-2018 03:47 PM 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 RE: HHC 2018 Programming Contests - Namir - 10-04-2018 06:09 PM (10-02-2018 04:33 PM)Joe Horn Wrote: Namir Shammas submitted this contest entry. Its elegance was unmatched (thankfully), and it gave me a good laugh. Thanks Joe for posting it as you had promised me. Namir RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 12:00 AM Craig Bladow's RPN contest entry can be downloaded from HERE. My observations about Craig's entry:
RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 12:11 AM Benoit Maag's RPN contest entry can be downloaded from HERE. My observations about Benoit's entry:
RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 12:36 AM Roger Hill's RPN contest entry can be downloaded from HERE. My observations about Roger's RPN entry:
RE: HHC 2018 Programming Contests - Didier Lachieze - 10-05-2018 05:07 AM (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. RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 06:22 AM (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. RE: HHC 2018 Programming Contests - Didier Lachieze - 10-05-2018 07:45 AM 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 RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 12:26 PM (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. RE: HHC 2018 Programming Contests - David Hayden - 10-05-2018 02:25 PM 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 RE: HHC 2018 Programming Contests - Gerson W. Barbosa - 10-05-2018 07:23 PM HP-48G/GX version: Code:
476.5 bytes, # 7FDEh RE: HHC 2018 Programming Contests - 3298 - 10-05-2018 08:26 PM 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.) RE: HHC 2018 Programming Contests - Joe Horn - 10-05-2018 09:32 PM 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! RE: HHC 2018 Programming Contests - Gerson W. Barbosa - 10-05-2018 09:51 PM (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. RE: HHC 2018 Programming Contests - Thomas Klemm - 10-06-2018 10:14 AM (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 RE: HHC 2018 Programming Contests - Gerson W. Barbosa - 10-06-2018 11:42 AM (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. RE: HHC 2018 Programming Contests - 3298 - 10-06-2018 12:07 PM 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). |