Riddler Express: November 4, 2022

David Ding

November 4, 2022

Leap Into a Better Calendar

The end of daylight saving time here on the East Coast of the U.S. got me thinking more generally about the calendar year. Each solar year consists of approximately 365.24217 mean solar days. That’s pretty close to 365.25, which is why it makes sense to have an extra day every four years. However, the Gregorian calendar is a little more precise: There are 97 leap years every 400 years, averaging out to 365.2425 days per year.

Can you make a better approximation than the Gregorian calendar? Find numbers L and N (where N is less than 400) such that if every cycle of N years includes L leap years, the average number of days per year is as close as possible to 365.24217.

\(L = 85\) and \(N = 351\). With 85 leap years in a 351-year cycle, the average number of days per year is \(365.242165242\dots\) which gives an error of \(4.75783 \times 10^{-6}\) days.

Explanation:

The average number of days in a year with \(L\) leap years over an \(N\)-year cycle is:

\begin{align} d &= \frac{365(N - L) + 366L}{N} \\ \\ &= \frac{365N - 365L + 366L}{N} \\ \\ &= \frac{365N + L}{N} \\ \\ &= 365 + \frac{L}{N} \end{align}

Since \(L\) and \(N\) are positive integers with \(L < N\), then \(\frac{L}{N}\) must represent the fractional part of the average number of days, and we want to get it as close to 0.24217 as possible.

With our mission statement created, we can write a short computer program to go over all the possible ratios of \(L\) to \(N\) and find the one closest to our target. Below is my program in MATLAB:

function [L, N, bestVal, bestErr] = getOptLeapYears(maxN, target)
%getOptLeapYears get L and N for the Riddler Express Nov 4, 2022
    % target is the decimal part of the target solar days
    % maxN is the maximum N

    bestVal = 0;
    bestErr = 1;

    for k = 1:maxN
        [bestErrSoFar, indx] = min(abs((1:k-1)/k - target)); 
        if bestErrSoFar < bestErr
            L = indx;
            N = k;
            bestVal = L/N;
            bestErr = bestErrSoFar;
        end
    end
end

Where the outputs "bestVal" represents the best value of \(\frac{L}{N}\) and "bestErr" is the minimized difference between "bestVal" and our target, which is 0.24217 in our case. Since it is given that \(N < 400\), we have "maxN" = 399 in our program.

Running the above program with those inputs yields:

\(L = 85\), \(N = 351\), and we will have on average 365.242165242 solar days per year, which is off from our target by \(4.75783 \times 10^{-6}\) days, or 0.411 seconds. We lose less than half a second every year using this calendar system. To put this in perspective, the next time we need a "leap leap" day to make up for this difference would be after more than 200,000 years! On the scale of a human lifetime, this calendar needs no further tweaks and we have indeed leapt into a more accurate calendar.