项目欧拉#19代码似乎是正确的。我错过了什么?

时间:2012-11-06 05:45:16

标签: php

问题19:

  

您将获得以下信息,但您可能更愿意这样做   为自己研究。

     

1900年1月1日是星期一。

     

三十天有九月,四月,六月和   十一月。

     

所有其他人都有三十一人,仅救二月,其中   二十八岁,风雨无阻。在闰年,二十九岁。

     

闰年发生在任何一年,可以被4整除,但不能在a上整除   世纪,除非它被400整除。

     

二十世纪的第一个月(1901年1月1日至2000年12月31日)有多少个星期日下降?

我认为使用PHP可以轻而易举,因为它有很多内置的时间和日期功能。我的代码非常简单,所以我很难看到我在做什么,这是错的。

我的代码:

<?php
    echo "<pre>";
    $sunday_count = 0;
    for( $year = 1901; $year <= 2000; $year++ ) {
        for( $month = 1; $month <= 12; $month++ ) {
            // Produces a date in format: 1/1/2000
            $date = $month . "/1/" . $year;
            $time = strtotime( $date );
            $is_sunday = ( date( 'l', $time ) == "Sunday" );
            echo "$date "
               . ( $is_sunday ? 'was a Sunday. ' : '' )
               . "<br>";
            if( $is_sunday ) $sunday_count++;
        }
    }
    echo "Answer: $sunday_count";
    echo "</pre>";
?>

我的代码提出的解决方案是169,这是不正确的。有什么想法吗?

修改1

解决方案应该是171。

使用Wolfram Alpha和我的Windows时钟,我加倍检查了我的代码报告的几个星期日。所有这些都可以查看。

所以似乎我的代码报告了有效和合法的星期日,但不知怎的,它错过了其中的两个。

修改2

我对代码中的日期格式进行了以下微小更改:

$date = sprintf('%d-%02d-01', $year, $month); // formats yyyy-mm-dd

然后我使用@ MadaraUchiha的代码生成一个包含171个正确日期的数组。

将他的约会与我的约会进行比较后,这两个错过的日期是:

  

1901年9月1日   1901年12月1日

编辑3

Codepad also shows这些日期不是星期日(但它们确实应该是)。

我确信这些日期被正确地解释为YYYY-MM-DD,因为我的代码提供给解决方案的日期之一是2000-10-01,如果10是月份,这只是一个星期日,不是白天。

编辑4

显然,如果在32位系统上,Unix时间戳将无法在该范围之外工作:

Fri, 13 Dec 1901 20:45:54 GMT

Tue, 19 Jan 2038 03:14:07 GMT

3 个答案:

答案 0 :(得分:4)

它在某些使用时间戳的系统上可能无法工作的原因是32位系统上的Unix时间戳范围是从Fri, 13 Dec 1901 20:45:54 GMTTue, 19 Jan 2038 03:14:07 GMT,所以你几乎在第一个月内错过了几个月年。

64位系统具有更大的整数,这使得范围更大(在PHP中)。

答案 1 :(得分:2)

使用DateTime对象获得171(更短,更易读)代码:

header("Content-type: text/plain"); //Browser display

$time = new DateTime("1901-01-01");
$end = new DateTime("2000-12-31");

$counter = 0;

while (!$time->diff($end)->invert) { //$time isn't greater than $end
    $time->modify("+1 month");
    if ($time->format("l") == "Sunday") {
        $counter++;
        echo $time->format("Y-m-d") . " was a Sunday!\n";
    }
}

echo "\nTotal number of Sundays: $counter";

使用DateTime对象时,您将日期视为日期,而不是数字字符串。与其他任何方法相比,这为您提供了巨大的灵活性优势。

答案 2 :(得分:0)

此代码的问题是

$date = $month . "/1/" . $year;

这应该是

$date = "1/".$month."/" . $year;

你混合了几个月和几天的地方。