# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1106: Not a square unused

From New Scientist #2262, 28th October 2000 [link]

Harry, Tom and I each found a set consisting of a 4-digit perfect square, a 3-digit perfect square and a 2-digit perfect square that between them used nine different digits; but none of us could add a 1-digit square with the unused digit because 9, 4, 1 and 0 all appeared in each of our three sets. No two of us found exactly the same set; none of the squares in my set appeared in either Harry’s set or Tom’s set. There is one further set that none of us found whose unused digit is again not itself a perfect square.

List in ascending order the three squares in this set that none of us found.

[enigma1106]

### 3 responses to “Enigma 1106: Not a square unused”

1. Jim Randell 17 July 2017 at 8:23 am

This Python program uses the SubstitutedExpression() solver from the enigma.py library to solve the embedded problem and find possible sets that satisfy the conditions Tom, Dick and Harry are looking for, and then examines which arrangement of possible solutions satisfies the remaining conditions. It runs in 86ms.

```from itertools import combinations
from enigma import irange, is_duplicate, SubstitutedExpression, diff, printf

# 1, 2, 3, 4 digit squares without duplicated digits
squares = list(s for s in (i * i for i in irange(0, 99)) if not is_duplicate(s))

# find 10 digit solutions to the problem
p = SubstitutedExpression(
[ "A not in squares", "BC in squares", "DEF in squares", "GHIJ in squares" ],
env={ 'squares': squares }, # incorporate the list of squares into the environment
template="[unused = A, squares = (BC, DEF, GHIJ)]", # solution template
verbose=4, # output the solutions
solution="", # but don't output the substitution map
)

# record the potential answer sets
ss = list(ans for (s, ans) in p.solve())

# check answers have no squares in common
def check(s, t):
return all(a != b for (a, b) in zip(s, t))

# choose a set for me
for D in ss:
# choose sets for Harry and Tom
for (H, T) in combinations(diff(ss, [D]), 2):
# none of the squares in my set appear in Harry's or Tom's
if not(check(D, H) and check(D, T)): continue
# and find unused sets
for U in diff(ss, [D, H, T]):
printf("U={U} [D={D} H/T={H}/{T}]")
```

Solution: The three squares in the set none of them found were: 36, 841, 9025.

There are only 4 possible sets of squares:

[1] (16, 784, 9025) with 3 left over;
[2] (36, 841, 9025) with 7 left over;
[3] (36, 289, 5041) with 7 left over;
[4] (36, 729, 5041) with 8 left over.

Dick found set [1]. Tom and Harry found sets [3] and [4]. Leaving [2] as the set none of them found.

2. Brian Gladman 17 July 2017 at 5:21 pm
```from collections import defaultdict

# map the number of digits (2, 3 or 4) to a dictionary of
# squares with this number of different digits (the keys)
# and then to the set of digits in the square (as values)
sqrs = defaultdict(dict)
for n in range(4, 100):
sq = n * n
ss = str(sq)
dgts = set(ss)
n_dgts = len(dgts)
if n_dgts == len(ss):
sqrs[n_dgts][sq] = dgts

# create sets of triples of 2, 3 and 4 digit squares with nine
# different digits amoung them and the tenth digit not square
tr_set = set()
# two digit squares and their digit sets
for sq2, st2 in sqrs[2].items():
# three digit squares and their digit sets
for sq3, st3 in sqrs[3].items():
# their digits must be different
if not (st2 & st3):
s23 = st2 | st3
# four digit squares and their digit sets
for sq4, st4 in sqrs[4].items():
# all nine digits must be different
if not s23 & st4:
# all digits that are square must be present
if set('0149') < s23 | st4:

# we are told that there are four such triples
assert len(tr_set) == 4

# pick a triple for me
for my_tr in tr_set:
# those triples remaining
rest = tr_set.difference([my_tr])
# look for two triples that don't share any values with mine
th_trp = {s for s in rest if not (s & my_tr)}
if len(th_trp) == 2:
f = lambda x: tuple(sorted(x))
tt, ht = (f(x) for x in th_trp)
# find the fourth triple
ex, = rest.difference(th_trp)
print(f'Mine: {f(my_tr)}, [Tom, Harry]: [{tt}, {ht}], Other: {f(ex)}')
```
3. geoffrounce 15 March 2018 at 5:35 pm

Multiple configuration output in MiniZinc convieniently produces the four sets of squares

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

% 2-digit square ia AB, 3-digit square is CDE and 4-digit square is FGHI
var 0..9:A;   var 0..9:B;   var 0..9:C;
var 0..9:D;   var 0..9:E;   var 0..9:F;
var 0..9:G;   var 0..9:H;   var 0..9:I;

constraint all_different([A, B, C, D, E, F, G, H, I]);

% A, B, C and F cannot be zero
constraint A != 0 /\ C != 0 /\ F != 0;

% Digits 9, 4, 1 and 0 all appeared in each of the three sets
constraint D = 0 \/ E = 0 \/ F = 0 \/ G = 0 \/ H = 0 \/ I = 0;

constraint  A = 1 \/ B = 1 \/ C = 1 \/ D = 1 \/ E = 1 \/ F = 1  \/ G = 1 \/ H = 1 \/ I = 1;

constraint  A = 4 \/ B = 4 \/ C = 4 \/ D = 4 \/ E = 4 \/ F = 4  \/ G = 4 \/ H = 4 \/ I = 4;

constraint  A = 9 \/ B = 9 \/ C = 9 \/ D = 9 \/ E = 9 \/ F = 9  \/ G = 9 \/ H = 9 \/ I = 9;

% 2, 3 and 4 digits squares in each set
var 16..81: AB = 10*A + B;
var 100..961: CDE = 100*C + 10*D + E;
var 1089..9801: FGHI = 1000*F + 100*G + 10*H + I;

set of int: sq2 = {n*n | n in 4..9};
set of int: sq3 = {n*n | n in 10..31};
set of int: sq4 = {n*n | n in 32..99};

constraint AB in sq2 /\ CDE in sq3 /\ FGHI in sq4;

solve satisfy;

output [ "Sq2 = " ++ show(AB) ++ "  Sq3 = " ++ show(CDE) ++ "  Sq4 = " ++ show(FGHI) ];

% Sq2 = 16  Sq3 = 784  Sq4 = 9025   -  3 not used  - Dick's set
% Sq2 = 36  Sq3 = 729  Sq4 = 5041   -  8 not used  - Tom or Harry's set
% Sq2 = 36  Sq3 = 841  Sq4 = 9025   <<<  7 not used  - the extra set and  the answer
% Sq2 = 36  Sq3 = 289  Sq4 = 5041   - 7 not used  - Tom or Harry's set
% -------
% ==========
% Finished in 85msec
```

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