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


In [1]:
# # All the rest have thirty one.
# m = { i:31 for i in range(1,13) }
# # Thirty days has September, April, June and November.
# for i in [9,4,6,11]:
#     m[i] = 30
# # Saving February alone, Which has twenty-eight, rain or shine.
# m[2] = 28
def days_for_month(month, year):
    m = {1: 31, 2: 28, 3: 31, 4: 30,
     5: 31, 6: 30, 7: 31, 8: 31, 
     9: 30, 10: 31, 11: 30, 12: 31}
    # And on leap years, twenty-nine.
    if year % 4 == 0 and not (year % 100 == 0 and year % 400 != 0):
        m[2] = 29
    
    return m[month]

# Test
assert days_for_month(2, 100) == 28
assert days_for_month(2, 400) == 29

In [2]:
start_year = 1901
end_year = 2000

# 1 Jan 1900 was a monday.
days = 0
for y in range(1900, start_year):
    for mon in range(1,13):
        days += days_for_month(month=mon, year=y)
offset = days % 7

first_sundays = []
for y in range(start_year, 2001):
    for mon in range(1, 13):
        if (offset + days_for_month(month=mon, year=y)) % 7 == 6:
            first_sundays.append((mon+1, y))
        offset = (offset + days_for_month(month=mon, year=y)) % 7
print len(first_sundays)


171