Enigmatic Code

Programming Enigma Puzzles

Enigma 1385: On this date

From New Scientist #2545, 1st April 2006

A very long time ago within the space of less than 100 years six members of a family were born on 1st April, all in different years. The year of birth of each of them was a perfect square. If we call them A to F in order of birth the number of years that separated the births of the following pairs was also a perfect square: A and D, A and E, B and D, B and F, C and D, C and E, C and F, E and F.

In which years in chronological order were the six born?

[enigma1385]

Advertisements

One response to “Enigma 1385: On this date

  1. Jim Randell 10 October 2013 at 9:14 am

    Finding a solution to this problem depends on one crucial observation. And for the sake of solving the problem I’ve assumed a certain amount of constancy in the calendar going back to ancient times. This Python program runs in 44ms.

    from itertools import combinations
    from enigma import irange, printf
    
    # we represent years by an integer, but there is no year 0 so:
    #
    # 2006AD = 2006
    # ...
    # 2AD = 2
    # 1AD = 1
    # 1BC = 0
    # 2BC = -1
    # 3BC = -2
    # ...
    #
    # this allows us to compute differences easily, but for BC years
    # the year number is given by 1 - n (not -n) [see ISO 8601]
    
    # we note that outside the year range 145BC to 144AD we can't
    # have 6 years with square year numbers in any 100 year span
    
    # possible squares
    squares = set(i * i for i in irange(0, 12))
    
    # is the year number square?
    def is_square_year(n):
      return (n if n > 0 else 1 - n) in squares
    
    # check the differences between the specified years
    def check(A, B, C, D, E, F):
      return squares.issuperset((D - A, E - A, D - B, F - B, D - C, E - C, F - C, F - E))
    
    # find sequences of 6 square numbered years
    def solve():
      sq = list()
      for y in irange(144, -145, -1):
        # find years with a square year number
        if not is_square_year(y): continue
        # drop years more than 99 years apart
        while sq and sq[-1] - y > 99:
          sq.pop(-1)
        # find six years that satisfy the conditions
        for ss in combinations(sq, 5):
          ss = (y,) + ss
          if check(*ss): yield ss
        sq.insert(0, y)
    
    # display a year
    def year(n):
      return (str(n) + ' AD' if n > 0 else str(1 - n) + ' BC')
    
    for years in solve():
      print(', '.join(year(y) for y in years), years)
    

    Solution: The years in chronological order are: 49 BC, 25 BC, 1 BC, 1 AD, 16 AD, 25 AD.

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: