Enigmatic Code

Programming Enigma Puzzles

Enigma 367: Spilt ink

From New Scientist #1516, 10th July 1986 [link]

Uncle Bungle has been making up another long division sum with letters substituted for digits, and those who know him well — as I do — will not be surprised to hear that all was not as it should be. Being rather old-fashioned he still uses ink, and being rather careless he has spilt it so that some of the letters were, I’m afraid, quite illegible. What can be read can be seen below, and I am glad to say that what is left is as it should be; that is, each letter stands for a different digit:

Rewrite the complete sum with letters and blanks replaced by digits.

[enigma367]

2 responses to “Enigma 367: Spilt ink”

1. Jim Randell 21 October 2016 at 8:27 am

We can use the [[ `SubstitutedDivision()` ]] solver from the enigma.py library to solve this problem in one line. Instead of writing a program to do the call we can invoke it directly from the command line. Here’s the command and its output:

```% python -m enigma SubstitutedDivision "trm?d / sm = txs" "trm - pkx = kt" "kt? - hx? = x?" "x?d - khx = ks"
[solving trm?d / sm = txs, [('trm', 'pkx', 'kt'), ('kt?', 'hx?', 'x?'), ('x?d', 'khx', 'ks')] ...]
20883 / 78 = 267 rem 57 [d=3 h=4 k=5 m=8 p=1 r=0 s=7 t=2 x=6] [208 - 156 = 52, 528 - 468 = 60, 603 - 546 = 57]
```

This runs in 80ms.

Solution: The complete sum is: 20883 / 78 = 267 remainder 57.

We can also use the generalised alphametic solver ([[ `SubstitutedExpression()` ]]) from the enigma.py library.

We introduce the symbols ABC to stand for the illegible letters (they are inserted as AABC, reading from top to bottom in the diagram). Which gives us the following run file:

```# solver to use
SubstitutedExpression

# solver options
--symbols="dhkmprstxABC"
--distinct="dhkmprstx"

# the division sum
"txs * sm + ks = trmAd"

# the multiples
"t * sm = pkx"
"x * sm = hxB"
"s * sm = khx"

# the intermediate subtraction sums
"trm - pkx = kt"
"ktA - hxB = xC"
"xCd - khx = ks"
```

Which we can run like this to get the same solution:

```% python -m enigma -r enigma367.run
(txs * sm + ks = trmAd) (t * sm = pkx) (x * sm = hxB) (s * sm = khx) (trm - pkx = kt) (ktA - hxB = xC) (xCd - khx = ks)
(267 * 78 + 57 = 20883) (2 * 78 = 156) (6 * 78 = 468) (7 * 78 = 546) (208 - 156 = 52) (528 - 468 = 60) (603 - 546 = 57) / A=8 B=8 C=0 d=3 h=4 k=5 m=8 p=1 r=0 s=7 t=2 x=6
[1 solution]
```

This runs in 76ms.

The [[ `SubstitutedExpression()` ]] solver uses a heuristic to choose the number of symbols it has to consider values for. In this case it only needs to look at s, m, and t, the values of the remaining symbols can be derived. The same approach can be used to solve the program manually (or indeed, programatically).

2. Brian Gladman 21 October 2016 at 4:25 pm
```from itertools import permutations

# allocate the symbols needed to complete the division
for k, m, s, t, x in permutations(range(10), 5):

# form the divisor, the dividend and the remainder
sm, txs, ks = 10 * s + m, 100 * t + 10 * x + s, 10 * k + s

# form and check the quotient and its digits where necessary
trm_d = sm * txs + ks
try:
_t, r, _m, _1, d = (int(x) for x in str(trm_d))
except ValueError:
continue
s1 = set((d, k, m, r, s, t, x))
if _t != t or _m != m or len(s1) != 7:
continue

# now form and check the first partial product
pkx = sm * t
try:
p, _k, _x = (int(c) for c in str(pkx))
except ValueError:
continue
if not (_x == x and _k == k and 0 < p < 10 and p not in s1):
continue

# check the remaining partial products
kt_, hx_ = 100 * k + 10 * t + _1, sm * x
x_d = 10 * (kt_ - hx_) + d
try:
h, _x, _ = (int(c) for c in str(hx_))
except ValueError:
continue
s2 = s1.union([h, p])
khx = 100 * k + 10 * h + x
assert x_d - khx == ks and len(s2) == 9
kt_, hx_ = 100 * k + 10 * t + _1, sm * x
if hx_ // 10 != 10 * h + x:
continue

print('         {}'.format(txs))
print('     -------')
print('  {} ) {}'.format(sm, trm_d))
print('       {}'.format(pkx))
print('       ---')
print('        {}'.format(kt_))
print('        {}'.format(hx_))
print('        ---')
print('         {}'.format(x_d))
print('         {}'.format(khx))
print('         ---')
print('          {}'.format(ks))
```

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