kostumブログ

勉強したことやノート代わりのアウトプットに使っています。

project Euler 019

環境

問題

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

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

20世紀(1901年1月1日から2000年12月31日)中に月の初めが日曜日になるのは何回あるか?

考え方

  1. 変数に西暦年、月、日を設定する
  2. 日は「9月, 4月, 6月, 11月は30日, 2月を除く他の月は31日。」「2月は28日まであるが, うるう年のときは29日」「うるう年は西暦が4で割り切れる年に起こる。しかし、西暦が400で割り切れず100で割り切れる年はうるう年でない」条件を満たしつつ、for文で回す。

コード

// 0 = 日、1 = 月、2 = 火、3 = 水、4 = 木、5 = 金、6 = 土
let date = 1;
let limitDay = 31;
let sum = 0;
for (let year = 1900; year < 2001; year++) {
  for (let month = 1; month < 13; month++) {
    if (month === 9 || month === 4 || month === 6 || month === 11) {
      limitDay = 30;
    } else if (
      month === 1 ||
      month === 3 ||
      month === 5 ||
      month === 7 ||
      month === 8 ||
      month === 10 ||
      month === 12
    ) {
      limitDay = 31;
    } else if (month === 2) {
      if (year % 400 !== 0 && year % 100 === 0) {
        limitDay = 28;
      } else if (year % 4 === 0) {
        limitDay = 29;
      } else {
        limitDay = 28;
      }
    }
    for (let day = 1; day <= limitDay; day++) {
      if (year > 1900 && day === 1 && date === 0) {
        sum = sum + 1;
      }
      date = date + 1;
      // 曜日計算
      if (date === 7) {
        date = 0;
      }
    }
  }
}
return sum;

説明

  • 曜日、月によって変化する日、月の初めが日曜日になる回数を変数に設定する。
  • for 文で1900年から2000年までループする。
  • その中で、for 文で1月から12月まで回す。
  • この時、月によって変わる最後の日を条件分岐で設定する。
  • さらにその中で、for 文で1日〜28 or 29 or 30 or 31日を回す。
  • 日の for 文内で、月の初めが日曜日になる時かつ1901年以上の時、数える。
  • さらに、曜日計算をする