Enigmatic Code

Programming Enigma Puzzles

Enigma 1445: Count in German

From New Scientist #2606, 2nd June 2007

In the following statements digits have been consistently replaced by capital letters, different letters being used for different digits.

ZWEI is a prime number, DREI is a triangular number, VIER is a perfect square.

Triangular numbers are those that fit the formula n(n+1)/2, like 1, 3, 6 and 10.

What are the numbers represented by (a) DREI and (b) VIER?

[enigma1445]

Advertisements

4 responses to “Enigma 1445: Count in German

  1. Jim Randell 31 March 2013 at 10:09 am

    This Python program runs in 44ms.

    from itertools import permutations
    from collections import defaultdict
    from enigma import irange, is_duplicate, is_triangular, concat, Primes, printf
    
    # possible digits
    ds = set('0123456789')
    
    # primes
    primes = Primes(10000)
    
    # record solutions
    r = defaultdict(set)
    
    # VIER is a 4-digit square with distinct digits
    for i in irange(32, 99):
      VIER = str(i * i)
      if is_duplicate(VIER): continue
      (V, I, E, R) = VIER
      # ZWEI is prime, so I is 1, 3, 7, 9
      if I not in '1379': continue
    
      # DREI is a triangular number
      for D in ds.difference((V, I, E, R, '0')):
        DREI = int(concat(D, R, E, I))
        if not is_triangular(DREI): continue
    
        # ZWEI is a prime number
        for (Z, W) in permutations(ds.difference((V, I, E, R, D)), 2):
          if Z == '0': continue
          ZWEI = int(concat(Z, W, E, I))
          if ZWEI not in primes: continue
    
          r[(VIER, DREI)].add(ZWEI)
          printf("[ZWEI={ZWEI} DREI={DREI} VIER={VIER}]")
    
    # output results
    for (k, v) in r.items():
      printf("DREI={k[1]} VIER={k[0]} [ZWEI={v}]")
    

    Solution: (a) DREI=1653; (b) VIER=4356.

  2. geoffrounce 31 March 2013 at 10:44 am

    Here is my solution. It gives 7 different answers for ZWEI, which is presumably why the teaser setter only asked for answers for DREI and VIER:

    DREI VIER ZWEI = 1653 4356 2753
    DREI VIER ZWEI = 1653 4356 2953
    DREI VIER ZWEI = 1653 4356 2053
    DREI VIER ZWEI = 1653 4356 7253
    DREI VIER ZWEI = 1653 4356 7853
    DREI VIER ZWEI = 1653 4356 8753
    DREI VIER ZWEI = 1653 4356 8053

    def is_tri(x):
        t = 8 * x + 1
        u = int((8 * x + 1) ** 0.5 + 0.5)
        return t == u ** 2
    
    def is_prime(n): 
        for x in range(2, int(n**0.5)+1): 
            if n % x == 0: 
                return False 
        return True
    
    def is_sq(n): 
        for a in range(2, int(n**0.5)+1): 
            if a * a == n: 
                return True 
        return False
    
    from itertools import permutations
    for p in permutations((1,2,3,4,5,6,7,8,9,0),7):
        d,r,e,i,z,w,v = p
        if all(x !=0 for x in (d,v,z)):
            drei = i + 10*e + 100*r + 1000*d
            zwei = i + 10*e + 100*w + 1000*z
            vier = r + 10*e + 100*i + 1000*v
            if is_prime(zwei) and is_tri(drei) and is_sq(vier):
                print('DREI VIER ZWEI = ', drei,vier,zwei)
    
  3. Naim Uygun 31 March 2013 at 1:40 pm

    I agree with geoffrounce. My Python program:

    from itertools import permutations
    for z,w,e,i,d,r,v in permutations("9876543210",7):
        zwei=int("".join((z,w,e,i)))
        rz=int(zwei**0.5+2)
        durum=True
        for q in range(2,rz):
            if zwei%q==0:
                durum=False
                break
        if durum==True:
            vier=int("".join((v,i,e,r)))
            rv=vier**0.5
            if rv !=int(rv): continue
            drei= int("".join((d,r,e,i)))
            root=(-1+(1+8*drei)**0.5)/2
            if root == int(root):
                print("(a) DREI=",drei," (b) VIER=",vier)
                break
    
  4. arthurvause 31 March 2013 at 8:35 pm

    Another approach:

    primesbelow100 = set(x for x in range(11,100,2)
                         if all(x%p for p in (2,3,5,7))) | set((2,3,5,7))
    p4d = [x for x in range(1001,10000,2)
           if all(x%p for p in primesbelow100)
           and len(set(str(x)))==4]
    tr = [(n*(n+1))/2 for n in xrange(45,141) if len(set(str(n*n)))==4]
    sq =[n*n for n in xrange(32,100) if len(set(str(n*n)))==4]
    
    print set([ (DREI,VIER) for (ZWEI,DREI,VIER) in
              ( (ZWEI,DREI,VIER) for ZWEI in p4d for DREI in tr for VIER in sq
               if ZWEI%100==DREI%100
               and str(DREI%1000)==str(VIER%1000)[::-1]
               and len(set(str(ZWEI)+str(DREI)+str(VIER)))==7 )])
    

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: