Leap Year
You get a year year of the Gregorian calendar. Return true if it is a leap year, the kind that has a 29th of February, and false otherwise.
A year is a leap year when it is divisible by 4, except for years divisible by 100, which are not leap years unless they are also divisible by 400.
Function
- yearinteger
- the year to check
- Returnsboolean
- true when the year has a 29th of February, false otherwise
Constraints
1 ≤ year ≤ 106
Examples
- Input
- year = 2024
- Output
- true
- Explanation
2024is divisible by4and is not a century year, so it is a leap year.
- Input
- year = 1900
- Output
- false
- Explanation
1900is divisible by4, but also by100and not by400, so the century exception applies: not a leap year.
- Input
- year = 2000
- Output
- true
- Explanation
2000is divisible by100, which would rule it out, but also by400, which brings it back. It is a leap year.
Hints
Open them one at a time. Each one gives away a little more.
A remainder of
0after dividing by4is the first rule. Which years break it?Century years break it, and multiples of
400break the century rule in turn. Every multiple of400is also a multiple of100and of4, so the order of your checks decides the answer.Check divisibility by
400first, then by100, then by4, and let the first rule that matches decide. Or combine them: divisible by 4 and not by 100, or divisible by 400.
Solution
Each rule needs one remainder, so the work is three divisibility checks. The trap is the order: on 2000, a century that is also a multiple of 400, the rules disagree. Test the most specific rule first, or write one expression whose parentheses keep the exceptions in place.
Check the rules from most specific to least
Intuition
Divisible by 4 makes a year leap, divisible by 100 undoes that, and divisible by 400 undoes the undo. Every multiple of 400 is a multiple of 100, and every multiple of 100 is a multiple of 4, so the most specific rule that matches decides the answer.
Test 400, then 100, then 4, and return at the first match. 2000 stops at the first test, 1900 at the second, 2024 at the third. A year that matches none is not divisible by 4, so it is an ordinary year.
Algorithm
- If
year % 400 == 0, returntrue. - If
year % 100 == 0, returnfalse. - If
year % 4 == 0, returntrue. - Otherwise return
false.
def isLeapYear(year):
if year % 400 == 0:
return True
if year % 100 == 0:
return False
if year % 4 == 0:
return True
return FalseOne boolean expression
Intuition
Read the rule as two ways to be a leap year: divisible by 4 and not a century, or divisible by 400. That sentence becomes (year % 4 == 0 and year % 100 != 0) or year % 400 == 0.
2024 passes the first half. 1900 and 2000 both fail it as centuries; only 2000 passes the second, since 1900 % 400 is 300. Grouping it as divisible by 4 and (not a century or a multiple of 400) gives the same answer for every year.
Algorithm
- Compute
year % 4 == 0 and year % 100 != 0: divisible by 4 and not a century. - Compute
year % 400 == 0. - Return
trueif either part holds.
def isLeapYear(year):
# Every 4th year, except centuries, except every 400th year.
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
Pitfalls and edge cases
- Checking only
year % 4 == 0. It is right for every year from1901to2099, which is why the bug hides, and wrong for1900and2100. - Testing
100before400in an if chain. The century test returnsfalsefor2000before the400test runs. - Dropping the divisible by 4 part.
year % 100 != 0 or year % 400 == 0calls2023a leap year, because2023is not a century. - Using
year / 4where you meant the remainder. Division tells you how many times4fits; the remainder tells you whether it fits exactly.
Frequently asked questions3
What is the time complexity of checking a leap year?
O(1) in time and space: at most three remainder operations and a few comparisons, whatever the year.
Why is 1900 not a leap year but 2000 is?
Both are century years, divisible by 100, which normally rules a year out. 2000 is also divisible by 400, and that rule overrides the century rule. 1900 leaves a remainder of 300 when divided by 400, so it stays an ordinary year.
Why do the century rules exist?
A solar year lasts about 365.2422 days. A leap day every 4 years gives an average of 365.25, about 3 days too many every 400 years. Skipping the leap day in 3 of every 4 century years removes those days and brings the average to 365.2425, which keeps the calendar in step with the seasons.
Similar problems
Problems that use the same ideas. Solving two or three of them is what makes a pattern stick.
def isLeapYear(year):
# Write code hereTest #1
Test #2
Test #3
Argument
year = 2024
Expected Output
true