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