Sunday, May 8, 2011

Project Euler-Problem 19

Description

From Project Euler:

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)?

Solution

Most modern languages (Ruby included) have decent basic date support baked in. In our case, Ruby makes it easy to check what day of the week a given date falls on through the use of the sunday? through saturday? methods. So all we really have to do here is iterate through the 1,200 months (12 months/year * 100 years) and check the first of each month:

(1..12).to_a.product((1901..2000).to_a).count { |month,year| Time.new(year,month,1).sunday? }

Another simple solution provided by the power of Ruby. One thing I would have liked to see, though, was the product method on the Range class. Or even better, having the * operator as an alias to the product method. This can be achieved easily enough, though:

class ::Range
  def product(other)
    self.to_a.product(other.to_a)
  end
  alias :* :product
end

((1..12) * (1901..2000)).count { |month,year| Time.new(year,month,1).sunday?}

The full source and specifications can be seen on github. Next time, finding the sum of digits in 100!

No comments: