Enigmatic Code

Programming Enigma Puzzles

Enigma 1580: If you knew what I knew…

From New Scientist #2745, 30th January 2010 [link]

I played a little logical game with my two highly intelligent godsons, Proddy and Addy. I had in mind three different digits chosen from 1 to 8 and I whispered the product of the three to Proddy and the sum of the three to Addy. I explained all this to them and our conversation then went as follows:

Me: “Proddy, can you now work out what my three numbers are?”

Proddy: “No.”

Me: “Now do you think that Addy will be able to work out what my numbers are?”

Proddy: “No, he will not be able to work them out.”

Addy: “Now I know what the numbers are!”

What are they?

[enigma1580]

Advertisements

One response to “Enigma 1580: If you knew what I knew…

  1. jimrandell 6 February 2012 at 9:35 am

    The following Python program runs in 37ms.

    from itertools import combinations
    from collections import defaultdict
    from enigma import irange, multiply, printf
    
    # go through the possible sets of numbers and accumulate by product
    prod = defaultdict(list)
    for x in combinations(irange(1, 8), 3):
      p = multiply(x)
      # record the numbers by product and sum
      prod[p].append(x)
    
    # we are interested in the sets that do not have unique products
    sets = []
    for (p, v) in prod.items():
      if len(v) < 2: continue
      sets.extend(v)
    
    # go through the possible sets and accumulate the sums
    sums = defaultdict(list)
    for x in sets:
      s = sum(x)
      sums[s].append(x)
    
    # now examine each possible product and keep a track of ones where
    # each of the possible sums has multiple possibilities
    ans = {}
    sets = []
    for p in sorted(prod.keys()):
      v = prod[p]
      if len(v) < 2: continue
      no = True # would Proddy think Addy could determine the numbers?
      for x in v:
        s = sum(x)
        if len(sums[s]) < 2:
          no = False # if there is only 1 possibility for the sums it may be possible
          break
      ans[p] = no
      if no: sets.extend(v)
    sets = set(sets)
    
    # now, go through the products, where the answer is no,
    # and see if one of the possible sums has only one possibility
    for p in sorted(prod.keys()):
      v = prod[p]
      if len(v) < 2: continue
      if not ans[p]: continue
      for x in v:
        s = sum(x)
        i = sets.intersection(sums[s])
        if len(i) == 1:
          printf("{x} p={p} s={s}")
    

    Solution: The numbers are 2, 3 and 4.

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: