Enigmatic Code

Programming Enigma Puzzles

Enigma 304: Enigmatic dates

From New Scientist #1452, 18th April 1985 [link]

In this puzzle dates are written in the form 17/3/08 or 9/12/72 but then the /s are deleted and the digits consistently replaced by letters, different letters represent different digits.

I was born on ENIGMA. So how old was I on EMPTY? I was __ years old (and AGE days to be precise). By the end of 1999 I shall be ON in years.

What’s the POINT?

[enigma304]

Advertisements

3 responses to “Enigma 304: Enigmatic dates

  1. Jim Randell 21 August 2015 at 8:44 am

    Initially I thought there were two solutions to this problem, but then I remembered that it was originally set in 1985.

    This Python code runs in 35ms.

    from datetime import date
    from itertools import permutations
    from enigma import irange, printf
    
    digits = set('0123456789')
    
    # ENIGMA is a six-figure date,
    # EN is a 2-figure day
    for EN in irange(10, 31):
      (E, N) = str(EN)
      if E == N: continue
    
      # IG is a 2-figure month
      for IG in (10, 12):
        (I, G) = str(IG)
        ds1 = digits.difference((E, N, I, G))
        if len(ds1) != 6: continue
    
        # MA is a 2-figure year
        for (M, A) in permutations(ds1, 2):
          ds2 = ds1.difference((M, A))
    
          # ON is the age at the end of 1999
          s = str(99 - int(M + A))
          if not(len(s) == 2 and s[1] == N): continue
          O = s[0]
          ds3 = ds2.difference((O,))
          if len(ds3) != 3: continue
    
          # P, T, Y are the remaining letters
          for (P, T, Y) in permutations(ds3):
            y = 1900 + int(T + Y)
            if y > 1985: continue
            for (d, m) in ((E + M, P), (E, M + P)):
              try:
                EMPTY = date(y, int(m), int(d))
              except ValueError:
                continue
    
              bday = date(y, IG, EN)
              if bday > EMPTY: bday = date(y - 1, IG, EN)
              
              if (EMPTY - bday).days == int(A + G + E):
                printf("POINT={P}{O}{I}{N}{T} [ENIGMA={E}{N}/{I}{G}/{M}{A} ON={O}{N} EMPTY={EMPTY} AGE={A}{G}{E}]")
    

    Solution: POINT = 85167.

    Your birth date represented by ENIGMA is 26/10/1943, and the date represented by EMPTY is 24/8/1979, on which date your age is 35 years, 302 days, and 302 corresponding to AGE. At the end of 1999 you will be 56 years old, represented by ON.

    If the puzzle had been set after 24/8/1997 then that date could be represented by EMPTY, and your age then would have been 53 years, 302 days. In this case POINT would be 85169.

    Line 33 of the program ignores solutions where EMPTY is after 1985.

  2. Brian Gladman 22 August 2015 at 5:24 pm
    from itertools import permutations, product
    from datetime import date, timedelta
    
    digits = set('0123456789')
    # publication year
    now = 1985
    
    # compose the first date (ENIGMA), noting that the
    # day, month and year all have two digits
    for dy, mn in product(range(10, 32), range(10, 13)):
      enig = str(dy) + str(mn)
      if len(set(enig)) != 4:
        continue
      for yr in range(10, now % 100):
        enigma = enig + str(yr)
        r1 = digits.difference(enigma)
        # there must now be four digits left
        if len(r1) != 4:
          continue
        E, N, I, G, M, A = enigma
        age = int(A + G + E)
        
        # find the year (which must be TY from EMPTY)
        for T, Y in permutations(digits.difference(enigma), 2):
          y = int(T + Y)
          # add AGE days to this date to form EMPTY
          d2 = date(1900 + y, mn, dy) + timedelta(days = age)
          # the day and the month for EMPTY must have 3 digits 
          # for which  E and M must match those in ENIGMA
          _E, _M, *p = str(d2.day) + str(d2.month)
          if not (_E == E and _M == M and len(p) == 1):
            continue
          P = p[0]
          
          # now find the unused digit for O
          O, *r = r1.difference([P, T, Y])
          # check that O and N give the correct age at the end of 1999
          if not r and yr + int(O + N) == 99:
            d1 = date(1900 + yr, mn, dy)
            fs = 'POINT = {} (ENIGMA {:%d/%m/%Y}, EMPTY {:%d/%m/%Y}, AGE {})'
            print(fs.format(''.join((P, O, I, N, T)), d1, d2, age))
    
  3. Brian Gladman 22 August 2015 at 10:16 pm

    Jim has kindly pointed out that the above version is flawed. In fact I mistakenly published the wrong version of my code – here is the correct version:

    from itertools import permutations, product
    from datetime import date, timedelta
    
    digits = set('0123456789')
    # publication year
    now = 1985
    
    # compose the first date (ENIGMA), noting that the
    # day, month and year all have two digits
    for dy, mn in product(range(10, 32), range(10, 13)):
      enig = str(dy) + str(mn)
      if len(set(enig)) != 4:
        continue
      for yr in range(10, now % 100):
        enigma = enig + str(yr)
        r1 = digits.difference(enigma)
        # there must now be four digits left
        if len(r1) != 4:
          continue
        E, N, I, G, M, A = enigma
        age = int(A + G + E)
        
        # find the year (which must be TY from EMPTY)
        for y in range(yr, now % 100):
          # add AGE days to this date to form EMPTY
          d2 = date(1900 + y, mn, dy) + timedelta(days = age)
          # the day and the month for EMPTY must have 3 digits 
          # for which  E and M must match those in ENIGMA
          _E, _M, *p = str(d2.day) + str(d2.month) +str(d2.year % 100)
          if not (_E == E and _M == M and len(p) == 3):
            continue
          P, T, Y = p
          
          # now find the unused digit for O
          O, *r = r1.difference([P, T, Y])
          # check that O and N give the correct age at the end of 1999
          if not r and yr + int(O + N) == 99:
            d1 = date(1900 + yr, mn, dy)
            fs = 'POINT = {} (ENIGMA {:%d/%m/%Y}, EMPTY {:%d/%m/%Y}, AGE {})'
            print(fs.format(''.join((P, O, I, N, T)), d1, d2, age))
    

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: