Enigmatic Code

Programming Enigma Puzzles

Enigma 1263: First and last

From New Scientist #2419, 1st November 2003 [link]

Last week my two Norwegian nephews, Firs and Lars, stayed with me. To make them use their English and logic I played a little game with them. I told them that I had thought of a whole number from one up to and including their sister Randum’s age. I told them that I would whisper the first letter in the English spelling of the number to Firs and the last letter to Lars (so if my number had been 1, I would have whispered “O” to Firs and “E” to Lars).

So whispered the appropriate letter to each of them and then the conversation went as follows:

Firs: “I cannot work out the number.”
Lars: “I still cannot work out the number.”
Firs: “I still cannot work out the number.”
Lars: “Now I know what it is.”
Firs: “So do I.”

How old is Randum and what number did I choose?

[enigma1263]

Advertisements

One response to “Enigma 1263: First and last

  1. Jim Randell 15 January 2015 at 8:49 am

    This Python program uses the int2words() function from the enigma.py library. It runs in 34ms.

    from itertools import count
    from collections import defaultdict
    from enigma import int2words, flatten, printf
    
    # filter words, based on letter at index i, according to fn
    def filter(ws, i, fn):
      d = defaultdict(list)
      for w in ws:
        d[w[i]].append(w)
      return flatten(v for (k, v) in d.items() if fn(v))
    
    ws = list()
    for n in count(1):
      w = int2words(n)
      ws.append(w)
    
      # F cannot work out the number
      # so the first letter must be ambiguous
      f1 = filter(ws, 0, lambda v: len(v) > 1)
      if not f1: continue
    
      # L cannot work out the number
      # so that last letter must be ambiguous
      l1 = filter(f1, -1, lambda v: len(v) > 1)
      if not l1: continue
    
      # F cannot work out the number
      # so the first letter must still be ambinguous
      f2 = filter(l1, 0, lambda v: len(v) > 1)
      if not f2: continue
    
      # L can work out the number
      # so the last letter must be unique
      l2 = filter(f2, -1, lambda v: len(v) == 1)
      if not l2: continue
    
      # F can work out the number
      # so the first letter must be unique
      f3 = filter(l2, 0, lambda v: len(v) == 1)
      if not f3: continue
    
      printf("[n={n}] f1={f1}")
      printf("[n={n}] l1={l1}")
      printf("[n={n}] f2={f2}")
      printf("[n={n}] l2={l2}")
      printf("[n={n}] f3={f3}")
    
      # determine possible choices
      cs = set(l2).intersection(f3)
    
      printf("n={n} cs={cs}")
      break
    

    Solution: Randum’s age is 12. The number chosen is 10.

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: