My attempt.
Independent of the date settings, and will run on a 48G or newer.
Maybe the elegance and efficiency will make the judges gasp in awe. One can always hope ;-)
Code:
\<<
\-> Y
\<<
@ list of cases to test.
@ first object is the month number:
@ -last test case is month 1 of the next year, and if you construct yyyymm01 as (y*100 + m)*100 +1 then m=101 will do the trick
@ -the first case reverses the dates so that the correct date will be dropped in case of PDP
@ here, y*1e4 + m*100 + 1 = (y-1)*1e4 + 1231, and the m works out to be -87.7 ;-)
@ second is the difference between the first day of the month and the last of the previous month
@ third ob is the nr of objects to drop in case of a PDP (1 for the first and last case)
{ {-87.7 -8870 1} {2 70 0} }
IF Y LEAP? THEN { { 3 72 0 } } + END
{ {4 70 0} {6 70 0} {8 70 0} {9 70 0} {11 70 0} {101 8870 1} } +
1
\<<
EVAL \-> m d n
\<<
@ construct yyyymm01
Y 100 * m + 100 * 1 +
IF DUP ISPRIME? THEN
@ substract d to get the day before
DUP d - SWAP
OVER ISPRIME? n 2 IFTE DROPN
ELSE DROP
END
\>>
\>>
DOLIST
\>>
\>>
@ without the local environment..
\<<
\-> Y
\<<
{ {1 -8870 -87.7 } {0 70 2} }
IF Y LEAP? THEN { { 0 72 3 } } + END
{ {0 70 4} {0 70 6} {0 70 8} {0 70 9} {0 70 11} {1 8870 101} } +
1
\<< EVAL
@ construct yyyymm01
Y 100 * + 100 * 1 +
IF DUP ISPRIME? THEN
@ get the day before
DUP ROT - SWAP
OVER ISPRIME? 4 ROLL 2 IFTE
ELSE 3
END
DROPN
\>>
DOLIST
\>>
\>>
ISPRIME?
@ Courtesy of John H. Meyers
\<<
{ DUP2 MOD NOT { DUP2 > { DROP2 -1 2 } IFT } IFT }
\-> p
\<< 1 MAX 2 p EVAL 1 + p EVAL 2 + p EVAL 2 +
WHILE DUP2 SQ \>= REPEAT
p EVAL 4 + p EVAL 2 + p EVAL 4 + p EVAL
2 + p EVAL 4 + p EVAL 6 + p EVAL 2 + p EVAL 6 +
END DROP 1 >
\>>
\>>
LEAP?
@ Courtesy of Christian Meland
\<< 4 2 ALOG DUP2 * 3 ->LIST MOD EVAL XOR SAME \>>
Cheers, Werner