Leap Years
The challenge
Write a function that takes an integer year and returns whether or not it is a leap year.
A leap year is one that is divisible by 4, but not divisible by 100 unless it is also divisible by 400.
For example:
2001is a typical common (non-leap) year.1996is a typical leap year.1900is an atypical common year (divisible by 100, but not 400).2000is an atypical leap year (divisible by 100 and 400).
Remember to follow the red-green-refactor cycle and, if you're using an AI coding assistant, keep it on a tight leash — one test at a time.
Suggested test list
- A year not divisible by 4 at all (e.g.
2023) → not a leap year (happy path). - A year divisible by 4 and not by 100 (e.g.
1996) → leap year (happy path). - A year divisible by 100 but not by 400 (e.g.
1900) → not a leap year (the tricky rule). - A year divisible by 400 (e.g.
2000) → leap year (the tricky rule, other direction). - What about year
0? Decide whether your function should treat it as a valid input, and write a test that documents your decision. - What about negative years? Does the rule even make sense historically, and should your function reject them, or just apply the same arithmetic?
- What is the smallest/largest input your language's integer type can represent — does your solution behave sensibly at those boundaries?
Your task
Implement the solution using strict TDD, one test from the list at a time.
💡 Show a reference solution (only after you've completed your own via TDD)
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}
module.exports = { isLeapYear };
// example tests, e.g. with Jest
test("typical common year", () => expect(isLeapYear(2001)).toBe(false));
test("typical leap year", () => expect(isLeapYear(1996)).toBe(true));
test("atypical common year", () => expect(isLeapYear(1900)).toBe(false));
test("atypical leap year", () => expect(isLeapYear(2000)).toBe(true));