Enigmatic Code

Programming Enigma Puzzles

Enigma 1118: 2001 – A specious oddity

From New Scientist #2274, 20th January 2001 [link]

George is planning to celebrate the new millennium — the real one — by visiting Foula, the most remote of the Shetland Islands. It is one of the few places in the world where the inhabitants still live by the old Julian calendar rather than the now almost universal Gregorian calendar.

In order to correct the drift of the Julian calendar against the seasons, Pope Gregory decreed that in 1582, Thursday 4th October (Julian) should be immediately followed by Friday 15th October (Gregorian), and in order to prevent a recurrence of the drift, years divisible by 100 would henceforth only be leap years if divisible by 400. Previously all years divisible by four were leap years. Catholic countries obeyed immediately, others — apart from Foula — fell into line in later centuries.

While planning his visit George programmed his computer to print 12-month calendars for the required year, showing weekdays, under both Julian and Gregorian styles. But when he ran the program he was surprised to find that the two printouts were identical.

He then realised that he had entered the wrong year number — the Julian and Gregorian calendars for the year 2001 are not the same.

What is the first year after 1582 for which they are the same?

[enigma1118]

Advertisements

One response to “Enigma 1118: 2001 – A specious oddity

  1. Jim Randell 24 April 2017 at 7:38 am

    This Python program runs in 41ms.

    from enigma import printf
    
    # year, gregorian start day, julian drift
    (year, start, drift) = (1583, 6, 10)
    
    while True:
    
      # categorise the leap year
      # 0 = not a leap year (in either calendar)
      # 1 = leap year in julian calendar but not gregorian
      # 2 = leap year in both calendars
      if year % 4 == 0:
        # this is a leap year in the julian calendar
        if year % 100 == 0 and year % 400 != 0:
          # but not in the gregorian calendar
          leap = 1
        else:
          leap = 2
      else:
        leap = 0
    
      # julian start day
      jstart = (start + drift) % 7
    
      # do the calendars co-incide?
      same = (start == jstart and leap != 1)
      printf("{year}: gregorian start = {start}, julian start = {jstart} [leap={leap}, drift={drift}, same={same}]")
      if same: break
    
      # move on to the next year
      ndays = (366 if leap == 2 else 365)
      start = (start + ndays) % 7
      year += 1
      if leap == 1: drift += 1
    

    Solution: The calendars are the same in year 2101.

    According to Wikipedia [ https://en.wikipedia.org/wiki/Foula ], the year 1900 was not treated as leap year on Foula, so their calendar is currently 1 day ahead of the Julian calendar, and so George’s printout would not be the correct calendar for Foula.

    The solution fits with what we would expect. We need the calendars to be offset by a whole number of weeks, and they start off 10 days apart. The only difference in the calendars is the way leap days are observed. So in every 400 year period there are 3 leap days that are observed in the Julian calendar, but not in the Gregorian calendar, so the drift will increase by 3 days every 400 years.

    In year 1600, both calendars will have observed a leap day and will still be 10 days apart.
    In year 1700, the Julian calendar will have observed a leap day, but the Gregorian calendar won’t, so they will be 11 days apart (at the end of the year).
    In year 1800, the Julian calendar have had a leap day, and the Gregorian won’t, so they will be 12 days apart.
    In year 1900, they will be 13 days apart.
    In year 2000, both calendars observe a leap day, so they remain 13 days apart.
    In year 2100, the Julian calendar has a leap day and the Gregorian calendar doesn’t, so they will be 14 days apart.

    So the printouts for Year 2101 will be the same for both calendars.

    Note that although the printouts for the Gregorian and Julian calendars would be the same for the year 2101, the calendars are not in sync. At the time adherents of the Julian calendar are celebrating January 1st, people following the Gregorian calendar would already be on January 14th (and for the residents of Foula it would be January 2nd).

    We can use the Unix ncal command to generate Julian and Gregorian calendars, and then compare the output to see if they are the same. Here’s a Python program that does the comparison for us.

    import subprocess
    from itertools import count
    from enigma import sprintf as f
    
    # command for the julian calendar
    jcmd = "ncal -J {year}"
    
    # command for the gregorian calendar
    gcmd = "ncal -s IT {year}"
    
    for year in count(1583):
      j = subprocess.check_output(f(jcmd), shell=True)
      g = subprocess.check_output(f(gcmd), shell=True)
      if j == g:
        print(f("same for year {year}"))
        break
    

    When we run this (on a Unix system) we find that Year 2101 is indeed the first year that the printouts are the same.

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: