# Enigmatic Code

Programming Enigma Puzzles

## Enigma 197: Addition: letters for digits (1 letter wrong)

From New Scientist #1343, 3rd February 1983 [link]

Once more, I’m afraid, there has been a mistake in Uncle Bungle’s latest addition puzzle. In this puzzle digits have been replaced by letters and the same letter should stand for the same digit wherever it appears, and of course different letters should stand for different digits. But all is not as it should be and one of the letters is wrong. The addition sum looks like this:

Write out the correct addition sum.

[enigma197]

### 4 responses to “Enigma 197: Addition: letters for digits (1 letter wrong)”

1. Jim Randell 7 June 2014 at 7:47 am

This Python program uses the SubstitutedSum() solver from the enigma.py library. It runs in 923ms.

```from enigma import chunk, join, SubstitutedSum, printf

# terms in the sum
t = 'MXHRXEME' + 'MGHRZXGE' + 'XEHRBHXM'

# letters involved, plus a new one
letters = set(t)

# replace a character in a string
def replace(s, i, x):
return s[:i] + x + s[i + 1:]

# consider each position
for (i, x) in enumerate(t):
# try replacing the letter in this position
for y in letters:
if x == y: continue

# split the string into new terms
(a, b, c) = (join(x) for x in chunk(replace(t, i, y), 8))

# and try to solve the sum
p = SubstitutedSum([a, b], c)
for s in p.solve():
printf("position {i}: {x} -> {y} [{s}]", s=p.substitute(s, p.text))
```

Solution: The correct sum is either: 24994626 + 21098416 = 46093042, or: 24094626 + 21998416 = 46093042.

One of the H’s in the two summands should be replaced with an R giving rise to the two answers (both give the same total in the sum), but we can’t determine which one of these is the “correct” sum.

2. Hugh Casement 16 August 2014 at 2:06 pm

I notice that the pattern 46093042 corresponds to the word SLAPDASH — more appropriate in the context of the puzzle than the meaningless jumble of letters used by the setter.

3. Jim Randell 30 May 2017 at 5:42 pm

Here’s a solution that uses MiniZinc. I’ve used the minizinc.py wrapper to make it simpler to generate the model. This Python 3.6 program executes in 397ms (using the [[ mzn-g12fd ]] solver – I found quite a wide variation in the run times (and accuracy) of the various solvers, but this one was the quickest, and gave the correct result).

```from enigma import substitute
from minizinc import MiniZinc, var, alphametic

p = MiniZinc(f"""

include "globals.mzn";

% the symbols in the incorrect sum
{var("0..9", "BEGHMRXZ")};

constraint all_different([B, E, G, H, M, R, X, Z]);

% make a new sum: abcdefgh + ijkmnpqr = stuvwxyz
{var("0..9", "abcdefghijkmnpqrstuvwxyz")};

constraint a != 0 /\ i != 0 /\ s != 0;

% the new sum is a correct alphametic sum
constraint {alphametic("{abcdefgh} + {ijkmnpqr} = {stuvwxyz}")};

% and differs from the original incorrect sum in only one place
constraint sum([
a != M, b != X, c != H, d != R, e != X, f != E, g != M, h != E,
i != M, j != G, k != H, m != R, n != Z, p != X, q != G, r != E,
s != X, t != E, u != H, v != R, w != B, x != H, y != X, z != M
]) = 1;

solve satisfy;

""")

for s in p.solve(solver="mzn-g12fd -a"):
print(substitute(s, "abcdefgh + ijkmnpqr = stuvwxyz"))
```
4. geoffrounce 30 May 2017 at 9:07 pm

I used your idea of a substituted sum in your wrapper to see what it would look like in standard MiniZinc code. The fastest run-time I got was 309 msec – this varied a lot depending which solver I used.

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

% letters in original sum
var 0..9:B;  var 0..9:E;  var 0..9:G;  var 0..9:H;  var 0..9:M;
var 0..9:R;  var 0..9:X;  var 0..9:Z;

constraint all_different([B, E, G, H, M, R, X, Z]);

set of int: Digit = 0..9;

% new variable abcdefgh
var Digit: a; var Digit: b; var Digit: c; var Digit: d; var Digit: e;
var Digit: f; var Digit: g; var Digit: h;

% new variable ijkmnpqr
var Digit: i; var Digit: j; var Digit: k;  var Digit: m; var Digit: n;
var Digit: p; var Digit: q; var Digit: r;

% new variable stuvwxyz
var Digit: s; var Digit: t; var Digit: u; var Digit: v; var Digit: w;
var Digit: x; var Digit: y; var Digit: z;

% no leading zeros for three new variables
constraint a != 0 /\ i != 0 /\ s != 0;

var 10000000..99999999: abcdefgh = h + 10*g + f*pow(10,2) + e*pow(10,3)
+ d*pow(10,4) + c*pow(10,5) + b*pow(10,6) + a*pow(10,7);

var 10000000..99999999: ijkmnpqr = r + 10*q + p*pow(10,2) + n*pow(10,3)
+ m*pow(10,4) + k*pow(10,5) + j*pow(10,6) + i*pow(10,7);

var 10000000..99999999: stuvwxyz = z + 10*y + x*pow(10,2) + w*pow(10,3)
+ v*pow(10,4) + u*pow(10,5) + t*pow(10,6) + s*pow(10,7);

% new sum
constraint abcdefgh + ijkmnpqr = stuvwxyz;

% new sum differs from the original incorrect sum in only one place
constraint sum([
a != M, b != X, c != H, d != R, e != X, f != E, g != M, h != E,
i != M, j != G, k != H, m != R, n != Z, p != X, q != G, r != E,
s != X, t != E, u != H, v != R, w != B, x != H, y != X, z != M
]) = 1;

solve satisfy;

output [ show(abcdefgh) ++ " + " ++ show(ijkmnpqr) ++ " = " ++ show(stuvwxyz) ];

% Output
% 24994626 + 21098416 = 46093042
% 24094626 + 21998416 = 46093042
% ----------
% Finished in 309msec with G12 fd solver

% Finished in 14s 776msec with the Chuffed (bundled) solver
% Still running at 45 min with Geocode solver
```