Enigmatic Code

Programming Enigma Puzzles

Enigma 1706: Festival figures

From New Scientist #2873, 14th July 2012 [link]

In 1951 the Festival of Britain was held, with three main features at the exhibition site – the Dome of Discovery, the Skylon and the Royal Festival Hall. This inspired me to write down three positive whole numbers; altogether they use nine digits, with no digit repeated. One of the numbers is a perfect square and the other two are primes. They add up to 1951.

What, in increasing order, are my three numbers?

[enigma1706]

Advertisements

4 responses to “Enigma 1706: Festival figures

  1. Jim Randell 11 July 2012 at 5:34 pm

    The following Python program uses the prime sieve from my enigma.py library. It runs in 45ms.

    from enigma import Primes, is_duplicate, irange, concat, printf
    
    # possible values for the square
    squares = set(x for x in (i * i for i in irange(1, 44)) if not is_duplicate(x))
    
    # accumulate possible primes
    primes = list()
    for p2 in Primes(1951):
      if is_duplicate(p2): continue
      # and possible values for the smaller prime
      for p1 in primes:
        s = 1951 - (p1 + p2)
        if s < 0: break
        if s not in squares: continue
        t = concat(p1, p2, s)
        if not(len(t) == 9 and len(set(t)) == 9): continue
        printf("p1={p1} p2={p2} s={s}")
      primes.append(p2)
    

    Solution: The three numbers are 487, 503 and 961.

  2. Brian Gladman 11 July 2012 at 8:18 pm

    Here is my effort:

    # There is at most one 4 digit number and the other two
    # numbers would then have 2 and 3 digits. Otherwise all
    # three numbers must have 3 digits.  So the primes have
    # at least 2 digits and their sum is hence even. So the
    # square must be odd and have at least two digits.
    
    # filter out integers with duplicate digits
    def unique(x):
      for n in x:
        s = str(n)
        if len(s) == len(set(s)):
          yield n
    
    # create a list of primes 10 < pr < 1951 with no duplicate digits
    pr = [2, 3, 5, 7]
    pr += [x for x in range(11,51,2) if all(x % p for p in pr)]
    pr = [x for x in unique(range(11,1951,2)) if all(x % p for p in pr)]
    
    # candidate odd squares with at least 2 digits < 1951 
    for s in unique(x * x for x in range(5, 45, 2)):
      ss = set(str(s))
      for p1 in pr:
        # check if remainder is prime 
        p2 = 1951 - s - p1
        if p2 < p1:
          break
        if p2 in pr:
          # check for numbers with 9 different digits
          s1, s2 = set(str(p1)), set(str(p2))
          if not ((s1 & s2) or ss & (s1 | s2)):
            if len(ss | s1 | s2) == 9:
              print(tuple(sorted((s, p1, p2))))
    
  3. Naim Uygun 11 July 2012 at 8:38 pm

    Greetings Brian,
    You have done good and understandable work.
    Your program gives the triples numbers for the sums 1951, 1453, 1881 correctly when I try it for each.
    How can one modified your program to output the triple numbers for any sum, if possible,
    for the same enigma (two primes, one perfect number, 9 different digits, no same digit).

    • Brian Gladman 11 July 2012 at 9:13 pm

      The best way to do this depends on how big the sum can be. If it has to be up to 9 digits, my simple prime sieve would have to be changed to give much larger primes. Apart from this the various fixed limits would need to be set from the sum value (the limits are hard coded right now). This would be easy if the maximum sum allowed was not too large.

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: