Post Reply 
HHC 2018 Programming Contests
10-06-2018, 12:48 PM
Post: #81
RE: HHC 2018 Programming Contests
(10-06-2018 11:42 AM)Gerson W. Barbosa Wrote:  This saves 47 bytes overall.

We can also use Werner's remark:
(10-01-2018 01:42 PM)Werner Wrote:  The period for 23x28 and 28x33 days is also halved to 322 and 462, respectively.

Code:
\<< RCLF RAD
  { 190 305 454 569 949 }
  { 91 371 553 }
  { 63 259 385 }
  5 ROLL DUP DATE DUP ROT ROT DDAYS
  { 322 462 759 } MOD
  { } 1 3
  FOR i SWAP DUP i GET
    6 ROLL SWAP - DUP 0 > *
    WHILE DUP HEAD NOT
    REPEAT TAIL
    END 1 GET ROT +
  NEXT SWAP DROP SORT HEAD DATE+ DUP ROT ROT DDAYS \PI *
  { 11.5 14 16.5 } / SIN 100 * 0 RND ROT STOF
\>>

Meanwhile I came up with something between your and 3298's solution:
Code:
«
  DATE DDAYS
  {
    { 63 259 385 }
    { 190 305 454 569 949 }
    { 91 371 553 }
  }
  OVER
  { 322 759 462 } MOD
  2
  « -
    WHILE DUP HEAD DUP 0 ≤
    REPEAT DROP TAIL
    END SWAP DROP
  » DOLIST
  SORT HEAD DATE OVER DATE+ ROT ROT +
  360 * { 23 28 33 } / SIN 100 * 0 RND
»

But I consider 3298's idea to calculate the difference, then the remainder, flatten the lists and only then sort the result more elegant. Only drawback is the use of:
Code:
1. +

Kind regards
Thomas
Find all posts by this user
Quote this message in a reply
10-06-2018, 03:15 PM (This post was last modified: 10-06-2018 03:17 PM by Eddie W. Shore.)
Post: #82
RE: HHC 2018 Programming Contests
(10-05-2018 09:32 PM)Joe Horn Wrote:  Here is Eddie Shore's winning PPL entry:

Code:
sub1(); // elegant background screen

EXPORT BIOXTR()
BEGIN
STARTAPP("Function");
Xmin:=−6*π;Xmax:=6*π;
Ymin:=−1.1;Ymax:=1.1;

sub1();
TEXTOUT("BIORYTHM",−2*π,0,5);
TEXTOUT("by Edward Shore",−2*π,−.5,5);
TEXTOUT("Find your fate.",−2*π,−2,5);
WAIT(1);

// enter birthdate
LOCAL b,b1,b2,b3;
INPUT({b1,b2,b3},
"When were you born?",
{"Month: ","Day: ","Year: "});
b:=b3+b1/100+b2/10000;

// calculation
LOCAL d,L0,L1,t,m,p;
d:=DDAYS(b,Date);
L0:={CEILING((d-5.75)/11.5),
CEILING((d-7)/14),
CEILING((d-8.25)/16.5)};
L1:={ROUND(11.5*L0(1)+5.75,0),
ROUND(14*L0(2)+7,0),
ROUND(16.5*L0(3)+8.25,0)};

// loop
WHILE L1(1)≠L1(2) AND L1(1)≠L1(3)
AND L1(2)≠L1(3) DO
m:=POS(L1,MIN(L1));
L0(m):=L0(m)+1;
L1:={ROUND(11.5*L0(1)+5.75,0),
ROUND(14*L0(2)+7,0),
ROUND(16.5*L0(3)+8.25,0)};
END;

// an elegant way to extract the date
IF L1(2)==L1(3) THEN
t:=L1(2);
ELSE
t:=L1(1);
END;
d:=DATEADD(b,t);

// results screen
LOCAL str1;
LOCAL L2:=
{{"Physical: ",23},
{"Emotional: ",28},
{"Intellectual: ",33}};
sub1();
TEXTOUT("Your next extreme day is on...",−5*π,1,5);
WAIT(0.5);
str1:=STRING(IP(FP(d)*100))+" / "
+STRING(FP(d*100)*100)+" / "
+STRING(IP(d));
TEXTOUT(str1,−5*π,.6,5);
FOR m FROM 1 TO 3 DO
str1:=L2(m,1)+
STRING(ROUND(100*SIN(2*π*t/L2(m,2)),0));
TEXTOUT(str1,−5*π,.6-.2*m,5);
END;
WAIT(0);
STARTVIEW(−1);
END;

// screen subroutine
sub1()
BEGIN
RECT(); 
LOCAL t;
HAngle:=0;
FOR t FROM −6*π TO 6*π STEP 12*π/720 DO
PIXON(t,SIN(2*π*t/23),#008000h);
PIXON(t,SIN(2*π*t/28),#FF0000h);
PIXON(t,SIN(2*π*t/33),#0000FFh);
END;
END;

When run, it shows this splash screen:

[Image: Shore1.png]

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:

[Image: Shore2.png]

It then outputs the next Extrema Date in elegant fashion:

[Image: Shore3.png]

Congrats to Eddie!

Good catch. I had the "Find Your Fate." on the input screen, and I forgot to change the help text when I changed the input from YYYY.DDMM to entering the year, day, and month separately.

The contest wanting elegance inspired me to do the splash screen and the more user friendly input/output.
Visit this user's website Find all posts by this user
Quote this message in a reply
10-06-2018, 03:57 PM
Post: #83
RE: HHC 2018 Programming Contests
(10-06-2018 12:48 PM)Thomas Klemm Wrote:  Meanwhile I came up with something between your and 3298's solution:
Code:
«
  DATE DDAYS
  {
    { 63 259 385 }
    { 190 305 454 569 949 }
    { 91 371 553 }
  }
  OVER
  { 322 759 462 } MOD
  2
  « -
    WHILE DUP HEAD DUP 0 ≤
    REPEAT DROP TAIL
    END SWAP DROP
  » DOLIST
  SORT HEAD DATE OVER DATE+ ROT ROT +
  360 * { 23 28 33 } / SIN 100 * 0 RND
»

I was getting wrong biorhythm results until I noticed my angle mode was set to RAD. Preserving the user’s settings and forcing DEG mode makes your program 367 bytes long, which is quite an improvement over mine. Well done!
Code:

« DATE DDAYS RCLF SWAP DEG { { 63. 259. 385. } 
{ 190. 305. 454. 569. 949. } { 91. 371. 553. } } OVER
 { 322. 759. 462. } MOD 2.
  « -
    WHILE DUP HEAD DUP 0. ≤
    REPEAT DROP TAIL
    END SWAP DROP
  » DOLIST SORT HEAD DATE OVER DATE+ ROT ROT +
 360. * { 23. 28. 33. } / SIN 100. * 0. RND ROT STOF
»

Gerson.
Find all posts by this user
Quote this message in a reply
10-06-2018, 04:21 PM
Post: #84
RE: HHC 2018 Programming Contests
(10-06-2018 12:48 PM)Thomas Klemm Wrote:  But I consider 3298's idea to calculate the difference, then the remainder, flatten the lists and only then sort the result more elegant.
Thank you very much.
(10-06-2018 12:48 PM)Thomas Klemm Wrote:  Only drawback is the use of:
Code:
1. +
If those shall go entirely, try replacing the inner program
Code:
\<< - SWAP MOD \>>
with this:
Code:
\<<
  - OVER MOD
  DUP 0. == ROT * +
\>>
... and remove both instances of 1. +.
I've taken inspiration from Gerson's program here, he thought of using comparisons for list processing first. This variant is 5 bytes longer though.

Another bit that could make all of our programs more elegant would be using units in the function values calculation to avoid that mode switching madness. (By the way, Thomas, your mashup program blindly assumes DEG mode and failed to return correct results on my calculator for that reason.) There are dedicated units for angles, and when SIN gets an input tagged with one of these, the unit overrides the current angle mode.
Unfortunately unit objects are pretty heavy, adding 13.5 bytes to the number they are attached to (that number is for single-symbol units like degrees and radians; longer units take even more). That's more than what we spend for the mode switching (12.5 bytes in my program).

Next discovery: exploding a sublist inside DOLIST (e.g. with an EVAL at the end of the program passed to DOLIST) causes all elements of the sublist to be added to the result list, no more flattening needed. That means, adding an EVAL at the end of the subprogram lets me remove the EVAL + + after the DOLIST. That's 5 bytes saved with no negative impact on elegance (if anything, it's more elegant afterwards).

And then there's a rare and kind of amusing bug. If my program (or the one by Thomas that's partially based on mine) runs during midnight, there's a chance the DATE calls happen on different sides of midnight and therefore return different values. That causes the calculated extrema date to be off by one. The function values remain correct though. I've corrected this in the revised "elegant" version below.

But before we come to that let's do something different, trying to get my program as short as possible. Of course that means doing exactly what I just criticized Thomas' program for, blindly assuming that the angle mode is radians (because that's what matches a freshly reset calculator, which the challenge demands programs to be compatible with). The midnight bug stays in. No pretty tagging either. Please enter in exact mode because some numbers are exact integers on purpose (those tend to be shorter when the reals aren't compiled to 2.5-byte pointers into ROM, but not everybody likes to use them because they are also slower). The list of weird numbers between 0 and 1 is precalculated like this: 2. \pi * { 23 28 33 } /
Code:
\<<
  DATE DDAYS
  { 322 759 462 }
  { { 62 258 } { 189 304 453 568 } { 90 370 } }
  PICK3 3. NDUPN \->LIST
  3. \<< - SWAP MOD EVAL \>> DOLIST
  SORT 1. GET
  1. + DATE OVER DATE+ UNROT +
  { .273181969878 .224399475257 .190399554763 } * SIN
  2. ALOG * 0. RND
\>>
238.5 bytes, #D5E7h.

And the revised "elegant" program (\^o is the official encoding for the degrees symbol, enter via the units menu or Alpha Rightshift-hold 6):
Code:
\<<
  DATE 1. DATE+ DUP UNROT DDAYS
  { 322 759 462 }
  { { 63 259 } { 190 305 454 569 } { 91 371 } }
  PICK3 3. NDUPN \->LIST
  3. \<< - SWAP MOD EVAL \>> DOLIST
  SORT HEAD
  ROT OVER DATE+
  "Next extrema date" \->TAG UNROT +
  { 23 28 33 } / 360_\^o * SIN
  100 * 0. RND
  { "P" "E" "I" } \->TAG
\>>
310.5 bytes, #EC5Dh.
Find all posts by this user
Quote this message in a reply
10-06-2018, 06:38 PM
Post: #85
RE: HHC 2018 Programming Contests
(10-06-2018 03:57 PM)Gerson W. Barbosa Wrote:  I was getting wrong biorhythm results until I noticed my angle mode was set to RAD.

Please excuse my sloppiness.

(10-06-2018 04:21 PM)3298 Wrote:  Next discovery: exploding a sublist inside DOLIST (e.g. with an EVAL at the end of the program passed to DOLIST) causes all elements of the sublist to be added to the result list, no more flattening needed.

That's something I didn't consider. Here's a program that uses it:
Code:
«
  DATE DDAYS
  {
    { 63 259 385 }
    { 190 305 454 569 949 }
    { 91 371 553 }
  }
  OVER
  { 322 759 462 } MOD 2
  « - EVAL
  » DOLIST 1
  «
    IF DUP 0 ≤
    THEN DROP
    END
  » DOLIST
  SORT HEAD
  DATE OVER DATE+ ROT ROT +
  360 * { 23 28 33 } / SIN 100 * 0 RND
»

Both your 1 + trick and Gerson's masking trick are nice but distract from the problem.
Maybe that's only me but it took me a while to figure out why you had to do that.
I tried to avoid this.

Quote:There are dedicated units for angles, and when SIN gets an input tagged with one of these, the unit overrides the current angle mode.

That's a nice solution I wasn't aware of. Of course we could also use Didier's 0 ACOS trick.

Quote:And then there's a rare and kind of amusing bug.

Though I was aware of the issue I didn't consider it a problem.
It's also present in my HP-41CX program.
Otherwise I would have needed to use a register to save the date.

Kind regards
Thomas
Find all posts by this user
Quote this message in a reply
10-07-2018, 01:46 PM
Post: #86
RE: HHC 2018 Programming Contests
Here's a cleaned up version of my previous post.
Code:
@ THIS IS NOT MY CONFERENCE ENTRY.
@ I came up with this one over the days since the conference.
@ It's similar to many others already posted.
@ P has maxima on days 6 and 17.
@ E has maxima on days 7 and 14. This is equivalent to
@ to a 14 day cycle with maxima on day 7.
@ I has maxima on days 8 and 25.

@ Using the Chinese remainder theorem and the ICHINREM command
@ on the 50g, the extrema days occur on these cycles:
@ { 91 371 } MOD 462
@ { 190 305 454 569 } MOD 759
@ { 63 259 } MOD 322


@ Enter birthdate
@ in the current calc format (MM.DDYYYY by default)
«
     DUP DATE DDAYS @ Get days since birthday
     DUP DUPDUP 3 \->LIST
     { 462 759 322 } MOD
     { [ 91 371 553 0 ]
       [ 190 305 454 569 949 0 ]
       [ 63 259 385 0 ] }
     SWAP
     2
     @ Level 2: an array in sorted order (except last value)
     @ Level 1: a number less than largest value in array
     @ This returns the smallest value in the L2 array
     @ that is larger than the L1 value.
     « \-> X
       « 1 DO GETI UNTIL X > END
         1 - GET X -
       »
     »
     DOLIST
     « MIN » STREAM
     +

   @ Stack is birthday days_to_extreme
   DUP UNROT DATE+ "EXTREMA" \->TAG
   SWAP
   { 23 28 33} /        @ Convert days to cycles
   2. * 3.14159265359 * @ Cycles to radians
   SIN 100. * 0. RND    @ Radians to biorhythm value
   { "PHYS" "EMOTION" "INTELLECT" } \->TAG
   OBJ\-> DROP
»
Find all posts by this user
Quote this message in a reply
10-09-2018, 04:48 AM
Post: #87
RE: HHC 2018 Programming Contests
(10-07-2018 01:46 PM)David Hayden Wrote:  
Code:
« MIN » STREAM

Stealing this idea I managed to combine filtering and sorting into a single reducing:
Code:
«
  DATE DDAYS
  {
    { 63 259 385 }
    { 190 305 454 569 949 }
    { 91 371 553 }
  }
  OVER
  { 322 759 462 } MOD 2
  « - EVAL
  » DOLIST
  «
    IF DUP2 MIN 0 ≤
    THEN MAX
    ELSE MIN
    END
  » STREAM
  DATE OVER DATE+ ROT ROT +
  360 * { 23 28 33 } / SIN 100 * 0 RND
»

Cheers
Thomas
Find all posts by this user
Quote this message in a reply
06-25-2019, 01:27 AM (This post was last modified: 06-25-2019 01:29 AM by Craig Bladow.)
Post: #88
RE: HHC 2018 Programming Contests
(10-05-2018 12:00 AM)Joe Horn Wrote:  Craig Bladow's RPN contest entry can be downloaded from HERE.

My observations about Craig's entry:
  • Program name: "ELEGANT". Clever. Wink
  • Built-in instructions. Very nice!
  • Uses MOD algorithm (earns two "elegance" points).
  • Nicely formatted outputs.
  • Unfortunately gets wrong answers. Input 8/19/1955, outputs 12/07/2018, should be 10/22/2018.

Thank you for judging this, Joe! I've had a chance to review my solution and it does get right answers, just not all of them! Wink I misinterpreted the contest description and implemented a solution that only reports days with one +100 and one -100 extrema. 10/22/2018 has two +100 extrema so it wasn't reported by my program.

The following is a corrected program:
Code:

LBL "ELEGANT"
"BY CRAIG BLADOW"
"XEQ ELEGANT OR"
"PRESS A IN USER"
"MODE, ENTER"
"BDAY PRESS R/S"
"BEEP, DISPLAYS"
"WHEN EXT FOUND"
"PRESS R/S FOR"
"EACH BRTHYM"
"R/S FOR NEXT"
"EXTREMA DAY"
"CHECKS EACH DAY"
"FOR +/- EXT"
"USES NO TRIG"
"CHECKS DAY MOD"
"PERIOD EQUAL"
"6,7,8 FOR +EXT"
"17,21,25 FOR"
"-EXT"
LBL A
"BDY?:MM.DDYYYY"
PROMPT
STO 11
DATE
DDAYS
STO 10
23
STO 00
28
STO 01
33
STO 02
LBL 00
0  
STO 12
1
STO+ 10
.002
STO 09
LBL 01
RCL 10
RCL IND 09
MOD
RCL 09
INT
6
+
X=Y?  
XEQ 06
ISG 09
GTO 01
LBL 02
.002
STO 09
LBL 03
RCL 10
RCL IND 09
MOD
RCL 09
INT
4
*
17
+
X=Y?
XEQ 06
GTO 04
ISG 09
GTO 03
2
RCL 12
X<Y?
GTO 00
LBL 04
RCL 11
RCL 10
DATE+
FIX 06
CLA
ADATE
AVIEW
BEEP
STOP
FIX 00
CF 29
"PHYSICAL: "
23
XEQ 05
ARCL ST X
AVIEW
STOP
"EMOTIONAL: "
28
XEQ 05
ARCL ST X
AVIEW
STOP
"INTELLECTUAL: "
33
XEQ 05
ARCL ST X
AVIEW
SF 29
STOP
GTO 00
LBL 05
RCL 10
X<>Y
÷
360
*
SIN
100
*
RND
RTN
LBL 06
1
ST+ 12
RTN
END

Try CC41!
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 2 Guest(s)