Thursday, 4 June 2015

Gregorian Date Calculation Golf 2a

My previous attempt at a Gregorian Date Calculation Golf routine to calculate the number of days in a month can be found here. However, this thread has an interesting discussion about optimizing the calculation in JavaScript. It turns out that using a shift-value to encode the twelve-element table is not new at all; though the following treats all instances of February as special cases and can therefore pack all the remaining months into just one bit each:

int DaysInMonth(int year, int month) {
    if (month == 2) {
        return IsLeapYear(year) ? 29 : 28;
    }
    return 30 + ((5546 >> month) & 1);
}

A potentially superior (in JavaScript) alternative is also given:

int DaysInMonth(int year, int month) {
    if (month == 2) {
        return IsLeapYear(year) ? 29 : 28;
    }
    return 30 + ((month + (month >> 3)) & 1);
}

Although both these algorithms are slower than a simple table lookup in C/C++ (on my machine), the latter is marginally quicker than my previous 32-bit and 64-bit Golf attempts.

However, even with these elegant solutions, there's always room for "improvement":

int DaysInMonth(int year, int month) {
    if (month == 2) {
        return IsLeapYear(year) ? 29 : 28;
    }
    return (month + (month >> 3)) | 30;
}

No comments:

Post a Comment