# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1111: Base-age

From New Scientist #2267, 2nd December 2000 [link]

Fill in the following cross-figure. No answer begins with a zero. The same base is used for all the entries, but it is not necessarily 10.

Across
1. A palindromic prime.
4. The square of the base being used.
5. A square.

Down
1. Three times my son’s age.
2. A prime.
3. A palindromic square.

How old is my son?

[enigma1111]

### 2 responses to “Enigma 1111: Base-age”

1. Jim Randell 12 June 2017 at 9:02 am

If the base is b, then represented in base b is always 100. So this is the answer to 4 across.

We are also told that 1 across and 3 down are palindromic numbers, so there are only 4 unknown values to place in the squares.

Additionally the smallest possible value for 1 down is 111. In base 18 this corresponds to 343 (decimal), which would make the son at least 114, so I don’t bother checking bases higher than this.

This Python program considers bases between 2 and 18 and creates a collection of alphametic expressions in that base, then uses the generalised alphametic solver (SubstituedExpression()) from the enigma.py library to look for solutions.

It runs in 66ms

```# 1 across is palindromic
# 4 across is 100
# 3 down is palindromic
#
# using Z=0, U=1, the square is:
#
#   A B A
#   U Z Z
#   C D A

from enigma import SubstitutedExpression, irange, nconcat, printf

# the remaining expressions
exprs = [
# "1 across: A palindromic prime"
"is_prime(ABA)",
# "5 across: A square"
"is_square(CDA)",
# "1 down: 3 times my son's age"
"AUC % 3 = 0",
# "2 down: A prime"
"is_prime(BZD)",
# "3 down: A palindromic square"
"is_square(AZA)",
]

# consider bases up to 18
# base2int("100", 18) = 324, so the son would be at least 108
for b in irange(2, 18):

# create the alphametic problem in the appropriate base
p = SubstitutedExpression(
exprs,
symbols="ABCDUZ",
distinct="",
l2d={ 'Z': 0, 'U': 1 },
base=b,
)

# and solve it
for s in p.solve(verbose=0):
(A, B, C, D, U, Z) = (s[x] for x in 'ABCDUZ')
# calculate the sons age (= AUC // 3)
age = nconcat(A, U, C, base=b) // 3
printf("age={age}, base={b}, square=[{A} {B} {A} / {U} {Z} {Z} / {C} {D} {A}]")
```

The cross-figure is in base 7, and the filled out grid is:

```2 1 2
1 0 0
6 4 2```

1 across: 212 (base 7) = 107 (decimal), prime.
4 across: 100 (base 7) = 49 (decimal), 7².
5 across: 642 (base 7) = 324 (decimal), 18².

1 down: 216 (base 7) = 111 (decimal), 3× 37.
2 down: 104 (base 7) = 53 (decimal), prime.
3 down: 202 (base 7) = 100 (decimal), 10².

2. geoffrounce 13 June 2017 at 7:33 pm

I used Jim’s analysis that the answer to 4 across is 100.

It is not very pretty code and I was not sure whether to post it, but it gets the answer in about 100 msec on my laptop. Fortunately, clue 3 down gives a unique answer for the number base, which is used for the rest of the code.

```# Grid for unknown digits
#        A  B  A
#        1  0  0
#        C  D  A

def conv_base(b,A,B,C):
# base b,3 digits are A, B and C - converts base b to base 10
if A > 0 and A < b:
if B < b and C < b:
num = A*b*b + B*b + C
if 2 <= num < 1000:
return num

def is_prime(n):
for x in range(2, int(n**0.5)+1):
if n % x == 0:
return False
return True

# list of primes less than 1000
pr_list = []
for n in range(2,1000):
if is_prime(n):
pr_list.append(n)

# clue 3 down - A0A - to find A and base b
for n in (101, 202, 303, 404, 505, 606, 707, 808, 909):
for b in range(3,19):
num = conv_base(b, n // 100, n // 10 % 10, n % 10)
for a in range(1,33):
if a * a == num:
A = n // 100
print('A = ', n // 100, 'base = ',b)  # A = 2, b = 7
base = b  # use for other clues

# clue 1 across  - ABA  - to find B
for n in (212, 222, 232, 242, 252, 262, 272, 282, 292):
num = conv_base(base, A, n// 10 % 10, A)
if num in pr_list:
B = int(n // 10 % 10)
print('B = ',B)     # B = 1

# clue 2 down - B0D - to find D
for n2 in (101, 102, 103, 104, 105, 106, 107, 108, 109):
num2 = conv_base(base, B, 0, n2 % 10)
if num2 in pr_list:
D = int(n2 % 10)
print('D = ', D )  # D = 4

# clue 5 across - CDA - to find C
for n5 in (142, 242, 342, 442, 542, 642, 742, 842, 942):
num5 = conv_base(base, n5 //100, D, A)
for n in range(10,33):
if n * n == num5:
C = n5 // 100
print('C = ', C)   # C = 6

# Check 1 down - my son's age (A1C)
# A1C = 216

num6 = conv_base(7,2,1,6)

print( 'My son''s age = ',num6 // 3)
print()

print ('Grid is:')
print(A,B,A)
print(1,0,0)
print(C,D,A)

'''
Output
A =  2 base =  7
B =  1
D =  4
C =  6
My sons age =  37

Grid is:
2 1 2
1 0 0
6 4 2
'''
```