Introduction
A leap year (in the Gregorian calendar) occurs:
- In every year that is evenly divisible by 4.
- Unless the year is evenly divisible by 100, in which case it’s only a leap year if the year is also evenly divisible by 400.
Some examples:
- 1997 was not a leap year as it’s not divisible by 4.
- 1900 was not a leap year as it’s not divisible by 400.
- 2000 was a leap year!
For a delightful, four-minute explanation of the whole phenomenon of leap years, check out [this YouTube video](https://www.youtube.com/watch?v=xX96xng7sAE).
Instructions
Instructions
Your task is to determine whether a given year is a leap year.
Dig Deeper
Boolean chain
Chain of boolean expressions
export function isLeap(year) {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
The first boolean expression uses the remainder operator to check if the year is evenly divided by 4.
- If the year is not evenly divisible by
4, then the chain will “short circuit” due to the next operator being a logical AND (&&),
and will return false.
- If the year is evenly divisible by
4, then the logical NOT operator is used to check if the year is not evenly divisible by 100.
- If the year is not evenly divisible by
100, then the expression is true and the chain will “short-circuit” to return true,
since the next operator is a logical OR (||).
- If the year is evenly divisible by
100, then the expression is false, and the returned value from the chain will be if the year is evenly divisible by 400.
| year | year % 4 == 0 | year % 100 != 0 | year % 400 == 0 | is leap year |
|---|
| 2020 | true | true | not evaluated | true |
| 2019 | false | not evaluated | not evaluated | false |
| 2000 | true | false | true | true |
| 1900 | true | false | false | false |
The chain of boolean expressions is efficient, as it proceeds from testing the most likely to least likely conditions.
Shortening
By using the falsiness of 0, a test for a value equaling 0 can be shortened using the logical NOT operator,
like so
export function isLeap(year) {
return !(year % 4) && (year % 100 != 0 || !(year % 400));
}
It can be thought of as the expression not having a remainder.
When the body of a function is a single expression, the function can be implemented as an arrow function, like so
export const isLeap = (year) =>
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
or
export const isLeap = (year) =>
!(year % 4) && (year % 100 != 0 || !(year % 400));
Notice that return and the curly braces are not needed.
Ternary operator
Ternary operator
export function isLeap(year) {
return year % 100 == 0 ? year % 400 == 0 : year % 4 == 0;
}
A conditional operator, also known as a “ternary conditional operator”, or just “ternary operator”,
uses a maximum of two checks to determine if a year is a leap year.
It starts by testing the outlier condition of the year being evenly divisible by 100.
It does this by using the remainder operator.
If the year is evenly divisible by 100, then the expression is true, and the ternary operator returns if the year is evenly divisible by 400.
If the year is not evenly divisible by 100, then the expression is false, and the ternary operator returns if the year is evenly divisible by 4.
| year | year % 100 == 0 | year % 400 == 0 | year % 4 == 0 | is leap year |
|---|
| 2020 | false | not evaluated | true | true |
| 2019 | false | not evaluated | false | false |
| 2000 | true | true | not evaluated | true |
| 1900 | true | false | not evaluated | false |
Although it uses a maximum of only two checks, the ternary operator tests an outlier condition first,
making it less efficient than another approach that would first test if the year is evenly divisible by 4,
which is more likely than the year being evenly divisible by 100.
Shortening
By using the falsiness of 0, a test for a value equaling 0 can be shortened using the logical NOT operator,
like so
export function isLeap(year) {
!(year % 100) ? !(year % 400) : !(year % 4);
}
It can be thought of as the expression not having a remainder.
When the body of a function is a single expression, the function can be implemented as an arrow function, like so
export const isLeap = (year) =>
year % 100 == 0 ? year % 400 == 0 : year % 4 == 0;
or
export const isLeap = (year) => (!(year % 100) ? !(year % 400) : !(year % 4));
Notice that return and the curly braces are not needed.
switch statement
switch statement
export function isLeap(year) {
switch (true) {
case year % 400 == 0:
return true;
case year % 100 == 0:
return false;
default:
return year % 4 == 0;
}
}
The switch statement tests the value true, which leaves the actual testing up to the case arms.
The default arm of the switch returns whether the year is evenly divisable by 4 when none of the previous arms match.
| year | year % 4 | year % 100 | year % 400 | is leap year |
|---|
| 2020 | 0 | 20 | 20 | true |
| 2019 | 3 | 19 | 19 | false |
| 2000 | 0 | 0 | 0 | true |
| 1900 | 0 | 0 | 300 | false |
The switch statement is somewhat more verbose than other approaches,
and may also be considered less readable.
Shortening
By using the falsiness of 0, a test for a value equaling 0 can be shortened using the logical NOT operator,
like so
export function isLeap(year) {
switch (true) {
case !(year % 400):
return true;
case !(year % 100):
return false;
default:
return !(year % 4);
}
}
It can be thought of as the expression not having a remainder.
Source: Exercism javascript/leap