def weekday_generator_function(): while True: yield 'Monday' yield 'Tuesday' yield 'Wednesday' yield 'Thursday' yield 'Friday' yield 'Saturday' yield 'Sunday' def day_of_month_generator_function(): day, month, year = 1, 1, 1901 while year < 2001: yield day day += 1 if month == 2: if year % 4 == 0 and (not year % 100 == 0 or year % 400 == 0): if day == 30: month += 1 day = 1 elif day == 29: month += 1 day = 1 elif month in [9, 4, 6, 11] and day == 31: day = 1 month += 1 elif month in [1, 3, 5, 7, 8, 10] and day == 32: day = 1 month += 1 elif month == 12 and day == 32: day = 1 month = 1 year += 1 def euler_019(): wds = weekday_generator_function() next(wds) # get rid of first Monday ds = zip(wds, day_of_month_generator_function()) s = len([1 for weekday, date in ds if weekday == "Sunday" and date == 1]) return s def euler_019_brain(): """ We have 100 years which means 1200 months. Every months starts with a day and 1/7 of all days are Sundays. """ return 1200 // 7 if __name__ == "__main__": assert(euler_019() == 171) assert(euler_019() == euler_019_brain()) print("e019.py: {}".format(euler_019()))