# Enigmatic Code

Programming Enigma Puzzles

## Enigma 394: Unwinding

From New Scientist #1544, 22nd January 1987 [link]

Professor Kugelbaum was unwinding at the Maths Club with a cigar after lunch when a wild-looking man burst in and introduced himself thus:

“My name is TED MARGIN. Juggling with the letters of my name one obtains both GREAT MIND and GRAND TIME. But I digress. Each letter of my name stands for one digit exactly from 1 to 9 inclusive and vice versa. And, do you know,

(A × R × M) / (A + R + M) = 2,

MAD is greater than ART (though RAT is greater than either), and TED = MAR + GIN.

If, in addition, I were to tell you the digit which corresponds to M then you could deduce the one-to-one correspondence between the letters of my name and the digits 1 to 9″.

At this point a helpful butler removed the man, but Kugelbaum was amused to find that the information was quite consistent.

Write the digits 1 to 9 in the alphabetical order of the letters to which they correspond.

[enigma394]

### 5 responses to “Enigma 394: Unwinding”

1. Jim Randell 5 May 2017 at 8:32 am

We can solve this puzzle using a couple of routines from the enigma.py library. First the SubstitutedExpression() solver is used to solve the alphametic expressions, then filter_unique() to find solutions that give a unique answer by the value of M.

This Python 2 program runs in 48ms.

```from enigma import SubstitutedExpression, irange, filter_unique, printf

# the alphametic puzzle
p = SubstitutedExpression(
[ "2 * (A + R + M) == A * R * M", "R > M", "M > A", "MAR + GIN = TED" ],
digits=irange(1, 9),
)

# find solutions with a unique value of M
# the solve() function provides us with a sequence of (<dict>, <answer>) pairs
# we require the answer be unique by the value of M in the dictionary
(r, _) = filter_unique(p.solve(verbose=1), (lambda (d, a): d['M']), (lambda (d, a): a))

# output solutions
for (d, a) in r:
```

There are 4 further solutions where M = 3:

The program can be adapted to run under Python 3 by using the unpack() function (from the enigma.py library) when constructing the functions to be passed to filter_unique(). Line 13 becomes:

```(r, _) = filter_unique(p.solve(verbose=1), unpack(lambda d, a: d['M']), unpack(lambda d, a: a))
```
2. geoffrounce 5 May 2017 at 4:37 pm

I found a MiniZinc solution by setting the configuration to multiple outputs and examining the outputs to find a unique answer with M = 4, giving the solution. Four other values with M = 3 were also found.

```% A Solution in MiniZinc
include "globals.mzn";

var 1..9:T;  var 1..9:E;  var 1..9:D;  var 1..9:M; var 1..9:A;
var 1..9:R;  var 1..9:G;  var 1..9:I;  var 1..9:N;

constraint alldifferent([T,E,D,M,A,R,G,I,N]);

var 100..999: MAD = 100*M + 10*A + D;
var 100..999: ART = 100*A + 10*R + T;
var 100..999: RAT = 100*R + 10*A + T;
var 100..999: TED = 100*T + 10*E + D;
var 100..999: MAR = 100*M + 10*A + R;
var 100..999: GIN = 100*G + 10*I + N;

constraint (A * R * M) = 2 * (A + R + M) ;
constraint (RAT > ART) /\ (RAT > MAD) ;
constraint TED = MAR + GIN;

solve satisfy;

% show answer with letters in alphabetical order
output [ " A, D, E, G, I, M, N, R, T = " ++ show([A, D, E, G, I, M, N, R, T]) ];

% A, D, E, G, I, M, N, R, T = [1, 3, 9, 2, 7, 4, 8, 5, 6] << M = 4 is unique

% Other values for M = 3
% A, D, E, G, I, M, N, R, T = [1, 7, 6, 2, 4, 3, 9, 8, 5]
% A, D, E, G, I, M, N, R, T = [1, 4, 9, 2, 7, 3, 6, 8, 5]
% A, D, E, G, I, M, N, R, T = [1, 5, 4, 6, 2, 3, 7, 8, 9]
% A, D, E, G, I, M, N, R, T = [1, 2, 7, 6, 5, 3, 4, 8, 9]
% Finished in 139msec

```
• geoffrounce 7 May 2017 at 8:36 am

A Python 3 permutation solution found the answer in 16 msec, with a total run-time of 95 msec.

```from itertools import permutations

fstr = 'A={}, D={}, E={}, G={}, I={}, M={}, N={}, R={}, T={}'
digits = set(range(1,10))

for p1 in permutations(range(1,10),3):
a, r, m = p1
if a * r * m == 2 * (a + r + m):
q = digits.difference((a, r, m))
for p2 in permutations(q):
d, e, g, i, n, t = p2
mad, art = 100*m + 10*a + d, 100*a + 10*r + t
rat = 100*r + 10*a + t
if rat > mad and rat > art:
ted = 100*t + 10*e + d
mar, gin = 100*m + 10*a + r, 100*g +10*i + n
if ted == mar + gin:
print(fstr.format(a, d, e, g, i, m, n, r, t))

# A=1, D=3, E=9, G=2, I=7, M=4, N=8, R=5, T=6   <<< the answer
# A=1, D=2, E=7, G=6, I=5, M=3, N=4, R=8, T=9
# A=1, D=4, E=9, G=2, I=7, M=3, N=6, R=8, T=5
# A=1, D=5, E=4, G=6, I=2, M=3, N=7, R=8, T=9
# A=1, D=7, E=6, G=2, I=4, M=3, N=9, R=8, T=5
```

A Visual Basic (Visual Studio 2017) solution took a lot more coding to loop all the variables and test for different variable values. Output was to a console screen, which seemed a bit of a retro look.

```Module Module1

Sub Main()
Dim a, d, e, g, i, m, n, r, t As Integer
Dim mad, art, rat, ted, mar, gin As Integer

For a = 1 To 9
For r = 1 To 9
If r = a Then Continue For
For m = 1 To 9
If m = r Or m = a Then Continue For
If a * r * m = 2 * (a + r + m) Then
For t = 1 To 9
If t = m Or t = r Or t = a Then Continue For
For d = 1 To 9
If d = t Or d = m Or d = r Or d = a Then Continue For
mad = 100 * m + 10 * a + d
art = 100 * a + 10 * r + t
If mad <= art Then Continue For
rat = r * 100 + 10 * a + t
If rat > mad And rat > art Then
For e = 1 To 9
If e = d Or e = t Or e = m Or e = r Or e = a Then Continue For
For g = 1 To 9
If g = e Or g = d Or g = t Or g = m Or g = r Or g = a Then Continue For
For i = 1 To 9
If i = g Or i = e Or i = d Or i = t Or i = m Or i = r Or i = a Then Continue For
For n = 1 To 9
If n = i Or n = g Or n = e Or n = d Or n = t Or n = m Or n = a Then Continue For
ted = 100 * t + 10 * e + d
mar = 100 * m + 10 * a + r
gin = 100 * g + 10 * i + n
If ted = mar + gin Then
Console.WriteLine("a, d, e, g, i, m, n, r, t = {0} {1} {2} {3} {4} {5} {6} {7} {8} " _
, a, d, e, g, i, m, n, r, t)
End If
Next
Next
Next
Next
End If
Next
Next
End If
Next
Next
Next
End Sub

' OUTPUT
'-------
'a, d, e, g, i, m, n, r, t = 1 3 9 2 7 4 8 5 6   <<< the answer
'a, d, e, g, i, m, n, r, t = 1 4 9 2 7 3 6 8 5
'a, d, e, g, i, m, n, r, t = 1 7 6 2 4 3 9 8 5
'a, d, e, g, i, m, n, r, t = 1 2 7 6 5 3 4 8 9
'a, d, e, g, i, m, n, r, t = 1 5 4 6 2 3 7 8 9

End Module
```
3. Brian Gladman 5 May 2017 at 5:53 pm
```from collections import defaultdict
from itertools import combinations, permutations
from functools import reduce

# convert a sequence of digits to a number
dgts2nbr = lambda *seq: reduce(lambda x, y: 10 * x + y, seq)

sol = defaultdict(list)
# start with A, M and R with A < M < R and A.R.M = 2.(A + R + M)
for A, R in combinations(range(1, 10), 2):
if A * R > 2:
M, r = divmod(2 * (A + R), A * R - 2)
if not r and A < M < R:
s1 = set(range(1, 10)).difference([A, R, M])
# allocate remaining digits to remaining letters
for D, E, G, I, N, T in permutations(s1):
# find solutions with TED = MAR + GIN
if dgts2nbr(T, E, D) == dgts2nbr(M, A, R) + dgts2nbr(G, I, N):
sol[M].append((A, D, E, G, I, M, N, R, T))

# look for a solution that is unique given M
for m, t in sol.items():
if len(t) == 1:
print(f'(A, D, E, G, I, M, N, R, T) ==> {t[0]}')
```
4. Jim Randell 7 May 2017 at 12:10 pm

In a permutations() based approach, once we have determined values for A, M, R we don’t need to consider all 720 possible permutations of the remaining six digits for D, E, G, I, N, T, instead we can get away looking at the 120 possible values of just T, E, D (or G, I, N) and check that the values for the remaining three letters, computed from TED = MAR + GIN, consist of the remaining 3 digits.

```from itertools import permutations
from collections import defaultdict
from enigma import irange, nconcat, nsplit, printf

ss = defaultdict(list)

# A < M < R
for A in irange(1, 7):
for R in irange(A + 2, 9):
d = A * R - 2
if d < 1: continue
(M, r) = divmod(2 * (A + R), d)
if r != 0: continue
if not(A < M < R): continue

# choose letters for T, E, D
MAR = nconcat(M, A, R)
for (T, E, D) in permutations(set(irange(1, 9)).difference((A, M, R)), 3):
TED = nconcat(T, E, D)
# compute G, I, N
GIN = TED - MAR
if GIN < 123: continue
(G, I, N) = nsplit(GIN)
if I == 0 or N == 0: continue
s = (A, D, E, G, I, M, N, R, T)
if len(set(s)) != 9: continue
# record solutions by the value of M
printf("A={A} M={M} R={R}, T={T} E={E} D={D}, G={G} I={I} N={N}")
ss[M].append(s)

# output solutions unique by the value of M
for (M, vs) in ss.items():
if len(vs) == 1:
printf("M={M} => {vs[0]}")
```

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