# Enigmatic Code

Programming Enigma Puzzles

## Enigma 327: It all adds up

From New Scientist #1475, 26th September 1985 [link]

Below is an addition sum with letters substituted for digits. The same letter stands for the same digit wherever it appears, and different letters stand for different digits.

Write out the sum with numbers substituted for letters.

[enigma327]

### 8 responses to “Enigma 327: It all adds up”

1. Jim Randell 8 January 2016 at 9:29 am

This is another problem that can be fed directly into the SubstitutedSum() solver from the enigma.py library.

This Python program runs in 52ms.

```from enigma import SubstitutedSum

```

Solution: 1912803 + 2428850 + 4312835 = 8654488.

Instead of writing individual programs for such problems, I have added code to the enigma.py library that allows you call the SubstitutedSum() solver directly from the command line. This kind of problem can now be solved directly by just passing the parameters as command line arguments:

```% python enigma.py SubstitutedSum "KBKGEQD + GAGEEYQ + ADKGEDY = EXYAAEE"
KBKGEQD + GAGEEYQ + ADKGEDY = EXYAAEE)
(1912803 + 2428850 + 4312835 = 8654488) / A=4 B=9 D=3 E=8 G=2 K=1 Q=0 X=6 Y=5
```
2. geoffrounce 8 January 2016 at 11:15 am

Here is a MiniZinc solution;

```include "globals.mzn";

var 0..9:K;   var 0..9:B;  var 0..9:G;
var 0..9:E;   var 0..9:Q;  var 0..9:A;
var 0..9:D;   var 0..9:Y;  var 0..9:X;

constraint K != 0 /\ G!= 0 /\ A != 0 /\ E != 0;

constraint alldifferent([K,B,G,E,Q,A,D,Y,X]);

constraint
(K * pow(10,6) + B * pow(10,5) + K * pow(10,4) + G * 1000
+ E * 100 + Q * 10 + D) +
(G * pow(10,6) + A * pow(10,5) + G * pow(10,4) + E * 1000
+ E * 100 + Y * 10 + Q) +
(A * pow(10,6) + D * pow(10,5) + K * pow(10,4) + G * 1000
+ E * 100 + D * 10 + Y) ==
(E * pow(10,6) + X * pow(10,5) + Y * pow(10,4) + A * 1000
+ A * 100 + E * 11);

solve satisfy;

output [show(K),show(B),show(K),show(G),show(E),show(Q),show(D)," + ",
show(G),show(A),show(G),show(E),show(E),show(Y),show(Q)," + ",
show(A),show(D),show(K),show(G),show(E),show(D),show(Y)," = ",
show(E),show(X),show(Y),show(A),show(A),show(E),show(E)];

% Output
% 1912803 + 2428850 + 4312835 = 8654488
```
3. geoffrounce 9 January 2016 at 1:37 pm

Easier to programme as a Python permutation solution, but not as fast as MiniZinc

```from itertools import permutations

for p in permutations('1234567890',9):
k,b,g,e,q,a,d,y,x = p
if k == 0 or g == 0 or a == 0 or e == 0: continue
num1 = int(k + b + k + g+ e + q + d)
num2 = int(g + a + g + e + e + y + q)
num3 = int(a + d + k + g + e + d + y)
ans = int(e + x + y + a + a + e + e)
if num1 + num2 + num3 == ans:
print(num1, '+', num2, ' + ', num3, ' = ', ans)
break    # we are only looking for one sum

# 1912803 + 2428850  +  4312835  =  8654488
```
4. liam 9 January 2016 at 3:18 pm

Hi so I had a go at the problem (sorry I’m quite new to python lol!!) and I made this

```for k in range(10):
for b in range(10):
if b != k:
for g in range(10):
if g != k and g != b:
for e in range(10):
if e != k and e != b and e != g:
for q in range(10):
if q != k and q != b and q != g and q != e:
for d in range(10):
if d != k and d != b and d != g and d != e and d != q:
for a in range(10):
if a != k and a != b and a != g and a != e and a != q and a != d:
for y in range(10):
if y != k and y != b and y != g and y != e and y != q and y != d and y != a:
for x in range(10):
if x != k and x != b and x != g and x != e and x != q and x != d and x != a and x != y:
if 1000000*k + 100000*b + 10000*k + 1000*g + 100*e + 10*q + d + 1000000*g + 100000*a + 10000*g + 1000*e + 100*e + 10*y + q + 1000000*a + 100000*d + 10000*k + 1000*g + 100*e + 10*d + y == 1000000*e + 100000*x + 10000*y + 1000*a + 100*a + 10*e + e:
print str(k) + str(b) + str(k) + str(g) + str(e) + str(q) + str(d) + " + " + str(g) + str(a) + str(g) + str(e) + str(e) + str(y) + str(q) + " + " + str(a) + str(d) + str(k) + str(g) + str(e) + str(d) + str(y) + " = " + str(e) + str(x) + str(y) + str(a) + str(a) + str(e) + str(e)
```

but it seems to be running a bit slowly can anyone help me??? Thanks again for the help!!

• Jim Randell 9 January 2016 at 4:20 pm

Hi Liam – Welcome to Enigmatic Code.

Your program produces the right answer, and on my machine it runs in about 1.2s (using PyPy 4.0.1, or about 19.4s using the standard Python 2.7.11 interpreter). The reason it’s slow is the simplicity of the algorithm. The nested for loops construct all possible assignments of the digits to the letters, so the test at line 18 is evaluated 3,628,800 times (= factorial(10)).

Three years ago, after coding up a solution to Enigma 63 – a similar problem – (using Python’s itertools.permutations() to generate all possible assignments of letters to digits), I decided to write a generic solver for such puzzles to save me the bother of having to write a custom program each time. (Puzzles like this were quite popular in early Enigmas). I ended up with a more sophisticated algorithm that does many fewer tests, and I’ve incorporated that into the SubstitutedSum() solver in the enigma.py library. On this problem it runs about 1000× faster than your program (using the standard Python interpreter).

• liam 9 January 2016 at 6:05 pm

Oh gosh I feel a bit slow now – who knew we we’re supposed to build fast programs and not just simple programmes! gosh 1000 x faster I see I have a lot of learning to do! I’m quite new to all this python stuff, sorry haha. Although I suppose if you’ve already written a computer to solve all these sorts of problems there’s not much point me writing one!! I’ll have a go at some of the other problems here then, thanks again for the help!

• fisty frodo 9 January 2016 at 10:27 pm

I love your code. For me it symbolises a lot of my feelings about programming as an art form: a perfect merging of mechanical beauty and gritty complexity. Sure, it’s not concise, but it exaggerates and elucidates the actual physicality of what is required to calculate a solution. Bravissimo.

• liam 10 January 2016 at 10:20 am

Haha gosh that’s so nice of you fisty frodo (or should I call you fisty?) theres clearly a fierce debate here lol! You used some difficult words, but I think I know what you meant! Bravissimo is Spanish right? Yeah so maybe it’s time for programmers to write computers that are not fast but sort of more simple and I’m sure people would appreciate that! Thanks again!