Project Euler #19 - Counting Sundays Problem

Viewed 218

I have been working on this problem for a while. It's a problem that says you have to find how many Sundays land on the First of the Month in the years 1901 to 2000. I've made it mostly work, but it still outputs 173, instead of 171 (the correct answer).

Does anyone why this is?

months = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31}

start, end = 1900, 2001

years = range(start, end)
leap_years = range(1904, 2001, 4)

Sundays = 0
days = 1
for year in years:
  if year in leap_years:
    months[2] = 29 
  else:
    months[2] = 28

  for month in range(1, 13):
    for day in range(1, months[month]+1):
      if days == 7:
        if day == 1:
          print(year, month, day)
          Sundays += 1
        days = 1
      else:
        days += 1


print(Sundays)
2 Answers

Your algorithm is completely correct - just the inputs are wrong. start and end should be:

start, end = 1901, 2000

The range(a, b) function is not inclusive of b, but it is inclusive of a. Thus start should be 1901 instead of 1900.

The end is a bit more tricky, you have to think about the phrasing of the question:

... in the years 1901 to 2000

Think about it - this means every day up to, but not including, Jan 1 2000. Thus the last year that you actually want to iterate through and check is 1999. Thus, setting end to 2000 will cause the range() function to return all the years up to, but not including, 2000. Which is exactly what the question asks for.

Your days assumes day equal 1 is days equal 1, (Monday) starting from the first month (and then progresses through the months, years). I don't think this will accurately calculate the count of Sundays that fall on the first of each month over the years.

If you enter the following code at the beginning of your program (and delete the line before your loop that says days = 1), it will correctly give the number of Sundays == 171. This will start out the day of week for the first day of the first month of the first year accurately.

from calendar import weekday
start, end = 1901, 2001
days = 1 + weekday(start, 1, 1)

Note that the weekday function uses zero based counting, (Monday through Sunday is 0 to 6) so that's why 1 is added to the result in the initialization of days. (Because your Monday to Sunday is 1 to 7).

Just to illustrate how the solution could find Sundays without iterating through every day of all the years:

from calendar import weekday

sundays = 0

for yr in range(1901, 2001):
    for month in range(1, 13):
        if weekday(yr, month, 1) == 6:
            sundays += 1

print(sundays) # prints 171
Related