Days between dates challenge for 11c and 34c « Next Oldest | Next Newest »

 ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-09-2009, 09:56 AM Katie Wasserman and I have been extolling the virtues of the HP-11c via emails recently, and we decided to implement the days between dates algorithm found in the "Formulas Used" Appendix of the HP-12c manual. Each of us developed an RPN program on the 11-c for this algorithm, and then we shared them so we could benefit from the other's ideas. Katie thought this would be a good challenge for this community, and I agree. So here are the rules. The goal is to develop an RPN program on either the HP-11c or HP-34c that conserves the scarce resources on these calculators as much as possible. To this end, these are the evaluation criteria to determine the "best" program. Like golf, the lowest score wins. Evaluation criteria: One point for each line of code. Seven points for each register used (not including the stack and lastx). Two points for each label used. You must implement the delta-DYS (actual day basis) algorithm in the Formulas Used Appendix of the HP-12c manual. Katie and I discovered that this algorithm, as listed, does not work correctly if the date range includes century years that are not divisible by 400, such as 1800, 1900, 2100, etc. (although the 12-c does work correctly for these years, so the actual implemented algorithm is different than the printed algorithm). Nevertheless, implement the algorithm as printed in the manual. Let's see who comes up with the lowest (best) score. I have to admit, Katie is a master at this and I will be surprized if anyone can top her effort. To the winner goes the honor of being identified as the winner in this thread! ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-09-2009, 11:50 AM FYI, here's the formula that's to be implemented, taken from the 12C appendix: ```Actual Day Basis delta-days = f(DT2) – f(DT1) where: f(DT) = 365 (yyyy) + 31 (mm – 1) + dd + INTG (z/4) – x and for mm <= 2 x = 0 z = (yyyy) – 1 for mm > 2 x = INTG (0.4mm + 2.3) z = (yyyy) INTG = Integer portion. ``` Edited: 9 Aug 2009, 11:53 a.m. ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 01:46 PM Just one question on the scoring - with these calcs, is one line of code always the same size irrespective of what that line of code is? Although I am a big fan of the 11C, I don't program it much if at all and coming from a UserRPL perspective, I am used to variable command sizes, often with surprising results. Mark ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 01:51 PM And another point just thinking this through - us Europeans are going to produce a different program I suspect to those Stateside due to the different date formats. You'll need to define the date format before people start coding on DD.MMYYYY. Mark ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-09-2009, 01:56 PM You're right. Let's use the US standard, mm.ddyyyy. It would be interesting, however, if dd.mmyyyy might result in more efficient code. :) Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-09-2009, 01:53 PM Mark, I'm pretty sure the answer is "yes." A line of code might be "4", or it might be ".", or it might be "x>y". I think they are all one byte long. ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 02:05 PM Thanks Don. I'm pretty certain it is 1:1 now myself having just reacquainted myself with the 11C program model. In fact, as soon as I did this, I realised what a daft question it was!! Will use US date format.... but as you say, doing it the European way would be interesting for comparison. Mark ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 02:12 PM And another question as this might make a difference. What is the stack order, DT1 in y, DT2 in x or the other way round? Also, are we assuming the program pointer is at 000 for running the program or do we need to define a starting label? Mark ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-09-2009, 02:55 PM DT1 and DT2 order in the stack, your choice, although Katie and I assumed that you would enter DT1 first, so it would be in Y. We also had LBL A as the first instruction, although you could omit that and assume you are at 00 when you R/S, I suppose, to gain 2 points on one fewer label. ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 04:00 PM Me again! Please can you post some official results so we can check our programs against them - ideally, these results should include an example where the algorithm fails as detailed above. Thanks :) Mark ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-09-2009, 05:03 PM Sure, Mark, here are a couple: ```8.141950 8.092009 --> 21545 (my age in days) 7.121960 12.042008 --> 17677 2.281900 3.011900 --> 2 using this algorithm (incorrect) --> 1 on a real 12c (correct, because 1900 is not a leap year) ``` ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 05:20 PM Thanks Don :) My first draft has weighed in with a hefty score of 103 (written on an 11C). Not sure I can reduce that by much unless I change the main algorithm. Mark hugh steers Senior Member Posts: 536 Threads: 56 Joined: Jul 2005 08-09-2009, 06:06 PM ```01 LBL A 02 GSB 02 03 X<>Y 04 GSB 02 05 - 06 RTN 07>LBL 02 08 1 09 + 10 STO 00 11 IP 12 STO 01 13 STO- 00 14 100 15 STO× 00 16 RCL 00 17 IP 18 STO 02 19 STO- 00 20 R^ 21 1E4 22 STO× 00 23 RCL 01 24 4 25 X<=Y? 26 GTO 01 27 R^ 28 12 29 STO+ 01 30 1 31 STO- 00 32 ENTER 33>LBL 01 34 R^ 35 RCL 01 36 30.6 37 × 38 IP 39 STO+ 02 40 Rv 41 RCL 00 42 365 43 × 44 RCL 00 45 4 46 ÷ 47 IP 48 + 49 RCL+ 02 50 RTN ``` notes: numbers wont be single lines as shown. Rv = roll down, R^ = roll up. havent tested on a real 11c. this was a free42 program. i just changed LBL A and GSB for the 11c. I cant remember whether the 11c has functions im using missing? :-) ▼ hugh steers Senior Member Posts: 536 Threads: 56 Joined: Jul 2005 08-09-2009, 06:19 PM ok, i tried it on my 15c. lines = 60 regs = 3 labels = 3 (including main one) = 60 + 21 + 6 87 also, tidied, register and label names to be more 11c ish. ```01 LBL A 02 GSB 2 03 X<>Y 04 GSB 2 05 - 06 RTN 07>LBL 2 08 1 09 + 10 STO 0 11 INT 12 STO 1 13 STO- 0 14 100 15 STO× 0 16 RCL 0 17 INT 18 STO 2 19 STO- 0 20 R^ 21 1E4 22 STO× 0 23 RCL 1 24 4 25 X<=Y? 26 GTO 1 27 R^ 28 12 29 STO+ 1 30 1 31 STO- 0 32 ENTER 33>LBL 1 34 R^ 35 RCL 1 36 30.6 37 × 38 INT 39 STO+ 2 40 Rv -- roll down 41 RCL 0 42 365 43 × 44 RCL 0 45 4 46 ÷ 47 INT 48 + 49 RCL+ 2 50 RTN ``` Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-09-2009, 06:30 PM I haven't test it either, on an 11c the score would be: 58 lines (expanding numbers as needed) + 3 x 2 points/label + 3 x 7 points/register = 85. This would be a good score, but it doens't implement the formula as presented. My best score so far is a bit less than this: 66 lines + 1 label (it's reused) + 2 registers = 82. You could save 4 points by label reuse too since all your branches are forward. Edited: 9 Aug 2009, 6:32 p.m. ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-09-2009, 07:08 PM Also, it uses recall arithmetic which the 11C doesn't have unfortunately. I think I can see a way of reducing mine a bit which might enable me to remove a register and save a few lines. Also, if I implement Katie's label trick, I can save one label - but I am not going to do that as I didn't know that trick existed so would be cheating! Mark ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-09-2009, 07:20 PM Right, the 11C and the 34c don't have RCL arithmetic. Aside form the integrate and solve functions I think that the 11c and 34c are 100% program code compatible and have the same memory size. Label reuse isn't a trick, it's suggested in the 11C manual! ▼ hugh steers Senior Member Posts: 536 Threads: 56 Joined: Jul 2005 08-09-2009, 07:41 PM Sure it implements the formula presented :-) i just rearranged some of the calculation to be an equivalent form. it should get the exact same answers. i didn't know about the rcl arithmetic. strange that's missing on the 11c really, when it's there on the 15. ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-09-2009, 08:45 PM Quote: Sure it implements the formula presented :-) i just rearranged some of the calculation to be an equivalent form. it should get the exact same answers. You sure confused me on this. Some program commentary might help convince me that these are the same algorithms. Anyway, the final RCL+2 is easily adjusted for the 11C and I end up 59 lines (I change 100 --> EEX 2 and 1EEX4 --> EEX 4), 3 registers and you can get away with 1 label I think (even though you used 3). So your score is potentially 81, wow! Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-09-2009, 08:48 PM Here's my entry. Assumes dates are in the format mm.ddyyyy with starting date in Y and ending date in X. GSB A will return the days between them per the 12c manual appendix function description. LBL A is used 3 times, this is fine as long as the program is not starting in the middle (like with a GTO .005) followed by a GSB A. Registers I and 0 are used and will and not be restored, no other register is touched. No flags are used and any output format is ok. score= 82 (66 lines, 2 registers, 1 label) ``` 001 LBL A -- expects Y=starting date (mm.ddyyyy), X=ending date (mm.ddyyyy) 002 0 003 STO 0 -- zero the days accumulator 004 Rv 005 GSB A -- get the negative number of days for the ending date in register 0 006 CHS -- flip the sign of register 0 007 STO 0 008 R^ -- get the starting date -- and process the same way -- the final RTN will end the program 009 LBL A -- reuse of 'A' expects X=mm.ddyyyy and subtracts the day count from register 0 (it also preserves Y in T) 010 STO I 011 INT 012 X<>I -- I now contains 'mm' 013 FRAC 014 EEX 015 2 016 x 017 INT 018 STO - 0 -- subtract 'dd' 019 Rv -- needed just to preserve the starting date 020 3 021 6 022 5 023 LASTx 024 FRAC 025 EEX 026 4 027 x 028 x 029 STO - 0 -- subtract 365 x 'yyyy' 030 Rv -- needed just to preserve the starting date 031 LASTx -- get back 'yyyy' 032 X<>I -- swap places with 'mm' 033 3 034 X > Y -- if 'mm'<=2 then 035 DSE -- 'yyyy' - 1 036 Rv -- get 'mm' back into I 037 X<>I get 'z' into X 038 4 039 / 040 INT 041 STO - 0 -- subtract INT(z/4) 042 Rv -- needed just to preserve the starting date 043 RCL I -- get 'mm' 044 1 045 - 046 3 047 1 048 x 049 STO - 0 subtract ('mm' - 1) * 31 050 Rv -- needed just to preserve the starting date 051 2 052 RCL I 053 X<=Y -- if 'mm'<=2 no need to add anything 054 GTO A -- this is a forward branch to the next 'LBL A' 055 . 056 4 057 x 058 2 059 . 060 3 061 + 062 INT 063 STO + 0 -- add INT('mm' x .4 + 2.3) 064 LBL A -- re-use of this label 065 RCL 0 066 RTN ``` ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-11-2009, 09:20 AM Can we keep this open a little longer please? I have a problem with my code - when you step-run it or do it manually, it appears to work OK but when you run it properly, it fails. There is a stack-lift problem in it somewhere which is proving to be a real bloody nuisance to track down. I remember getting caught like this with an HP32S program but I wasn't using all 4 stack levels in that one so an extra enter didn't cause a problem. I can't remember the exact code size because it is riddled with R/S commands at the moment but I think it was 66 or 67 with 1 label and 2 registers. I really want to get this fixed before we start discussing our solutions. Thanks, Mark ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-11-2009, 09:44 AM Stack problems are the worst, especially since there's variation among HP calculations models in the way they handle stack lift. A good rule of thumb to help avoid bumping stuff you need off the top of the stack is to use a roll-down before after storing a number before you start a new calculation that doens't immediately need the stored result. It's amazing what you can do with a 4-level stack with careful planning, but it's often a challenge to figure it out a a basic RPN machine -- the 41C and 42S make stack manipulation far too easy. Steve Perkins Member Posts: 104 Threads: 0 Joined: Dec 2007 08-11-2009, 01:20 PM I guess I do better at improving others marvelous efforts. I'm not so good at programming from scratch. I improved Katie's efforts just a little. The first trick was to just clear the registers instead of storing 0 to reg 0. Not what one usually does in a program since it destroys what you might really want saved, but it is two instructions shorter. Then I used division by 2.5 instead of multiplication by .4 so I could just test with 2.5 instead of 2. That saved just one step. Here's my small improvement. It wouldn't exist without Katie, so she gets the credit: ```001 LBL A -- expects Y=starting date (mm.ddyyyy), X=ending date (mm.ddyyyy) 002 CLEAR REG 003 GSB A -- get the negative number of days for the ending date in register 0 004 CHS -- flip the sign of register 0 005 STO 0 006 R^ -- get the starting date -- and process the same way -- the final RTN will end the program 007 LBL A -- reuse of 'A' expects X=mm.ddyyyy and subtracts the day count from register 0 (it also preserves Y in T) 008 STO I 009 INT 010 X<>I -- I now contains 'mm' 011 FRAC 012 EEX 013 2 014 x 015 INT 016 STO - 0 -- subtract 'dd' 017 Rv -- needed just to preserve the starting date 018 3 019 6 020 5 021 LASTx 022 FRAC 023 EEX 024 4 025 x 026 x 027 STO - 0 -- subtract 365 x 'yyyy' 028 Rv -- needed just to preserve the starting date 029 LASTx -- get back 'yyyy' 030 X<>I -- swap places with 'mm' 031 3 032 X > Y -- if 'mm'<=2 then 033 DSE -- 'yyyy' - 1 034 Rv -- get 'mm' back into I 035 X<>I get 'z' into X 036 4 037 / 038 INT 039 STO - 0 -- subtract INT(z/4) 040 Rv -- needed just to preserve the starting date 041 RCL I -- get 'mm' 042 1 043 - 044 3 045 1 046 x 047 STO - 0 subtract ('mm' - 1) * 31 048 X<>I -- get 'mm' while preserving starting date 049 2 -- constant for test, and also possible division later 050 . 051 5 052 X > Y -- if 'mm'<=2 don't need adjustment 053 GTO A -- this is a forward branch to the next 'LBL A' 054 / -- dividing by 2.5 is the same as multiplying by 0.4 055 2 056 . 057 3 058 + 059 INT 060 STO + 0 -- add INT('mm' x .4 + 2.3) 061 LBL A -- re-use of this label 062 RCL 0 063 RTN ``` ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-11-2009, 02:05 PM Hey Steve, I'll let Katie speak for herself, but I too thought of CLR REG to save one instruction, but I'm sure Katie's point is to not alter any registers other than the two she is using, and CLR REG certainly does that! ▼ Steve Perkins Member Posts: 104 Threads: 0 Joined: Dec 2007 08-11-2009, 02:58 PM I agree. It's not the prefered method at all for a real routine. One that might be used in other contexts and with a surrounding application. It saves two lines, but it could be argued that it "uses" all the registers and thus the point penalty is extreme. ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-11-2009, 03:14 PM Quote:It saves two lines Actually, one, right? 0 STO 0 vs. CLR REG ▼ Steve Perkins Member Posts: 104 Threads: 0 Joined: Dec 2007 08-11-2009, 05:58 PM That one line replaces ```002 0 003 STO 0 -- zero the days accumulator 004 Rv ``` But Katie interprets it as "using" 19 additional registers, so I withdraw it. My tricks now only save two lines in her wonderful code. It's sure great to have nice code to start with, right? ▼ Don Shepherd Posting Freak Posts: 1,392 Threads: 142 Joined: Jun 2007 08-11-2009, 06:12 PM Oh, I see what you are saying now, Steve. You're right. Re Katie, I agree. I'm not even in the same league! Steve Perkins Member Posts: 104 Threads: 0 Joined: Dec 2007 08-11-2009, 03:10 PM Actually, it seems that my line 40 can be deleted too. The starting date is still preserved in the top stack register where it's expected after the first call to the date numbering subroutine. With that refinement we have: score= 78 (62 lines, 2 registers, 1 label) ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-11-2009, 05:18 PM Steve, Refinements of my code are most welcome and appreciated. Combining clever ideas of many of the people here can result in some amazing code. Yes, I avoided Clear REG for the obvious reason that would count as using another 19 registers :( Your use of 2.5 / instead of .4 * is brilliant! I had concluded that I needed the Rv at line 40, but that may have been in a earlier version of my code and I left it in place unnecessarily. Thanks for the improvements! -Katie ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-12-2009, 06:57 AM Here is my version. I haven't looked at anyone elses' code so I don't know how it compares. This was a useful exercise for me and a lot of fun as I don't normally do any programming outside RPL. The 4 line stack and stack-lift problems caught me out a couple of times but here is the result: 64 lines, 1 label, 2 registers. ```x SWAP I Rdown GSB A x SWAP I GSB A RCL I - RTN LBL A INT LASTx FRAC EEX 2 * INT STO 0 LASTx FRAC EEX 4 * 3 6 5 x SWAP y * STO+ 0 LASTx Rup ENTER SF 0 1 - 3 1 * STO+ 0 x SWAP y 3 X>Y GTO A Rdown CF 0 . 4 * 2 . 3 + INT STO- 0 LBL A Rup F? 0 1 F? 0 - 4 / INT RCL 0 + ``` You will notice that I didn't include an opening label and I took advantage of the implied RTN at the last step. I consider both these omissions legit. It was agreed at the start that an opening label wasn't necessary and my program returns to 000 after each run so no manual re-pointing is necessary. Concerning the implied RTN, HP document this in the manuals so quite happy to use it! However, this might give me a 2 line advantage so I'll let the adjudicators decide on that one :) Written on 11C and thanks for the fun challenge! Mark PS: Living in a dd.mm.yyyy part of the world, working with mm.dd.yyyy is unbelievably confusing! It's like have to learn left is right!! Edited: 12 Aug 2009, 7:01 a.m. ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 08-12-2009, 11:18 AM Mark, Very nice code! The way you use I register and the 0 flag is a great idea, much more obvious than my convoluted program. Dropping the fist LBL and last RTN, well it's ok if nothing else is in memory, not so good if there's other code in there but Don's the contest judge.... -Katie ▼ Mark Edmonds Senior Member Posts: 283 Threads: 33 Joined: Jul 2008 08-12-2009, 03:46 PM Thanks for the feedback Katie :) To be perfectly honest, I don't think my code is especially elegant and would be a pain to maintain if a functional change is needed. In comparison, I thought your code was much easier to understand and works using the same resources, even less actually and as such, I consider it to be a neater solution. I liked the clever use of DSE and the way you run into the sub on the second pass so the sub's RTN acts as the end. I thought of doing that myself but it wasn't possible the way I set things up. Looking at your code made me realise another method of calculating the date difference by negating the actual DT1 value before passing to the sub. You wouldn't need to negate the return value and everything would be simple addition (but the month test would be more difficult). Mark

 Possibly Related Threads... Thread Author Replies Views Last Post HP50G early days vs Prime early days? Mike Powell 7 1,138 10-09-2013, 11:17 AM Last Post: Eric Rechlin HP-34C Draining battery quickly Bill Crowell 2 718 09-08-2013, 08:30 AM Last Post: aj04062 HP-34C Curiosity Matt Agajanian 7 1,320 08-23-2013, 06:02 PM Last Post: Stephan Matthys hp 17bii+ dates calculation... JoePaul 6 1,231 07-14-2013, 11:32 AM Last Post: Katie Wasserman Casio fx-CP400 emulator (90 days trial) Mic 2 997 05-16-2013, 01:07 PM Last Post: critor HP-34C Emulator BShoring 8 1,411 03-30-2013, 05:04 PM Last Post: BShoring Looking for PRNG for HP-34C Dave Boyd 3 786 09-22-2012, 07:10 PM Last Post: Mike T. Introduction and discontinuation dates for HP Calculators Harald 9 1,432 07-30-2012, 04:43 PM Last Post: Jake Schwartz HHC 2012 dates Palmer O. Hanson, Jr. 2 583 06-19-2012, 12:03 PM Last Post: Namir A longstanding HP-34C mystery Matt Agajanian 11 1,667 05-03-2012, 02:29 AM Last Post: Alexander Oestert

Forum Jump: