# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1120: Assorted numbers

From New Scientist #2276, 3rd February 2001 [link]

Consider the five-digit and six-digit numbers represented by the words MELONS, PLUMS, APPLES, LEMONS and BANANA, in which different letters stand for different digits but the same letter always stands for the same digit whenever it appears.

If the product 2 × MELONS is greater than the product 35 × PLUMS, but less than the product 3 × APPLES; and if the product 99 × LEMONS is greater than the product 16 × APPLES, but less than the product 210 × PLUMS, then how big is a BANANA?

Thanks to Hugh Casement for providing the source for this puzzle.

[enigma1120]

### 5 responses to “Enigma 1120: Assorted numbers”

1. Jim Randell 10 April 2017 at 8:07 am

We can use the general alphametic solver (SubstitutedExpression()) from the enigma.py library to solve this puzzle. While Python allows us to join the pairs of inequalities into single expressions (x < y < z) the solver can run more efficiently if they are kept separate.

This run-file executes in 404ms.

```#!/usr/bin/env pypy enigma.py -r

# solver to use
SubstitutedExpression

# solver arguments
--reorder=0

# expressions to solve
"35 * PLUMS < 2 * MELONS"
"99 * LEMONS < 210 * PLUMS"
"2 * MELONS < 3 * APPLES"
"16 * APPLES < 99 * LEMONS"
```

Solution: BANANA = 763636.

• Jim Randell 10 April 2017 at 8:13 am

We can also use MiniZinc to express the problem as a set of constraints. Here I’ve used the minizinc.py wrapper to make the coding easier.

This Python 3.6 program runs in 175ms.

```from enigma import concat, printf
from minizinc import MiniZinc, var, alphametic

# create the model
m = MiniZinc(f"""

include "globals.mzn";

% declare the decision variables
{var("0..9", "BENOSU")};
{var("1..9", "ALMP")};

% they are all distinct
constraint all_different([A, B, E, L, M, N, O, P, S, U]);

% the alphametic expressions
constraint {alphametic("16 * {APPLES} < 99 * {LEMONS}")};
constraint {alphametic("99 * {LEMONS} < 210 * {PLUMS}")};
constraint {alphametic("35 * {PLUMS} < 2 * {MELONS}")};
constraint {alphametic("2 * {MELONS} < 3 * {APPLES}")};

solve satisfy;

""")

for s in m.solve():
BANANA = m.substitute(s, "BANANA")
printf("BANANA={BANANA} [{s}]", s=concat((concat(k, '=', v) for (k, v) in s.items()), sep=" "))
```
2. geoffrounce 10 April 2017 at 11:24 am

A 4-stage permutation solution, permuting the 10 digits in groups of (3,3,2,2) ran in 416 msec

```from itertools import permutations

digits = set('1234567890')

from itertools import permutations
for p1 in permutations('1234567890',3):
o, n, s = p1

p2 = digits.difference(p1)
for q1 in permutations(p2, 3):
m, e, l = q1
if m == '0' or l == '0': continue
melons = int(m + e + l + o + n + s)
lemons = int(l + e + m + o + n + s)

p3 = p2.difference(q1)
for q2 in permutations(p3,2):
a, p = q2
if a == '0' or p == '0':continue
apples = int(a + p + p + l + e + s)

p4 = p3.difference(q2)
for q3 in permutations(p4,2):
u, b = q3
if b == '0': continue
plums = int(p + l + u + m + s)

if 2 * melons > 35 * plums and  2 * melons < 3 * apples:
if 99 * lemons > 16 * apples and  99 * lemons < 210 * plums:
banana = int(b + a + n + a + n + a)

print('BANANA={}, LEMONS={}, MELONS={}, APPLES={}, PLUMS={}'. \
format(banana,lemons,melons,apples, plums))

# BANANA=763636, LEMONS=109238, MELONS=901238, APPLES=655108, PLUMS=51498
```
3. geoffrounce 10 April 2017 at 12:00 pm

A MiniZinc solution ran in 117 msec

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

var 0..9:O;   var 0..9:N;  var 0..9:S; var 1..9:M;
var 1..9:L;   var 0..9:E;  var 1..9:A; var 1..9:P;
var 0..9:U;   var 0..9:B;

constraint alldifferent([O, N, S, M, L, E, A, P, U, B]);

var 100000..999999 : MELONS = 100000*M + 10000*E + 1000*L + 100*O + 10*N + S;
var 100000..999999 : LEMONS = 100000*L + 10000*E + 1000*M + 100*O + 10*N + S;
var 100000..999999 : APPLES = 100000*A + 10000*P + 1000*P + 100*L + 10*E + S;
var 100000..999999 : BANANA = 100000*B + 10000*A + 1000*N + 100*A + 10*N + A;
var 10000..99999 : PLUMS = 10000*P + 1000*L + 100*U + 10*M + S;

constraint ( 2 * MELONS > 35 * PLUMS) /\  (2 * MELONS < 3 * APPLES);
constraint (99 * LEMONS > 16 * APPLES) /\  (99 * LEMONS < 210 * PLUMS);

solve satisfy;

output[ "BANANA = " ++ show(BANANA) ];

% BANANA = 763636
% Finished in 117msec

```
4. Brian Gladman 10 April 2017 at 3:48 pm
```from itertools import permutations
from functools import reduce

# 99.LEMONS < 210.PLUMS <  12.MELONS
# 32.MELONS < 48.APPLES < 297.LEMONS

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

for p in permutations(range(10), 6):
E, L, M, N, O, S = p
if 0 not in (L, M):
lemons = dgts2nbr((L, E, M, O, N, S))
melons = dgts2nbr((M, E, L, O, N, S))
if 99 * lemons < 12 * melons and 32 * melons < 297 * lemons:

for A, B, P, U in permutations(set(range(10)).difference(p)):
apples = dgts2nbr((A, P, P, L, E, S))
plums = dgts2nbr((P, L, U, M, S))

if (99 * lemons < 210 * plums < 12 * melons and
32 * melons < 48 * apples < 297 * lemons):
banana = dgts2nbr((B, A, N, A, N, A))
print(f'BANANA = {banana} (PLUMS = {plums}, LEMONS = '
f'{lemons}, APPLES = {apples}, MELONS = {melons})')
```