# Enigmatic Code

Programming Enigma Puzzles

## Enigma 1092: A prime age

From New Scientist #2248, 22nd July 2000 [link]

Marge, April, May, June, Julia and Augusta have all celebrated their birthday today. They are all teenagers and with the exception of the one pair of twins their ages are all different.

Today, only Marge and April have ages which are prime numbers, but the sum of the ages of all the girls is also a prime number. On their birthday last year, only May and June had ages which were prime numbers, but again the sum of the ages of all the girls was a prime number. On their birthday two years before that, only May and Julia had ages which were prime numbers, but even then, the sum of the ages of all the girls was again a prime number.

How old is Augusta?

[enigma1092]

### 3 responses to “Enigma 1092: A prime age”

1. Jim Randell 16 October 2017 at 7:49 am

I wrote a program that just considers all possible assignments of ages to the girls, and it ran in 435ms.

The Python 3.6 program below, starts by looking for sequences of ages that sum to a prime number, and would also give a prime sum for the ages a year ago and three years ago. It runs in 98ms.

Run: [ @repl.it ]

```from itertools import combinations, permutations
from enigma import irange, is_prime, uniq, printf

# indices for the girls
girls = (Mar, Apr, May, Jun, Jul, Aug) = irange(0, 5)

# possible ages (they are all teenagers)
ages = (13, 14, 15, 16, 17, 18, 19)

# generate possible ages
def generate():

# choose five of the ages
for s in combinations(ages, 5):

# and sum them
t0 = sum(s)

# then add in one of them again (for the twins)
for x in s:
t = t0 + x

# check the sum of the ages is prime, and would be prime last year, and three years ago
if not all(is_prime(t + d) for d in (0, -6, -18)): continue

# return the ages
yield s + (x,)

# find girls with prime ages
def check(age, ago=0):
return tuple(x for x in girls if is_prime(age[x] - ago))

# choose possible ages
for s in generate():

# and assign the ages to the girls
for age in uniq(permutations(s)):

# in the current year only Mar and Apr are prime
if check(age) != (Mar, Apr): continue

# last year only May and Jun were prime
if check(age, 1) != (May, Jun): continue

# three years ago only May and Jul were prime
if check(age, 3) != (May, Jul): continue

# output solutions
printf("Mar={age[Mar]} Apr={age[Apr]} May={age[May]} Jun={age[Jun]} Jul={age[Jul]} Aug={age[Aug]}")
```

Solution: Augusta is 15.

There is only one assignment of ages that satisfies the conditions of the problems:

Marge = 13, April = 13, May = 14, June = 18, Julia = 16, Augusta = 15

In fact, there are only two sequences of ages that will allow the sums to be prime this year, last year and three years ago:

(13, 14, 14, 15, 16, 17), sum = 89
(13, 13, 14, 15, 16, 18), sum = 89

For both sequences the sum last year would be 83, and three years ago it would be 71. But the first of these sequences would give three prime ages three years ago.

2. Jim Randell 16 October 2017 at 7:59 am

Here is the problem expressed as a set of MiniZinc constraints.

I get an execution time of 195ms for the [[ `mzn-gecode -a` ]] solver.

```include "globals.mzn";

% current ages (all teenagers)
set of int: Ages = { 13, 14, 15, 16, 17, 18, 19 };
var Ages: Mar;
var Ages: Apr;
var Ages: May;
var Ages: Jun;
var Ages: Jul;
var Ages: Aug;

% primes below 120
set of int: Primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 };

% there are five different ages between them
constraint nvalue([ Mar, Apr, May, Jun, Jul, Aug ]) = 5;

% today only Mar and Apr have prime ages
constraint forall (x in { Mar, Apr }) (x in Primes);
constraint forall (x in { May, Jun, Jul, Aug }) (not(x in Primes));

% and the sum of the six ages is prime
constraint sum([ Mar, Apr, May, Jun, Jul, Aug ]) in Primes;

% last year, only May and Jun had prime ages
constraint forall (x in { May, Jun }) (x - 1 in Primes);
constraint forall (x in { Mar, Apr, Jul, Aug }) (not(x - 1 in Primes));

% and the sum of the six ages was prime
constraint sum (x in [ Mar, Apr, May, Jun, Jul, Aug ]) (x - 1) in Primes;

% three years ago, only May and Jul had prime ages
constraint forall (x in { May, Jul }) (x - 3 in Primes);
constraint forall (x in { Mar, Apr, Jun, Aug }) (not(x - 3 in Primes));

% and the sum of the six ages was prime
constraint sum (x in [ Mar, Apr, May, Jun, Jul, Aug ]) (x - 3) in Primes;

solve satisfy;
```
3. Brian Gladman 17 October 2017 at 9:22 am
```from itertools import product

# test for primes below 121
pr = (2, 3, 5, 7, 11)
is_prime = lambda x: x in pr or all(x % p for p in pr)

# teenage years
teens = range(13, 20)

# Marge and April's ages are primes now
for Mar, Apr in product((x for x in teens if is_prime(x)), repeat=2):

# May and June's ages were primes last year
for May, Jun in product((x for x in teens if is_prime(x - 1)), repeat=2):

# there is at most one duplicate and May's age three years ago was prime
ls = len(set((Mar, Apr, May, Jun)))
if ls < 3 or not is_prime(May - 3):
continue

# Julia and Augusta's ages are among the remaining non-primes
rest = {x for x in teens if not is_prime(x)}.difference([May, Jun])
for Jul, Aug in product(rest, repeat=2):
t = (Mar, Apr, May, Jun, Jul, Aug)

# there is exactly one duplicate and Julia's age 3 years ago was prime
if len(set(t)) != 5 or not is_prime(Jul - 3):
continue

# this year, one year and three years ago the sum of their
# ages is/was prime and two of the six ages are/were prime
st = sum(t)
if all(is_prime(st - 6 * x) and
len([1 for a in t if is_prime(a - x)]) == 2 for x in (0, 1, 3)):
print(f'Marge .. Augusta: {t}')
```

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