# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1104: Odd and even squares

From New Scientist #2260, 14th October 2000 [link]

In the following statement digits have been consistently replaced by capital letters, different letters being used for different digits:

ONE and NINE are odd perfect squares, FOUR is an even perfect square.

Find the numerical value of the square root of (NINE × FOUR × ONE).

[enigma1104]

### 8 responses to “Enigma 1104: Odd and even squares”

1. Jim Randell 31 July 2017 at 8:38 am

This puzzle can be solved using the SubstitutedExpression() solver from the enigma.py library.

This run file executes in 82ms.

```#!/usr/bin/env python -m enigma -r

SubstitutedExpression

--invalid="0,ONEF"
--invalid="2|4|6|8,E"
--invalid="1|3|5|7|9,R"

"is_square(ONE)"
"is_square(NINE)"
"is_square(FOUR)"
```

Solution: The square root of (NINE × FOUR × ONE) is 73872.

2. geoffrounce 31 July 2017 at 12:35 pm

This Python programme ran in 46 msec.

```from itertools import permutations
from math import sqrt

def is_sq(n):
c = int(n**(1/2) + 0.5)
return (c**2 == n)

for p in permutations('1234567890',4):
O, N, E, I = p
if O == '0' or N == '0' : continue
ONE = int(O + N + E)
NINE = int(N + I + N + E)

if is_sq(ONE) and ONE % 2 == 1:
if is_sq(NINE) and NINE % 2 == 1:

r = set('1234567890').difference(p)
for q in permutations(r,3):
F, U, R = q
if F == '0': continue
FOUR = int(F + O + U + R)
if is_sq(FOUR) and FOUR % 2 == 0:
print('ONE = {}, NINE = {}, FOUR = {}' \
.format(ONE,NINE,FOUR))

print('Square Root of (NINE * FOUR * ONE) = ', \
int(sqrt(NINE * FOUR * ONE)))

# ONE = 361, NINE = 6561, FOUR = 2304
# Square Root of (NINE * FOUR * ONE) =  73872
```
3. Hugh Casement 31 July 2017 at 6:57 pm

No. 1425 is an expanded version of this one.

4. hakank 31 July 2017 at 8:35 pm

Here’s a Picat model that takes about 10ms to solve. Note that the square root calculation is done after solve. Hence all variables are assigned and we can use the non-CP variant sqrt/1. (One can also use a square_root/1 constraint similar to perfect_square/1, but it’s not needed.)

A comment about perfect_square/1: the domains for Y is restricted by fd_min_max/3 which simplifies the model.

```import cp.
main => time2(go).
go =>
L = [O,N,E,I,F,U,R],
L :: 0..9,

all_distinct(L),
ONE  :: 123..987,          ONE #= 100*O + N*10 + E,
NINE :: 1234..9876,      NINE #= 1000*N + 100*I + N*10 + E,
FOUR :: 1234..9876,    FOUR #= 1000*F + 100*O + U*10 + R,
perfect_square(ONE),
perfect_square(NINE),
perfect_square(FOUR),
ONE  mod 2 #= 1,
NINE mod 2 #= 1,
FOUR mod 2 #= 0,

solve([ff,split],L),

% Here all decision variables are assigned so we use the non-cp sqrt/1 to get the answer.
println(round(sqrt(NINE*FOUR*ONE))),
nl.

perfect_square(X) =>
fd_min_max(X, Min, Max),
Y :: ceiling(sqrt(Min))..ceiling(sqrt(Max)),
Y*Y #= X.
```

(A similar MiniZinc model is slower: about 100ms.)

• Jim Randell 1 August 2017 at 6:33 am

@hakank: Thanks for posting your Picat model. For some reason I don’t get any output when I try and run it, but if I replace the mod constraints at lines 14-16 with:

```  E mod 2 #= 1,
R mod 2 #= 0,
```

then I do get the expected answer.

5. hakank 1 August 2017 at 7:59 am

@jim. Ah. I assume that you are running Picat v 2.1#3 (the latest official release). It has a bug regarding larger domains in certain cases. I happen to run the forthcoming version where this bug is fixed. 🙂 Sorry about that. I hope the new version will be released soon.

6. geoffrounce 1 August 2017 at 9:01 am

I used Hakank’s square predicate and it ran in 64 msec, but ’round’ did not work for me in the output.

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

var 1..9:O;   var 1..9:N;  var 0..9:I;   var 0..9:E;
var 1..9:F;   var 0..9:U;  var 0..9:R;

var 123..987: ONE = 100*O + 10*N + E;
var 1234..9876: NINE = 1000*N + 100*I + 10*N + E;
var 1234..9876: FOUR = 1000*F + 100*O + 10*U + R;

constraint all_different ([O, N, E, I, F, U, R]);

predicate square(var int: y) =
let {
var 1..ceil(sqrt(int2float(ub(y)))): z
} in z*z = y;

constraint square(ONE) /\ ONE mod 2 == 1;
constraint square(NINE) /\ NINE mod 2 == 1;
constraint square(FOUR) /\ FOUR mod 2 == 0;

solve satisfy;

output [ "Square Root is " ++ show(sqrt(ONE * NINE * FOUR))];

% Square Root is 73872.0
% Finished in 64msec
```
7. hakank 1 August 2017 at 10:39 am

@geoffrounce Nice! For my own MiniZinc model I didn’t use sqrt like that.

Regarding round: There is no support for “round(var int)” in MiniZinc. However, when using values in the output like this, one can use “fix(…)” to convert to a non-var parameter and then use “round()”. So this works:

```output [ "Square Root is " ++ show(round(fix(sqrt(ONE * NINE * FOUR))))];
```

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