Project Eueler: problem19

問題

You are given the following information, but you may prefer to do some research for yourself.

1 Jan 1900 was a Monday.
Thirty days has September,
April, June and November.
All the rest have thirty-one,
Saving February alone,
Which has twenty-eight, rain or shine.
And on leap years, twenty-nine.
A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

回答

$nor = [31,28,31,30,31,30,31,31,30,31,30,31]
$nor_s = [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
$nor_d = 365
$leap = [31,29,31,30,31,30,31,31,30,31,30,31]
$leap_s = [1, 32, 61, 92, 122, 153, 183, 214, 245, 275, 306, 336]
$leap_d = 366

$sum = 0

def chk_leap(year)
  if year % 4 == 0 && year % 100 != 0
    return true
  elsif year % 400 == 0
    return true
  else
    return false
  end
end

def calc_leap(st)
  while st <= $leap_d do
    $sum += 1 if $leap_s.include?(st)
    st += 7
  end
  return st - $leap_d
end

def calc_nor(st)
  while st <= $nor_d do
    $sum += 1 if $nor_s.include?(st)
    st += 7
  end
  return st - $nor_d
end

dp = 6
1901.upto(2000).each do |x|  
  if chk_leap(x) then
    dp = calc_leap(dp)
  else
    dp = calc_nor(dp)
  end
end
p $sum

備考

無理矢理。

Dateモジュールを使ったり、
http://d.hatena.ne.jp/tmr_kohei/20110704/p1
ツェラーの公式を使うとスマートにできるのね。。
http://d.hatena.ne.jp/htz/20090303/1236048043