PDA

View Full Version : Fast Friday the 13th finder



GSAC3
04-02-2009, 03:00
Eros:

Since we have a "lucky" FRIDAY the 13th coming up soon, I thought someone may be interested in seeing how fast future Friday 13 dates could be determined using ThinBasic. I originally wrote an earlier version of the attached code for use with BCX and converted it for use with ThinBasic. It can, for example, find all of the Friday 13th dates between 1 Jan 2000 and 31 Dec 2999 in about 0.25 seconds on my laptop.

Enjoy -- Don

ErosOlmi
04-02-2009, 08:24
Great, pretty fast here too.

I would just change below piece of code in order to check input data (see "'---Better to check it" commented lines):


PRINTL ("FRIDAY THE 13TH. FINDER")
PRINTL ("-----------------------")
'
PRINT ("ENTER Starting MONTH (e.g. 1) ")
M = VAL(CONSOLE_READ())
if m = 0 then m = 1 '---Better to check it
MONTHbegin = M
PRINT ("ENTER Starting YEAR (e.g. 2000) ")
Y = VAL(CONSOLE_READ())
if Y = 0 then Y = 2000 '---Better to check it
YEARbegin = Y
'
PRINTL (" ")
'
PRINT ("ENTER Ending MONTH (e.g. 12) ")
MONTHend = VAL(CONSOLE_READ())
if MONTHend = 0 then MONTHend = 12 '---Better to check it
DAYend = MOS(MONTHend)
PRINT ("ENTER Ending YEAR (e.g. 2999) ")
YEARend = VAL(CONSOLE_READ())
if YEARend = 0 then YEARend = 2999 '---Better to check it


Thanks a lot for sharing the code.
Eros

ErosOlmi
04-02-2009, 09:03
I think I've found a little problem.

It seems returning the number of Friday 13 plus 1
For example during 2008 there is just one case but it returns 2. If you comment out line

PRINT (OUT_BUFFER)
you will see it.

Solution is to reset Counter variable before entering final loop:

...
' Find all subsequent Friday 13ths.

N = JD
count = 0 '---Reset the counter variable
DO
I=I+1
...

Ciao
Eros

Petr Schreiber
04-02-2009, 11:37
Hi,

very nice program.
For checking if value is inside proper interval, I recommend using outside function:


DO

PRINT ("ENTER Starting MONTH (e.g. 1) ")
M = VAL(CONSOLE_READ())

LOOP WHILE outside(m, 1, 12)


Maybe, to make it better, you can use general purpose "validating" function:


m = ValidatedInput("ENTER Starting MONTH (e.g. 1) ", 1, 12)

...

FUNCTION ValidatedInput( sRequest AS STRING, minValue AS NUMBER, maxValue AS NUMBER ) AS NUMBER

DIM tempVal AS NUMBER
tempVal = 0
DO

PRINT (sRequest)
tempVal = VAL(CONSOLE_READ())

LOOP WHILE outside(tempVal, 1, 12)

FUNCTION = tempVal

END FUNCTION

GSAC3
04-02-2009, 23:54
Eros and Petr:

Thanks for you'r feedback and suggestions.

I believe I have found the source of the problem relating to the "too many" dates for 2008. It was more than just zeroing the counter variable. It had more to do with the way I was using the Julian date to determine the week-day as affected by Leap centuries. I will post a revised version soon.

Don

GSAC3
05-02-2009, 00:49
OK, here is the revised version with (hopefully) the previous bugs corrected.

The attached ZIP contains five files:

F13TB.tBasic
BRUTEFORCE.tBasic
DIFF.EXE
Friday13.DAT
BRUTEFORCE.DAT

BRUTEFORCE is the Friday13th brute force iteration method.
The two DAT files are outputs in the range of 1 Jan 2000 through 31 Dec 2999.
The DIFF.EXE program facillitates comparing the two sets or results.

I haven't implemented Petr's changes yet bu plan to do so.

Don

GSAC3
05-02-2009, 01:57
F13TB.tBasic revised version with Petr Schreiber's very neat input checking function is attached.

BTW Petr, where in the tBasic documentation is the "NUMBER" type discussed? That was a new one for me.

Don

Petr Schreiber
05-02-2009, 10:22
Hi Don,

NUMBER is simply alias for EXT (EXTENDED).

That means 18 digits of precision, while covering huge area of values from 3.4x10^-4932 to 1.2x10^4932.
It is the most general purpose numeric variable type in ThinBasic, although it occupies most memory, calculations with this datatype are still very fast.

I used it as it can handle any floating point / integer value.

GSAC3
05-02-2009, 16:42
Petr--

Thanks for the info about NUMBER. I could not find anything about it in the user docs.

I was also wondering what the default type is for DIMed variables that are not specifically typed with the "AS" qualifier. In particular, I noticed that the following code will not work unless the variable COUNT is explicitly typed as a numeric variable:

DIM COUNT
INCR COUNT

Don

ErosOlmi
05-02-2009, 16:52
Hi Don,

I will try to fix that missing help info.
As Petr already stated, NUMBER is an alias of EXT data type. I introduced it at the beginning of the project thinking about kids and the possibility to be as much simple as possible for a young programmer just starting with a programming language. EXT data type if the largest numeric data type you can handle in thinBasic. It can contain all the other numeric data types. It has great precision and great number ranges. So it was simple.

Default data type for untyped variable is VARIANT. For this data type not all options are available. You cannot use INCR or prefix statements like +=, -=, ...
But this limitation can be a nice feature request ;)

Ciao
Eros

GSAC3
05-02-2009, 17:35
Eros--

Thanks for the info about default data type.

In the future, I will use explicit typing.

Don

GSAC3
05-02-2009, 18:51
Minor correction t0 F13TBp.tBasic to provide omitted default starting day value.

Don

Petr Schreiber
05-02-2009, 20:17
Thanks Don,

new version worked well here!
Little hint to save you typing - when you end DIM with ... AS something, it is like you would do it for each variable.

So instead of:


DIM JD As LONG, JDend As LONG, M As LONG, D As LONG, Y As LONG


you can write directly:


DIM JD, JDend, M, D, Y As LONG


... it will make all those variables LONG.


Thanks

GSAC3
05-02-2009, 21:06
Thanks Petr.

Don

GSAC3
18-02-2009, 22:45
Petr --

After tweaking the program algorithm a little bit, it is now more general and will find all occurrancs of ANY Month-Day / Week-Day pair, not just Friday the 13ths.

Don

Petr Schreiber
18-02-2009, 22:53
Hi Don,

thanks for new version, making it "universal" day finder was good idea :)


Petr