The Museum of HP Calculators

HP Forum Archive 19

[ Return to Index | Top of Index ]

Another days between dates challenge for 11c
Message #1 Posted by Don Shepherd on 14 Aug 2009, 10:29 p.m.

In this challenge, you are to develop an RPN program for the HP-11c that correctly calculates days between two dates. It must handle dates from Oct. 15, 1582 to Nov. 25, 4046 (same as the 12c). The evaluation criteria are the same as in an earlier thread on this subject: score = number of lines + 7*number of registers used (not including lastx or stack) + 2*number of labels used. The lowest score wins. The evaluation criteria are designed to reward those whose programs make the most economical use of scarce resources on the 11c.

Each entrant should calculate their score and post it with their code.

      
Re: Another days between dates challenge for 11c
Message #2 Posted by Katie Wasserman on 15 Aug 2009, 2:25 a.m.,
in response to message #1 by Don Shepherd

Here's an accurate days-between-dates 11C implementation based on this algorithm

01 LBL A
02  0
03 STO 0
04 Rv
05 GSB A
06 CHS
07 STO 0
08 R^
09 LBL A
10 STO I
11 INT
12  9
13 +
14  1
15  2
16  1/x
17 X<>Y
18  x
19 LASTx
20 X<>Y
21 INT
22  1
23  2
24 x
25 -
26 X<>I
27 FRAC
28 EEX
29  2
30 x
31 INT
32 STO - 0
33 Rv
34 LASTx
35 FRAC
36 EEX
37  4
38 x
39 RCL I
40  1
41  0
42 /
43 INT
44 -
45 X<>I
46  3
47  0
48  6
49  x
50  5
51  +
52  1
53  0
54  /
55 INT
56 STO - 0
57 Rv
58 RCL I
59  3
60  6
61  5
62 x
63 STO - 0
64 Rv
65 RCL I
66 4
67 /
68 INT
69 STO - 0
70 Rv
71 RCL I
72 EEX
73  2
74 /
75 INT
76 STO + 0
77 Rv
78 RCL I
79  4
80  0
81  0
82 /
83 INT
84 STO - 0
85 1
86 STO + 0
87 RCL 0
88 RTN

score: 88 lines, 2 registers, 1 label = 103

Edited: 15 Aug 2009, 2:28 a.m.

            
Re: Another days between dates challenge for 11c
Message #3 Posted by Gerson W. Barbosa on 16 Aug 2009, 1:38 p.m.,
in response to message #2 by Katie Wasserman

The following is based on the method used in the TI-59 Master Library Module (page 76). Day of the Week has also been included. The program is far from optimized: 91 + 3*7 + 3*2 = 116.

001-	LBL A			035-	*			069-	RCL 1
002-	GSB 0			036-	STO+ 0			070-	EEX
003-	x<>y			037-	Rv			071-	2
004-	GSB 0			038-	ENTER			072-	/
005-	-			039-	ENTER			073-	INT
006-	RTN			040-	.			074-	1
007-	LBL 0			041-	4			075-	+
008-	0			042-	*			076-	.
009-	STO 0			043-	2			077-	7
010-	Rv			044-	.			078-	5
011-	EEX			045-	3			079-	*
012-	2			046-	+			080-	INT
013-	*			047-	INT			081-	STO- 0
014-	ENTER			048-	STO 2			082-	RCL 1
015-	FRAC			049-	Rv			083-	4
016-	EEX			050-	1			084-	/
017-	4			051-	-			085-	INT
018-	*			052-	3			086-	STO+ 0
019-	STO 1			053-	1			087-	RCL 2
020-	3			054-	x<>y			088-	STO- 0
021-	6			055-	*			089-	R^
022-	5			056-	STO+ 0			090-	RCL 0
023-	*			057-	Rv			091-	RTN
024-	STO+ 0			058-	1			092-	LBL B
025-	Rv			059-	LSTx			093-	GSB 0
026-	INT			060-	x>y			094-	ENTER
027-	EEX			061-	GTO 1			095-	CHS
028-	2			062-	x<>y			096-	7
029-	/			063-	STO- 1			097-	/
030-	INT			064-	CLx			098-	INT
031-	LSTx			065-	STO 2			099-	7
032-	FRAC			066-	LBL 1			100-	*
033-	EEX			067-	Rv			101-	+
034-	2			068-	Rv			102-	RTN

