Enigmatic Code

Programming Enigma Puzzles

Enigma 1197: Nombres triangulaires

From New Scientist #2353, 27th July 2002 [link]

Triangular numbers are those that fit the formula ½n(n+1), such as 1, 3, 6 and 10.

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

UN, TROIS, SIX, and DIX are all triangular numbers, none of which starts with a zero.

Which numbers are represented by (in this order) UN, TROIS, SIX and DIX?

See also Enigma 1300.

[enigma1197]

Advertisements

3 responses to “Enigma 1197: Nombres triangulaires

  1. Jim Randell 19 October 2015 at 8:53 am

    This Python program runs in 33ms.

    from collections import defaultdict
    from itertools import permutations
    from enigma import irange, T as tri, is_duplicate, split, printf
    
    # return a dict of triangular numbers from T[a] to T[b]
    # (with no repeated digits) grouped by the residue mod m
    def tris(a, b, m=100):
      ts = defaultdict(list)
      for i in irange(a, b):
        t = tri(i)
        if is_duplicate(t): continue
        ts[t % m].append(t)
      return ts
    
    # two digit triangular numbers (we don't need the grouping)
    t2s = tris(4, 13).keys()
    
    # three digit triangular numbers (grouped by the final 2 digits)
    t3s = tris(14, 44)
    
    # five digit triangular numbers (grouped by the final 2 digits)
    t5s = tris(141, 446)
    
    # find values for SIX and DIX
    for (k, vs) in t3s.items():
      if len(vs) < 2: continue
      (I, X) = divmod(k, 10)
    
      for (SIX, DIX) in permutations(vs, 2):
        (S, D) = (SIX // 100, DIX // 100)
    
        # find value for TROIS
        for TROIS in t5s[I * 10 + S]:
          (T, R, O, _, _) = split(TROIS, int)
    
          # find value for UN
          for UN in t2s:
            (U, N) = split(UN, int)
            if len(set((U, N, T, R, O, I, S, X, D))) != 9: continue
    
            printf("UN={UN} TROIS={TROIS} SIX={SIX} DIX={DIX}")
    

    Solution: UN=45, TROIS=39621, SIX=120, DIX=820.

  2. Brian Gladman 19 October 2015 at 1:44 pm
    from collections import defaultdict
    from itertools import count, permutations
    
    # for two, three and five digit triangular numbers
    tri, tr2, tr3, tr5 = 0, [], defaultdict(list), defaultdict(list)
    for i in count(1):
      tri += i
      if tri >= 100000:
        break
      if 10 <= tri < 100:
        # collect two digit triangular numbers
        tr2.append(tri)
      elif tri < 1000:
        # collect three digit triangular numbers indexed 
        # on their lower two digits
        tr3[tri % 100].append(tri)
      elif tri >= 10000:
        # collect five digit triangular numbers indexed 
        # on their lower two digits
        tr5[tri % 100].append(tri)
    
    # consider all pairs of three digit triangular numbers
    # that share the same lower two digits
    for ix in list(tr3.keys()):
      I, X = divmod(ix, 10)
      for six, dix in permutations(tr3[ix], 2):
        # extract and check that S, D, I and X are all different
        S, D = six // 100, dix // 100
        if len(set((S, D, I, X))) == 4:
          
          # check possible values for TROIS
          for trois in tr5[10 * I + S]:
            # extract T, R and O
            tr, O = divmod(trois // 100, 10)
            T, R = divmod(tr, 10)
            s7 = set((T, R, O, S, D, I, X))
            # check that we have seven different values
            if len(s7) == 7:
          
              # now find a compatible value for UN
              for un in tr2:
                s = set(divmod(un, 10))
                if len(s) == 2 and not s & s7:
                  fs = 'UN = {}, TROIS = {}, SIX = {} and DIX = {}'
                  print(fs.format(un, trois, six, dix))
    
  3. geoffrounce 27 October 2015 at 8:38 pm
    from enigma import is_triangular
    from itertools import permutations
    
    for p in permutations('1234567890',9):
      u, n, t, r, o, i, s, x, d = p
      if u == '0' : continue
      un = int(u + n)
      if is_triangular (un) is not None:
        if t == '0': continue
        trois = int(t + r + o + i + s)
        if is_triangular(trois) is not None:
          if s == '0' : continue
          six = int(s + i + x)
          if is_triangular(six) is not None:
            if d == '0' : continue
            dix = int(d + i + x)
            if is_triangular(dix) is not None:
              print('UN = {}, TROIS = {}, SIX = {}, DIX = {}'.format(un,trois,six,dix))
              
    # UN = 45, TROIS = 39621, SIX = 120, DIX = 820
    

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: