How to Implement a Date Algorithm in Ruby
In this lesson, we are going to see how to solve another fun and challenging problem from Project Euler (question #19) where we need to figure out an efficient solution to the question: How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this lesson, we are going to see how to solve another fun and challenging math problem where we build an efficient solution to the question:

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

To solve this problem, first we have to add the date library to our code file. From there we can setup some variables:

require 'date'

start_date = Time.local(1901)
end_date = Time.local(2000,12,31)
sunday_counter = 0

The first variable has the starting date of the problem. By default the local method starts with January 1st so there is no need to specify the actual day. However, we need to specify the exact date for our end_date variable. The third variable will count the number of Sundays that fell on the first of the month during the period between the start_date and end_date.

Next, we are going to create a while loop:

while end_date >= start_date
  if end_date.strftime("%A") == "Sunday" && end_date.strftime("%d") == "01"
    sunday_counter += 1
  end

  end_date -= 86400
end

All of the code inside the while loop will iterate until the end_date is equal to or greater than the start_date. Essentially, this loop will count back in time starting from the end date.

Inside the loop we are converting each timestamp to a string and checking if it is Sunday and if it is falling on the first day of the month. If so, we are adding to the sunday_counter variable. The method strftime converts date to string and takes various parameters. Here, the %A argument checks for the named day of the week while %d checks for the date of the month.

Finally, we are removing a day from the value of end_date and we can do that by subtracting the number of seconds in a day, which is 86400.

Now we can print out the sunday_counter value and run the program. You'll see that the output is 171, and that's the right answer.

The complete code is here:

require 'date'

start_date = Time.local(1901)
end_date = Time.local(2000,12,31)
sunday_counter = 0

while end_date >= start_date
  if end_date.strftime("%A") == "Sunday" && end_date.strftime("%d") == "01"
    sunday_counter += 1
  end

  end_date -= 86400
end

puts sunday_counter

Working with dates can be confusing. However when you utilize tools such as strftime you'll discover that dates can be made more manageable.