# 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?

[enigma1197]

### 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
```

This site uses Akismet to reduce spam. Learn how your comment data is processed.