Date format is MM.DDYYYY

GSB A: works just like DeltaDYS on the 12C.

GSB B: similar to DATE on the 12C, but requires only one argument, the date, and returns 0=Sat, 1=Sun, ... 6=Fri.

 
Equivalent TurboBCD program:

Program DaysBetweenDates;

var days, dt1, dt2: real;

function f(dt: real): real;

var d, m, y, t, x: real;

begin y:=1e4*(Frac(100*dt)); m:=Int(dt); d:=Int(100*(Frac(dt))); x:=Int(0.4*m+2.3); t:=365*y+d+31*(m-1); if (m-1)<=1 then begin y:=y-1; x:=0 end; f:=t+Int(y/4)-Int(0.75*(Int(y/100)+1))-x end;

begin ReadLn(dt1,dt2); days:=f(dt2)-f(dt1); WriteLn(days:7:0) end.

>

Running 6.011960 10.311976 5996

>

Running 2.281900 3.011900 1

>

Edited to correct a typo in line 060

Edited: 16 Aug 2009, 7:19 p.m.

                  
Re: Another days between dates challenge for 11c
Message #4 Posted by Don Shepherd on 16 Aug 2009, 8:28 p.m.,
in response to message #3 by Gerson W. Barbosa

Hi Gerson.

Don't you mean: 102+3*7+4*2=131?

                        
Re: Another days between dates challenge for 11c
Message #5 Posted by Palmer O. Hanson,, Jr. on 16 Aug 2009, 9:30 p.m.,
in response to message #4 by Don Shepherd

Don:

Quote:
Don't you mean: 102+3*7+4*2=131?
He is not counting the LBL B and the last eleven steps as those are for the day of the week calculation and are not needed for days between dates

Recent correspondencc from Richard Nelson tells me that at one time there was a set of biorhythm programs for the SR-56. That should have some routines for a machine with a limited repertoire similar to that of the HP-11. So far I haven't got my hands on the programs. I'm working on it.

Palmer

                              
Re: Another days between dates challenge for 11c
Message #6 Posted by Don Shepherd on 16 Aug 2009, 10:06 p.m.,
in response to message #5 by Palmer O. Hanson,, Jr.

Oh, OK thanks Palmer. Don

                        
Re: Another days between dates challenge for 11c
Message #7 Posted by Gerson W. Barbosa on 16 Aug 2009, 11:02 p.m.,
in response to message #4 by Don Shepherd

Hello Don,

I should have mentioned the last few steps didn't have anything to do with your requirement. Sorry! (Thanks Palmer for taking the time to explain it). As I said, my implementation is far from optimized, so there's plenty of room for improvent.

This topic was discussed here some years ago. Thanks for bringing it back:

http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv015.cgi?read=78807

Regards,

Gerson.

Edited: 16 Aug 2009, 11:03 p.m.

                              
Re: Another days between dates challenge for 11c
Message #8 Posted by Don Shepherd on 17 Aug 2009, 12:33 a.m.,
in response to message #7 by Gerson W. Barbosa

Thanks for that link, Gerson. It is absolutely fascinating. Reading that thread, I see some names we haven't seen here very much recently, like Valentin Albillo and James Prange. You can always count on Valentin to defend the 15c (and the 71, as I recall), as he did in that thread. If V or James Prange are still lurking out there, I for one would welcome their regular return to this forum. We would all gain from their participation.

            
Re: Another days between dates challenge for 11c
Message #9 Posted by Bart (UK) on 17 Aug 2009, 8:26 a.m.,
in response to message #2 by Katie Wasserman

Hi Katie,

That formula does look more "compact" than the JD formula I based my routines on. I cannot better the code, but I have a suggestion for optimising the maths.

As (365*y) is an integer, then I assume (365*y) + INT(y/4) = INT(365*y + y/4) = INT(365.25*y)

This would save 2 steps in your program.

Perhaps maths gurus could comment on the validity of my assumption?

