解决问题19

Signed-off-by: SidneyZhang <zly@lyzhang.me>
This commit is contained in:
2025-12-21 16:11:46 +08:00
parent 29b522606a
commit a1f849985e
3 changed files with 464 additions and 262 deletions

View File

@@ -0,0 +1,84 @@
"""
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)?
"""
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Execution time: {end_time - start_time} seconds")
return result
return wrapper
def is_leap_year(year: int) -> bool:
return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)
def days_in_years(years: list[int]) -> int:
leapyears = [year for year in years if is_leap_year(year)]
return sum([366 if year in leapyears else 365 for year in years])
def count_sundays(start_year: int | str, end_year: int | str) -> int:
start_year = int(start_year) if isinstance(start_year, str) else start_year
end_year = int(end_year) if isinstance(end_year, str) else end_year
if start_year < 1900 or start_year > end_year:
raise ValueError(f"Invalid year range {start_year} to {end_year}")
last_days = days_in_years(list(range(1900, start_year)))
year_list = list(range(start_year, end_year + 1))
days = days_in_years(year_list) + (last_days % 7)
sundays = days // 7
return sundays
def days_month(year: int, month: int) -> int:
if month in [1, 3, 5, 7, 8, 10, 12]:
return 31
elif month in [4, 6, 9, 11]:
return 30
elif month == 2:
return 29 if is_leap_year(year) else 28
else:
raise ValueError(f"Invalid month {month}")
def days_sunday_month(start_year: int, end_year: int) -> int:
count = 0
outday = days_in_years(list(range(1900, start_year))) % 7
for year in range(start_year, end_year + 1):
for month in range(1, 13):
if outday == 6:
count += 1
outday = (outday + days_month(year, month)) % 7
return count
@timer
def main() -> None:
print(f"Number of Sundays between 1901 and 2000: {count_sundays(1901, 2000)}")
@timer
def main_first_day() -> None:
print(
f"Number of Sundays on the first of the month between 1901 and 2000: {days_sunday_month(1901, 2000)}"
)
if __name__ == "__main__":
main()
main_first_day()