Project Euler 19

次の情報が与えられている。

・1900年1月1日は月曜日である。
・9月、4月、6月、11月は30日まであり、2月を除く他の月は31日まである。
・2月は28日まであるが、うるう年のときは29日である。
・うるう年は西暦が4で割り切れる年に起こる。しかし、西暦が400で割り切れず100で割り切れる年はうるう年でない。

20世紀(1901年1月1日から2000年12月31日)で月の初めの日曜日の数を数えよ。

Mathematica

Needs["Calendar`"]

Count[
  Flatten[
    Table[
      Table[
        DayOfWeek[{i, j, 1}],
        {j, 1, 12}
      ],
      {i, 1901, 2000}
    ]
  ],
  Sunday
]

うるう年とかをプログラミングで算出するのはプログラミングの問題ではよくあるものだと思うのですが・・・
Mathematicaに装備されている、『指定された日付の曜日を返す』機能を持った DayOfWeek 関数がこの問題の意図をすべて破壊してしまっています。
文字通り曜日を並べて日曜日を数えただけです。


C/C++

#include <iostream>
using namespace std;

// n年が閏年かどうかを判定する
bool isLeapYear(int n){
	if(n%400==0) return true;
	else if(n%100==0) return false;
	else if(n%4==0) return true;
	else return false;
}

int main(){
	int DayOfWeek=0;
	int sunday=0;

	for(int year=1900 ; year<= 2000 ; year++){
		for(int month=1 ; month <= 12 ; month++){
			for(int day=1 ; day <= 31 ; day++){
				DayOfWeek++;

				if(DayOfWeek==7){
					if(year!=1900 && day==1) sunday++;
					DayOfWeek=0;
				}

				if(day == 28 && month == 2 && !isLeapYear(year)) break;
				else if(day == 29 && month == 2 &&  isLeapYear(year)) break;
				else if(day == 30 && (month==4 || month==6 || month==9 || month==11)) break;
			}
		}
	}
	cout << sunday << endl;

	int end;
	cin >> end;
	return 0;
}

閏年判定はif文の勉強のときにやっていた記憶が。懐かしい。
問題をきちんと読んでいなくて、思い切りつまづいた。数えるのは1901〜2000年の間なのだが、与えられているのは1900年の曜日だというのがちょっとひっかけ。