Bart

                  
Re: Another days between dates challenge for 11c
Message #10 Posted by htom trites jr on 18 Aug 2009, 2:20 a.m.,
in response to message #9 by Bart (UK)

In this particular case, on this platform, I think you could get away with it, but in the general case (even an emulated hp-11) you should not (and should expect to have a horrible bug to catch!)

                        
Re: Another days between dates challenge for 11c
Message #11 Posted by Bart (UK) on 18 Aug 2009, 7:08 a.m.,
in response to message #10 by htom trites jr

My reasoning is as follows:

The first term we know is an integer say INT1, the second term is INT2.FRAC1, the integer of which is INT2, thus the sum is INT1+INT2.

If we did not take the integer of the second term before summation, the sum will be [INT1+INT2].FRAC1, if we then take the integer part it is INT1+INT2, as before.

Some rules apply
1) One term must be an integer to start with
2) Both must be of the same sign

As far as I see, both these rules are adhered to within the scope of the implementation of this formula.

                              
Re: Another days between dates challenge for 11c
Message #12 Posted by htom trites jr on 18 Aug 2009, 9:35 a.m.,
in response to message #11 by Bart (UK)

The problem is in the nature of the actual implementation of floating point arithmetic. Values that are the results of the division of an integer by a power of 2 are "special", in that they can sometimes have exact representations in both decimal floating point and binary floating point. In general, this is not true; in this particular case it works. Change the divisor to, say, 53, and things won't be so neat.

                                    
Re: Another days between dates challenge for 11c
Message #13 Posted by Bart (UK) on 18 Aug 2009, 10:25 a.m.,
in response to message #12 by htom trites jr

Hmmm, so what you're saying is that it all looks good in the physical world but when going to & from 1's & 0's things get hairy.

                                          
Re: Another days between dates challenge for 11c
Message #14 Posted by htom trites jr on 18 Aug 2009, 1:26 p.m.,
in response to message #13 by Bart (UK)

Hairy? Oh my, yes. The entire Broadway musical (cast, orchestra, and crew) comes along, singing and dancing through your results, leaving you scratching your head and saying "What the F..."? If you're lucky you see it happen and eventually figure it out, if you don't, you swear at both the hardware and the gods to no effect.

Please read (it will take a while, sorry) What Every Computer Scientist Should Know About Floating Point and Users need to know too. (Handy .PDF version that has maybe a little too much white space; double side it when printing.)

                              
Re: Another days between dates challenge for 11c
Message #15 Posted by Steve Perkins on 18 Aug 2009, 4:16 p.m.,
in response to message #11 by Bart (UK)

Edit: This program has been shown to be incorrect. Don't try this at home.

Here's my modifications of Katie's example:

01 LBL A
02  0
03 STO 0
04 Rv
05 GSB A
06 CHS
07 STO 0
08 R^
09 LBL A
10 STO I
11 INT
12  9
13 +
14  1
15  2
16 /
17 FRAC
18  1
19  2
20  .
21  1
22 x
23 INT
24 X<>I
25 FRAC
26 EEX
27  2
28 x
29 INT
30 STO - 0
31 Rv
32 LASTx
33 FRAC
34 EEX
35  4
36 x
37 RCL I
38  1
39  0
40 /
41 INT
42 -
43 X<>I
44  3
45  0
46  6
47  x
48  5
49  +
50  1
51  0
52  /
53 INT
54 STO - 0
55 Rv
56 RCL I
57  3
58  6
59  5
60  .
61  2
62  4
63  2
64  5
65 x
66 INT
67 STO - 0
68 1
69 STO + 0
70 RCL 0
71 RTN

Score 71 lines, 2 regs, 1 label = 87

Edited: 19 Aug 2009, 4:20 p.m.

                  
Re: Another days between dates challenge for 11c
Message #16 Posted by Steve Perkins on 18 Aug 2009, 3:21 p.m.,
in response to message #9 by Bart (UK)

An excellent observation!

If I'm not mistaken, it should save 3 lines.

And it should work on a real 11C because of the BCD math, and a simulated 11C because .25 is an inverse power of 2 as pointed out below.

It makes me wonder if we could include the other year terms in the constant on a real (or correctly emulated) HP-11C?

