javascriptleap-year

Leap year solution check


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.";
    }
}


Solution

  • 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.";