[Challenge] Friday the 13th

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

[Challenge] Friday the 13th

Post by AbraCadaver »

Calculate the number of Friday the 13th occurrences from the first day in 1900 through the end of 2010.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
liljester
Forum Contributor
Posts: 400
Joined: Tue May 20, 2003 4:49 pm

Re: [Challenge] Friday the 13th

Post by liljester »

Code: Select all

<?php

$fri13 = 0;
for($year = 1900; $year <= 2010; $year++) {
	for($month = 1; $month <= 12; $month++) {
		if(date('l', mktime(0, 0, 0, $month, 13, $year)) == "Friday") {
			//print date("F Y",  mktime(0, 0, 0, $month, 13, $year)) ." has a friday the 13th.\n";
			$fri13++;
		}
	}
}
print"there are {$fri13} friday 13ths between 01-01-1900 and 31-12-2010.\n";
?>
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: [Challenge] Friday the 13th

Post by AbraCadaver »

You're missing 4 8O
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
liljester
Forum Contributor
Posts: 400
Joined: Tue May 20, 2003 4:49 pm

Re: [Challenge] Friday the 13th

Post by liljester »

bah no fair! mktime() only goes back to 1902.
User avatar
liljester
Forum Contributor
Posts: 400
Joined: Tue May 20, 2003 4:49 pm

Re: [Challenge] Friday the 13th

Post by liljester »

Code: Select all

<?php
$fri13 = 0;

for($year = 1900; $year <= 2010; $year++) {
	for($month = 1; $month <= 12; $month++) {
		$date = date_create("{$year}-{$month}-13");
		if(date_format($date, "l") == "Friday") {
			//print date_format($date, "Y m") ." has a friday the 13th.\n";
			$fri13++;
		}
	}	
}
print"there are {$fri13} friday 13ths between 01-01-1900 and 31-12-2010.\n";
?>
fixed :)
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Friday the 13th

Post by VladSun »

Code: Select all

class Friday13Calculator
{

	private static $fridays13inLeapYearWithWeekOffsets = array
	(
		1	=> 2,
		2	=> 1,
		3	=> 2,
		4	=> 2,
		5	=> 1,
		6	=> 1,
		7	=> 3,
	);

	private static $fridays13inNonLeapYearWithWeekOffsets = array
	(
		1	=> 2,
		2	=> 2,
		3	=> 1,
		4	=> 3,
		5	=> 1,
		6	=> 1,
		7	=> 2,
	);


	public static function get($startYear, $endYear)
	{
		$numberOfFridays13 = 0;
		
		for ($year = $startYear; $year <= $endYear; $year++)
		{
			if (self::isLeapYear($year))
				$fridays13InYear = self::$fridays13inLeapYearWithWeekOffsets;
			else
				$fridays13InYear = self::$fridays13inNonLeapYearWithWeekOffsets;

			$numberOfFridays13 += $fridays13InYear[self::getWeekOffset($year)];
		}

		return $numberOfFridays13;
	}

	private static function isLeapYear($year)
	{
		if ($year % 4 != 0)
			return false;
		if ($year % 100 != 0)
			return true;
		if ($year % 400 != 0)
			return false;
		return true;
	}


	private static function getWeekOffset($year)
	{
		return date_format(date_create('01-01-'.$year), 'N');
	}

}

echo Friday13Calculator::get(1900, 2010);

:)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: [Challenge] Friday the 13th

Post by AbraCadaver »

Nice work guys! Here's what I came up with:

Code: Select all

for($i=0, $start=new DateTime('1900-01-13'), $end=new DateTime('2010-12-31'); $start<=$end; $start->modify('13 of next month')) {
	if($start->format('N') == 5) {
		$i++;
		//$dates[] = $start->format('Y-m-d');  //if you need the dates
	}
}
echo $i;
Last edited by AbraCadaver on Tue Jul 20, 2010 2:46 pm, edited 1 time in total.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Friday the 13th

Post by VladSun »

Nice one :)

I've tried to speed up the process. I think the date_* functions are computational expensive.

I've been thinking about how to calculate the next weekOffset without using date_* functions - I just wanted to use the previous calculated value. It should be simple :)
Last edited by VladSun on Tue Jul 20, 2010 2:49 pm, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Friday the 13th

Post by VladSun »

Hm, I'm getting a warning with your code:
Warning: DateTime::modify() [datetime.modify]: Failed to parse time string (13 of next month) at position 0 (1): Unexpected character ...
EDIT: PHP v5.3.2-1ubuntu4.2
Last edited by VladSun on Tue Jul 20, 2010 2:47 pm, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Friday the 13th

Post by VladSun »

Some speed benchmarks:
mine: 0.00524377822876 seconds
liljester: 0.0471768379211 seconds
AbraCadaver: Sorry, could not run it ...
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: [Challenge] Friday the 13th

Post by AbraCadaver »

VladSun wrote:Hm, I'm getting a warning with your code:
Warning: DateTime::modify() [datetime.modify]: Failed to parse time string (13 of next month) at position 0 (1): Unexpected character ...
EDIT: PHP v5.3.2-1ubuntu4.2
That's strange, runs great for me. Seems like they broke something between 5.2.4 and 5.3.2 :(

PHP 5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2 (cli)
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: [Challenge] Friday the 13th

Post by Weirdan »

Code: Select all

echo 190;
Benchmark please :D
Last edited by Weirdan on Tue Jul 20, 2010 3:50 pm, edited 1 time in total.
Reason: Oops, used the wrong script for precalculation :)
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: [Challenge] Friday the 13th

Post by AbraCadaver »

AbraCadaver wrote:You're missing 4 8O
Same for you Weirdan :D
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: [Challenge] Friday the 13th

Post by Weirdan »

AbraCadaver wrote:Same for you Weirdan :D
Sorry, can't reproduce, please provide proper bugreport :P
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: [Challenge] Friday the 13th

Post by VladSun »

2 and a half (Weirdan's code) people say it's 190 ... find your bug :P
There are 10 types of people in this world, those who understand binary and those who don't
Post Reply