Ad
  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    It's not exactly that, we don't "add" days to a date, we create a new date with the original month and day, but with an incremented year. It's just that when you create a date with a day out of the bounds of the month (like January, 32nd or February, 29th on non-leap years, or even day = -1) the function changes the month so that the date will stay valid (so Date("January, 32nd") === Date("February, 1st"))

    That's important because if we "just" added one year everytime, a date starting on February, 29th would stay stuck on March, 1st forever (didn't I say April earlier? Maybe I should go learn the month of the year xD)

    Not sure if that was clear enough, to make it simpler we don't add a set number of days because that would depend on leap years, which is quite a pain in the ass (a year is a leap year if it's divisible by 4, but not by 100 except when it's also divisible by 400 (in which cas it's still a leap year)... And it's not added in the algorithm but we should add a leap year when divisible by 1000).

    Well, we don't care about that: when given for instance 2012, 2, 29, we just create a new date with incremented year (2013, 2, 29) and all the boring leap year check is made by the Date object. And we check if we're still on February and if the weekday is the same. While not we keep incrementing (2014, 2, 29, 2015, 2, 29, 2016, 2, 29, ...)

  • Custom User Avatar

    Great explanation, thanks. I misunderstand the function of Date.setFullYear(), now it all makes sense. setFullYear() will add "365" days to current date, so after adding 356 days, 29 February will be 1 March next year, if next year don't have 29 in February. It's really clever!!

  • Custom User Avatar

    No, your assumption is perfectly right that we need both t1.getDay() == t0.getDay and t1.getMonth() == t0.getMonth() to stop the loop (because of 29 February + 1 year giving a 1st April).

    Thus, we need to LOOP while t1.getDay() != t0.getDay OR t1.getMonth() != t0.getMonth(), which is equivalent to !(t1.getDay() == t0.getDay && t1.getMonth() == t0.getMonth()) (we keep looping while the current year is not a perfect birthday)

    A (maybe clearer) equivalent would be

    while (true) {
        t1.setFullYear(t0.getFullYear() + ++i, t0.getMonth(), t0.getDate());
        return i if (t1.getDay() == t0.getDay() && t1.getMonth() == t0.getMonth())
    }
    

    But I prefer avoiding return statements in a loop whenever possible.

  • Custom User Avatar

    I've looked up the getMonth function, but I still don't get why t1.getDay() !== t0.getDay but t1.getMonth() === t0.getMonth() will get the correct answer? Because while t1.getMonth() === t0.getMonth() will also return true and stop the loop.
    Could you please tell me about the logic here?