Wednesday, April 6, 2011

Calculating future occurences of Friday the 13th

I'd like to be able to start with a year, and calculate occurrences of Friday the 13th. A brute force solution is easy and obvious. I have something slightly better, but I have no doubt that someone else can come up with an elegant algorithm for this.

Perhaps a little trickier, I'd be interested in giving the program a month, and have it find the next year in which that month has a Friday the 13th.

Feel free to use pseudo code, but I expect people will vote more for working code samples in you favorite language.

From stackoverflow
  • initialize startDate to 13th of the month given in the current year
    while (true) {
        if (startDate.dayOfWeek == Date.FRIDAY)
             break;
        else
             startDate.year ++;
    }
    return startDate.year;
    
  • http://javascript.internet.com/time-date/find-friday-the-13th%27s!.html

  • Since your brute force algorithm is apparently the intuitive day-by-day iteration option, perhaps you haven't considered the Doomsday Algorithm. It would allow you to simply check if that 13th is a Friday. As far as I know, it is the most efficient solution to the problem.

  • Any month that starts with a Sunday has a Friday on the thirteenth. There are only 14 combinations possible knowing what day the first of the year is on (with or without leap year, and sun-sat). You should just calculate it once and get it over with. You'd only check 14*12 possible months to start out with, well with in reason.

    resultant table element (from 2009, 2010):

    [Thursday,false] => Feb, March, Nov
    [Friday,false] => Aug
    

    to fill the table you have a generic month Jan(31),Feb(28).. and then iterate with a seed of each day of the week, noting months that start with sunday, and also with a leap year and without. Pretty straight forward, and once done, you can share it with us :)

    Adam Davis : This is the fastest table method, afaict. There are fourteen types of weekdays - 7 for non leap years, 7 for leap years, and 12 months. A 2D or 3D array provides a very quick answer once you know what day of the week Jan 1 falls on, and whether it's a leap year - both are easy to calculate.
  • One thing I noticed is that the first of the month falls on a Sunday during months with a Friday the 13th. You can probably leverage this to make it easier to calculate.

  • This is how I would do it:

    • Assume year is known and is an integer.

    • Loop from 1 to 12

      • Create date with loop index, year and 13 for the day

    If you want to start with a month and year (you have to assume some sort of year), your algorithm becomes

    • Assume year is known and an integer

    • Assume month is known and is an integer

    • Loop

      • Create date with index of loop as year, known month variable, and 13 for the day

      • Determine day of week as per established algorithms

      • If day of week calculate above is Friday, return date, else

      • Else increment year by 1

  • Here's some example PHP code that goes through a pretty straight forward loop of the dates in a range. I would modify this to check the 13th of each month for Fridayness, rather than checking every Friday for 13thness, as they do in the example.

    pezi_pink_squirrel : Checking the 13th of each month is certainly the better way to go.
    Bill the Lizard : Yeah, seemed about 4X more efficient to me. :)

0 comments:

Post a Comment