INT (y * 365.2425)

Certainly worth a try, right?

Edited: 18 Aug 2009, 3:34 p.m.

                        
Re: Another days between dates challenge for 11c
Message #17 Posted by htom trites jr on 18 Aug 2009, 5:56 p.m.,
in response to message #16 by Steve Perkins

i := -4004
while oldmethod(i) = newmethod(i) do i := i+1 endwhile;
display ("error at", i)
                              
Re: Another days between dates challenge for 11c
Message #18 Posted by Steve Perkins on 18 Aug 2009, 6:26 p.m.,
in response to message #17 by htom trites jr

Yes, upon reflection (and testing) my idea was silly.

It doesn't work in many cases.

But the original y * 365.25 is good.

                                    
Re: Another days between dates challenge for 11c
Message #19 Posted by Bart (UK) on 19 Aug 2009, 6:22 a.m.,
in response to message #18 by Steve Perkins

Quote:
Yes, upon reflection (and testing) my idea was silly.


It implicitly breaks my rule #1 :-)
edit: and #2 as the y/100 is opposite in sign

Edited: 19 Aug 2009, 6:36 a.m.

                              
Re: Another days between dates challenge for 11c
Message #20 Posted by Steve Perkins on 18 Aug 2009, 6:42 p.m.,
in response to message #17 by htom trites jr

Here's my corrected version. I have more confidence in this one.

I don't need to recall the year to divide by 400, I use the year divided by 100 already there and just divide that by 4!

I also shortened the (m*306 + 5)/10 part by 1 line.

I tested these improvements to be the same. If someone finds a counterexample, I'd like to know.

Score 79 lines, 2 regs, 1 label = 95

01 LBL A
02  0
03 STO 0
04 Rv
05 GSB A
06 CHS
07 STO 0
08 R^
09 LBL A
10 STO I
11 INT
12  9
13 +
14  1
15  2
16 /
17 FRAC
18  1
19  2
20  .
21  1
22 x
23 INT
24 X<>I
25 FRAC
26 EEX
27  2
28 x
29 INT
30 STO - 0
31 Rv
32 LASTx
33 FRAC
34 EEX
35  4
36 x
37 RCL I
38  1
39  0
40 /
41 INT
42 -
43 X<>I
44  3
45  0
46  .
47  6
48  x
49  .
50  5
51  +
52 INT
53 STO - 0
54 Rv
55 RCL I
56  3
57  6
58  5
59  .
60  2
61  5
62  x
63 INT
64 STO - 0
65 Rv
66 RCL I
67 EEX
68  2
69 /
70 INT
71 STO + 0
72  4
73  /
74 INT
75 STO - 0
76 1
77 STO + 0
78 RCL 0
79 RTN

Edited: 18 Aug 2009, 6:50 p.m.

                                    
Re: Another days between dates challenge for 11c
Message #21 Posted by Bart (UK) on 19 Aug 2009, 6:33 a.m.,
in response to message #20 by Steve Perkins

Quote:
I don't need to recall the year to divide by 400, I use the year divided by 100 already there and just divide that by 4!

I also shortened the (m*306 + 5)/10 part by 1 line.




Now why didn't I think of that!!

One caution though, you seem to be taking INT[INT[y/100]/4], rather than INT[[y/100]/4], which may lead to errors in some cases.

Bart
                                          
Re: Another days between dates challenge for 11c
Message #22 Posted by Steve Perkins on 19 Aug 2009, 11:14 a.m.,
in response to message #21 by Bart (UK)

You are right, I am taking INT[INT[y/100]/4] intentionally. In my tests it was the same, and saved a step.

Let me know if you still think it's different, especially if you can show an example.

I wrote a 'C' program to check all year values and I think I'm OK.

A purist would have used a calculator program, but I was lazy I guess.

                                                
Re: Another days between dates challenge for 11c
Message #23 Posted by Bart (UK) on 19 Aug 2009, 4:28 p.m.,
in response to message #22 by Steve Perkins

As it is we are interested in removing the leap days of whole centuries but counting every fouth one of those.

So your formula should indeed work fine.


[ Return to Index | Top of Index ]

Go back to the main exhibit hall