I know there are better and more efficient solutions to check which year is a leap year. But I'm a beginner and I'm curious, despite my code being inefficient, does it still carry out the solution and its logic isn't flawed?
This is how to work out whether a particular year is a leap year:
A year is a leap year if it is evenly divisible by 4 ;
except if that year is also evenly divisible by 100;
unless that year is also evenly divisible by 400.
My solution:
function isLeap(year) {
if (year % 4 === 0 && year % 100 != 0) {
return "Leap year.";
}
if (year % 4 === 0 && year % 100 != 0 && year % 400 === 0) {
return "Leap year.";
}
if (year % 4 === 0 && year % 100 != 0 && year % 400 != 0) {
return "Not leap year.";
}
else {
return "Not leap year.";
}
}
In your code you have 3 if statements separately. The 3rd if-statement, regardless of the outcome, will log "Not a leap year", so year % 400 !=0
is a redundant check to make, because if removed, it will still fall under the else
comparison.
Meaning we can put everything that is not a leap year into the else
and eliminate the if statement, making the code look like this.
if (year % 4 === 0 && year % 100 != 0) {
return "Leap year.";
}
if (year % 4 === 0 && year % 100 != 0 && year % 400 === 0) {
return "Leap year.";
}
else {
return "Not leap year.";
}
and if we look at the remaining if statements, we can see that the first 2 comparisons are identical, and we have an optional check of year % 400 === 0
.
However, according to your 3 rules, the 3rd rule states:
unless that year is also evenly divisible by 400.
So we can assume that if it it divisible by 400, it's a guaranteed leap year and we have the statement year % 400 === 0
ensuring that. Then we follow that with an OR operator, ||
. This means that if we ever get a year that is divisible by 400, we always return that its a leap year regardless of the other 2 rules.
However, if its not divisible by 400, we have the 2 remaining comparisons year % 100 != 0 && year % 4 === 0
. And if these both are true, enforced by the AND operator, &&
, then it's also a leap year. Which would leave you with the following if statement.
if (year % 400 === 0 || year % 100 !== 0 && year % 4 === 0) {
return "Leap year.";
}
else {
return "Not leap year.";
}
At this point, you could say that a year will either enter the if statement by being true and falling under the rules of being a leap year. Meaning we could remove the else
and just have an if statement and an extra return afterwards that will never be reached if the function is called with a valid leap year.
if (year % 400 === 0 || year % 100 !== 0 && year % 4 === 0) {
return "Leap year.";
}
return "Not leap year.";