Of the conference attendees who submitted RPN (not RPL) entries to the programming contest, my entry for the WP 34s was the worst. I don't really have that much 34s experience, so I worked on it until about 4:30 AM Sunday morning. Had I known about SDL, SDR, and RTN+1, that would have shaved off quite a few steps. I avoided a few optimizations due to the contest rules favoring elegance over trickiness. Here's the writeup I gave Joe when I submitted the entry:
Code:
HHC 2014 Programming Contest Entry
Eric Smith
For WP 34S
The output format is YYYYMMDD.
All output is done by PSE 10 (approx 1.0 sec).
NOTE: contents of X register when program terminates is not
considered an output. It will by January 1 of the following
year, in YYYYMMDD format, regardless of whether it is prime.
Two flags are used to handle boundary conditions:
flag 01 clear when handling first month (DEC 31 of prev year, JAN 01 of specified year),
set for all subsequent months
flag 02 set when handling thirteenth month (DEC 31 of specified year, JAN 01 of next year)
No storage registers are used. Whether that is elegant or inelegant may be debatable.
A "SKIP 1" is used at one point after a test instruction. Normally I would consider a
SKIP instruction inelegant, since it is an impediment to program understanding and editing.
However, a "SKIP 1" after a test instruction effectively acts as an inversion of the test,
which in my opinion is elegant.
The constant 8800 is used. A line could be saved by coding it as "CONST #088, CONST #100, *",
but this seems inelegant. Using another factorization such as "CONST #176, CONST #050, *"
might be even worse since that further obfuscates the value.
In comments in the listing below, mm is month, mp is previous month
01 * LBL "A"
02 MODE Y.MD
03 CFALL ; init boundary condition flags
04 CONST #013 ; init month counter
05 x<>y
06 E ; 1 yyyy cnt
07 4 ; 1E4 yyyy cnt
08 * ; yyyy0000 cnt
09 INC .X ; yyyy0001 cnt
10 GTO 02
11 * LBL 01 ; yyyymm01 cnt ; main loop
12 SF 01 ; mark already handled JAN 01
13 FS? 02 ; already handled DEC 31?
14 RTN ; yes
15 * LBL 02
16 CONST #100 ; 100 yyyymm01 cnt ; advance to next month
17 + ; yyyymm01 cnt
18 DSZ .Y ; yyyymm01 cnt-1 ; reached 13th month?
19 GTO 03 ; no, go process
20 SF 02 ; ; flag final month
21 8 ; 8 yyyy1301 cnt-1 ; adjust from 13th month to first month of next year
22 8 ; 88 yyyy1301 cnt-1
23 0 ; 88 yyyy1301 cnt-1
24 0 ; 8800 yyyy1301 cnt-1
25 + ; yyyz0101 cnt-1
26 * LBL 03
27 PRIME? ; yyyymm01 cnt ; day 01 of month prime?
28 SKIP 1 ; yyyymm01 cnt ; yes - SKIP 1 after test reverses sense of test
29 GTO 01 ; yyyymm01 ; no, try next month
30 RCL X ; yyyymm01 yyyymm01 cnt ; save as potential second day of pair
; back up to last day of prev month
31 E ; 1 yyyymm01 yyyymm01 cnt
32 4 ; 1E4 yyyymm01 yyyymm01 cnt
33 / ; yyyy.mmdd yyyymm01 cnt
34 1 ; 1 yyyy.mmdd yyyymm01 cnt
35 CHS ; -1 yyyy.mmdd yyyymm01 cnt
36 DAYS+ ; yyyy.mpdd yyyymm01 cnt
37 E ; 1 yyyy.mpdd yyyymm01 cnt
38 4 ; 1E4 yyyy.mpdd yyyymm01 cnt
39 * ; yyyympdd yyyymm01 cnt
40 PRIME?
41 GTO 04 ; yes, found a pair
42 RDN ; yyyymm01 cnt ; no, get potential second day back
43 GTO 01 ; try next month
44 * LBL 04 ; first day of month and last day of prev month both prime
45 FS? 01 ; yyyympdd yyyymm01 cnt ; was first day Jan 1?
46 PSE 10 ; yyyympdd yyyymm01 cnt ; no, so display prev date
47 RDN ; yyyymm01 cnt
48 FC? 02 ; handling DEC 31?
49 PSE 10
50 GTO 01 ; try next month
When I finished that at 4:30 AM, I decided to have a go at an RPL version. I was convinced that I wouldn't even be in the running for RPL, and I was very tired and wanted to get some sleep before the start of the Sunday session, so I only spent half an hour on it, and didn't do even some obvious optimizations, such as replacing "3 ROLL" (which had earlier in the development been "4 ROLL") with ROT. With the benefit of hindsight, I should have stopped optimizing my 34s program around midnight and spend more time optimizing my RPL entry. My RPL entry as submitted was apparently the same length as David Hayden's winning entry as submitted. My writeup (done "by hand", so direct ASCII import to an RPL calculator will fail):
Code:
HHC 2014 Programming Contest Entry
Eric Smith
For HP 50g
The output format is YYYYMMDD. The output will be a list left on the stack.
306.5 #2586h
<< { } SWAP ; yyyy {}
1E4 *
1 + ; yyyy0001 {}
0 12 FOR i
100 + ; yyyymm01 {}
IF i 12 == THEN
8800 +
END
DUP ; yyyymm01 yyyymm01 {}
10000 / ; yyyy.mmdd
DUP IP 1e6 / ; .00yyyy yyyy.mmdd
SWAP FP 100 * ; mm.dd .00yyyy
+ ; mm.ddyyyy
-1 DATE+ ; mm.ddyyyy
100 * ; mmdd.yyyy
DUP IP ; mmdd mmdd.yyyy
SWAP FP ; .yyyy mmdd
1e8 * ; yyyy0000 mmdd
+ ; yyyymmdd
; yyyympdd yyyymm01 {}
IF DUP2 ISPRIME? SWAP ISPRIME? AND THEN
IF i 0 /= THEN
; yyyympdd yyyymm01 {}
3 ROLL ; {} yyyymmdd yyyymm01
SWAP + ; {} yyyymm01
SWAP ; yyyymm01 {}
ELSE
DROP ; yyyymm01 {}
END
IF i 12 /= THEN
DUP ; yyyymm01 yyyymm01 {}
3 ROLL ; {} yyyymm01 yyyymm01
SWAP + ; {} yyyymm01
SWAP ; yyyymm01 {}
END
ELSE
DROP
END
NEXT ; yyyymm01 {}
DROP ; {}
>>
The final DROP is not strictly necessary, since the contest rules didn't
say that we couldn't leave extra junk on the stack. For that matter, the
program would be slightly shorter if we just left the answers on the stack
indivdually, but if we didn't also include a count that would be rather
unfriendly.
Thanks to Joe for yet another interesting programming challenge!