HHC 2013 RPN Programming Challenge - Final Thought Jeff O. Posting Freak Posts: 875 Threads: 37 Joined: Jul 2005 10-16-2013, 04:26 PM In case anyone wants a diversion from the Prime discussion, I had one final thought about the HHC 2013 RPN Programming Challenge that I’ve been meaning to bring up. (I’m probably the only person who spent much time on the challenge after about September 25, but I enjoy them and so tend to keep fiddling with them long after the conference.) I don’t have any new programming revelations or insights beyond what the group presented in the few days after conference, just this: I believe all of the solutions presented at the forum (except Pauli’s here) converted the octal value one digit at a time, from left to right. At some point, I began to wonder if it would be more accurate to convert the number from right to left, i.e., start with least significant digit. It seemed to me that conversion from right to left would more accurately get the carry correct from the far right digits. Perhaps that is not a real concern, but I decided to attempt to write a program to do so, probably just for the fun of it. While I was able to write a 15 step wp34s program to convert from left to right, the best I have done so far for right-to-left conversion is 27 steps, as follows: ```Step Command Comment 001 ENTER duplicate entered value 002 EXPT extract exponent 003 +/- change sign of exponent 004 #011 enter 11 005 + add 11 to exponent 006 #008 enter 8 007 x<>Y swap 008 y^x calculate multiple of 8 for least significant digit 009 x<>Y swap 010 MANT extract mantissa of N 011 SDL 10 multiply by 1E10 012 #000 enter 0 for initial converted value 013 <>YYZX get stack in right order 014 FRAC take fractional part (only one digit) 015 STO-Y subtract from original to get integer part in Y 016 SDL 01 multiply fractional part by 10 017 RCL/ Z divide by current power of 8 018 STO+ T add to current sum 019 CL x Clear X, disable stack lift 020 #008 enter 8 021 STO/ Z divide into current power of 8 for next power 022 Rdown roll down 023 SDR 01 divide by 10 024 ENTER duplicate N 025 x=/=0? check if done 026 BACK 012 loop back until done 027 RCL T done, recall converted value ``` The above is for a 12-digit entry, since that’s the most you can enter on a wp34s. If you enter a value with less than 12 digits, it dutifully converts the trailing zeroes. Although I did not intend this result, this program seems to work for any value that can be entered into a wp34s, i.e., is not limited to 0 <= n <= 1. It does of course assume a valid octal input, i.e. no 8s or 9s. I note that this program does produce what Pauli declares to be the “True” answer for an input of 1e-95, so perhaps it is more accurate? Gene Wright Posting Freak Posts: 1,545 Threads: 168 Joined: Jul 2005 10-16-2013, 05:41 PM Here it is. Works. ```LBL A STO 1 1 0 STO 8 CLX LBL B RCL 1 1 0 X ENTER F INT STO 4 - STO 1 RCL 4 1 1 RCL 8 - 8 X<>Y g Y^X / RCL 3 + STO 3 g DSZ GTO B RCL 3 R/S ``` Please feel free to improve upon this. :-) Geoff Quickfall Posting Freak Posts: 1,083 Threads: 126 Joined: Sep 2006 10-16-2013, 06:12 PM Which 65 did you use :-) Paul Dale Posting Freak Posts: 3,229 Threads: 42 Joined: Jul 2006 10-16-2013, 06:53 PM My solution was digit at a time right to left, albeit with some limitations on the number of decimal places and the maximum value. - Pauli Jeff O. Posting Freak Posts: 875 Threads: 37 Joined: Jul 2005 10-17-2013, 11:02 AM After I developed my right-to-left conversion program, I thought I’d better re-check the solutions presented here before I asserted that they were all left-to-right. (I admit to not having studied them all in detail on first reading.) Your program looked similar to others that did it left-to-right, but then I noticed the MOD instruction and deduced you were doing it right-to-left. Regarding your use of MOD, I decided to try that instead of my method using FP to strip off one digit right of the decimal and then multiplying by 10. Doing so required me to use a (local) storage register, but I was also able to make it one step shorter, down to 26: ```001 ENTER duplicate entered value 002 EXPT extract exponent 003 +/- change sign of exponent 004 #011 enter 11 005 + add 11 to exponent 006 #008 enter 8 007 x<>Y swap 008 y^x calculate multiple of 8 for least significant digit 009 x<>Y swap 010 MANT extract mantissa of N 011 SDL 11 multiply by 1E11 012 LocR 001 create one local register to accumulate sum 013 RCL X get stack in right order 014 #010 enter 10 015 RMDR extract units digit using RMDR 016 STO-Y subtract from original to remove units digit 017 RCL/ Z divide by current power of 8 018 STO+ .00 add to current sum 019 CL x Clear X, disable stack lift 020 #008 enter 8 021 STO/ Z divide into current power of 8 for next power 022 Rdown roll down 023 SDR 01 divide by 10 024 x=/=0? check if done 025 BACK 012 loop back until done 026 RCL .00 done, recall converted value ``` Of course if I use a local storage register in my original version, I also save a step. The local register starts at zero, and so eliminates the need to enter a zero, which then saves a stack manipulation step later: ```001 ENTER duplicate entered value 002 EXPT extract exponent 003 +/- change sign of exponent 004 #011 enter 11 005 + add 11 to exponent 006 #008 enter 8 007 x<>Y swap 008 y^x calculate multiple of 8 for least significant digit 009 x<>Y swap 010 MANT extract mantissa of N 011 SDL 10 multiply by 1E10 012 LocR 001 create one local register to accumulate sum 013 RCL X get stack in right order 014 FRAC take fractional part (only one digit) 015 STO-Y subtract from original to get integer part in Y 016 SDL 01 multiply fractional part by 10 017 RCL/ Z divide by current power of 8 018 STO+ .00 add to current sum 019 CL x Clear X, disable stack lift 020 #008 enter 8 021 STO/ Z divide into current power of 8 for next power 022 Rdown roll down 023 SDR 01 divide by 10 024 x=/=0? check if done 025 BACK 012 loop back until done 026 RCL .00 done, recall converted value ``` Assuming I understand it correctly, I like your method of adding a digit, then dividing by 8 to push the result one octal digit. Eliminates the need to raise 8 to some power and keep a running multiple of 8. I think I’ll see if I can work that into my method to handle all 12 digit inputs. Improved version, using Pauli's method to convert the mantissa from right to left, then shift that left or right as needed based on the exponent by raising 8 to the appropriate power: ```1 LocR 002 create two local registers 2 STO .01 store entered value 3 MANT extract mantissa of N 4 SDL 11 multiply by 1E11 5 RCL X duplicate value 6 #010 enter 10 7 RMDR extract units digit using RMDR (to work for neg) 8 STO-Y subtract from original to remove units digit 9 STO+ .00 add to current sum 10 #008 enter 8 11 STO/ .00 push sum one octal digit right 12 RCL Z Recall previous value less units 13 SDR 01 divide by 10 14 x=/=0? check if done 15 BACK 010 loop back until done 16 x<>Y swap 17 RCL .01 recall original entry 18 EXPT extract exponent 19 INC X add 1 to exponent 20 y^X 8^(EXPT+1) 21 RCLx .00 recall converted mantissa value, multiply by 8^p ``` Last and maybe least, the following version converts the maintissa rigth to left, then shifts the result left or right as required by repeatedly multiplying by 8 or 1/8. The thought is that repeated multiplication may be more accurate than raising 8 to some power. ```11 LocR 002 create two local registers 2 STO .01 store entered value 3 MANT extract mantissa of N 4 SDL 11 multiply by 1E11 5 RCL X duplicate value 6 #010 enter 10 7 RMDR extract units digit using RMDR (to work for neg) 8 STO-Y subtract from original to remove units digit 9 STO+ .00 add to current sum 10 #008 enter 8 11 STO/ .00 push sum one octal digit right 12 RCL Z Recall previous value less units 13 SDR 01 divide by 10 14 x=/=0? check if done 15 BACK 010 loop back until done 16 x<>Y swap 17 RCL .01 recall original entry 18 EXPT extract power of 10 19 x=/= 0? check if exponent is zero 20 SKIP 001 if not zero, skip to SIGN 21 INC X if zero, set equal to 1 22 SIGN get sign of exponent 23 y^X raise 8 to 1 or -1 power to get 8 or .125 multiplier 24 RCL .01 recall original entry 25 EXPT extract power of 10 26 INC X add 1 to exponent 27 ABS take absolute value for loop index 28 x=0? check if loop index equals zero 29 SKIP 005 if so, done, go to end 30 RCL Y recall 8 or .125 31 STOx .00 multiply by 8 or .125 to shift left or right 32 x<>Y swap 33 DEC X decrement index 34 BACK 006 go back for next shift 35 RCL .00 recall answer ``` edit 1 - changed MOD to RMDR in first program to make it work with negative inputs. edit 2 - added new version edit 3 - added final version Edited: 23 Oct 2013, 8:46 a.m. Jeff O. Posting Freak Posts: 875 Threads: 37 Joined: Jul 2005 10-17-2013, 01:47 PM Hi Gene, I don't have a 65 handy (or an emulator or simulator) so I cannot test directly. I figured it should be more-or-less directly translatable to a wp34s program, so I thought I'd try that. But first I tried to step through the listing to make sure I understand it. You seem to be collecting the answer in register 3, yet I find no step that initializes it to zero. Did I miss some trick to initialize, or is there supposed to be a STO 3 after the CLX in step 9? Gene Wright Posting Freak Posts: 1,545 Threads: 168 Joined: Jul 2005 10-17-2013, 02:31 PM doh! Correct! Jeff O. Posting Freak Posts: 875 Threads: 37 Joined: Jul 2005 10-17-2013, 03:25 PM In that case, it works great!* At least as implemented in this wp34s program that only collapses the HP-65 two-step instructions for things like LBL A and RCL 3 into single step equivalents, but does not take advantage of any other wp34s improvements: ```Step Command Comment 001 LBL A Label Declaration A 002 STO 01 store input value in register 1 003 1 enter 1… 004 0 enter… 0 for 10 005 STO 08 store 10 in register 8 006 CLX Clear x, disable stack lift 007 STO 03 reset register 3 008 LBL B Label Declaration B 009 RCL 01 Recall current value from register 1 010 1 enter 1… 011 0 enter… 0 for 10 012 X multiply by 10 013 ENTER duplicate value 014 INT take integer part 015 STO 04 store X value in register 4 016 - subtract frational part from N for next N 017 STO 01 store X value in register 1, next N 018 RCL 04 Recall register 4, current digit 019 1 enter 1… 020 1 enter… 1 for 11 021 RCL 08 Recall register 8 022 - subtract 023 8 enter 8 025 X<>Y swap 026 Y^X Y^X 027 / divide into current digit 028 RCL 03 register 3, current sum 029 + add 030 STO 03 store new sum back in register 3 031 DSZ 08 decrement index, use register 8 032 GTO B loop back… 033 RCL 03 when done, recall converted value 034 R/S stop ``` * - well, works great with some input limitations that don't quite meet the 0 <= n <= 1 range specified by the Master of the Challenge :-) « Next Oldest | Next Newest »

 Possibly Related Threads... Thread Author Replies Views Last Post [PRIME] RPN: another attempt at returning more than one value to the RPN stack Marcus von Cube, Germany 5 1,947 11-05-2013, 02:44 AM Last Post: Marcus von Cube, Germany HP Prime 2013 8 13. Rev:5106 bluesun08 2 1,049 09-28-2013, 11:05 AM Last Post: debrouxl HHC 2013 programming contest winners Brian Walsh 52 9,365 09-26-2013, 11:39 PM Last Post: David Hayden Box left at HHC Tim Wessman 1 1,317 09-26-2013, 11:05 PM Last Post: Wlodek Mier-Jedrzejowicz HHC 2013 speakers' files Joe Horn 2 1,304 09-26-2013, 02:51 AM Last Post: Geoff Quickfall HHC 2013 Day 2 Highlights Eddie W. Shore 6 2,005 09-23-2013, 04:03 PM Last Post: Kimberly Thompson HHC 2013: Day 1 Highlights Eddie W. Shore 28 6,230 09-23-2013, 03:22 PM Last Post: Brad Barton HHC / HP Museum Programming Contest for RPN and RPL machines Gene Wright 18 4,458 09-22-2013, 09:39 AM Last Post: Miguel Toro HHC 2013 room numbers David Hayden 2 1,035 09-20-2013, 05:34 PM Last Post: sjthomas Flash Flood Warning: 9/16/2013 (One Week from HHC13) Eddie W. Shore 8 2,327 09-17-2013, 09:20 PM Last Post: Craig Ruff

Forum Jump: