Home More Samples
```
///////////////////////////////////////////////////////////////////////////////
// Birthday magic
///////////////////////////////////////////////////////////////////////////////
// Enigma 1448 Gwyn Owen, New Scientist magazine, June 23 2007.
///////////////////////////////////////////////////////////////////////////////
//
// For my brother-in-law's birthday in 2007 I made up a 4-by-4 magic square for
// him. Each of the rows, columns and main diagonals added up to his new age.
// I told him this but then only gave him the incomplete version shown below.
//
// +----+----+----+----+
// |    |    | 19 |    |
// +----+----+----+----+
// | 39 |    | 1  | 6  |
// +----+----+----+----+
// | 5  | 2  |    |    |
// +----+----+----+----+
// |    |    |    | 2  |
// +----+----+----+----+
//
// He managed to complete the square but only then realized that the top row of
// the square represented his date of birth, in the form:
//
// +----+----+----+----+
// |Day |Mnth| 19 | ?? |
// +----+----+----+----+
//
// What is his date of birth?
//
///////////////////////////////////////////////////////////////////////////////
//
// Solve the problem by running the query:
//
//          all BirthdayMagic(day,month,year,age)
//
///////////////////////////////////////////////////////////////////////////////
//
// Results:
//
// day = 1
// month = 3
// year = 1942
// age = 65
// ___ Solution: 1 ___ [00:00:00] __ [Backtracks: 0] ____
//
// Number of solutions: 1   Number of backtracks: 0
// Elapsed time: 00:00:00
//
///////////////////////////////////////////////////////////////////////////////
//
// Notes: Beware that unlike usual magic squares, this one can contain
// identical values. (Number 2 is repeated twice). Otherwise trivial.
// Note the constraints on month (1..12) and day (1..31) are not even needed.
// In fact, there is no need to assume that all values within the magic square
// are positive or fall within a certain range.
//
///////////////////////////////////////////////////////////////////////////////
pred BirthdayMagic(day::L, month::L, year::L,age::L) iff
ms::[0..15]->L &
ms = [a1, a2, a3, a4,
b1, b2, b3, b4,
c1, c2, c3, c4,
d1, d2, d3, d4] &

// Sum of all rows must be the same
a1 + a2 + a3 + a4 = age &
b1 + b2 + b3 + b4 = age &
c1 + c2 + c3 + c4 = age &
d1 + d2 + d3 + d4 = age &

// Sum of all columns must be the same
a1 + b1 + c1 + d1 = age &
a2 + b2 + c2 + d2 = age &
a3 + b3 + c3 + d3 = age &
a4 + b4 + c4 + d4 = age &

// Sum of both main diagonals must be the same
a1 + b2 + c3 + d4 = age &
d1 + c2 + b3 + a4 = age &

// Fill in the values we already know...
a3 = 19 &
b1 = 39 & b3 = 1 & b4 = 6 &
c1 =  5 & c2 = 2 &
d4 =  2 &

// Some final constraints and we are done...
day = a1 & month = a2 & year = 100*a3 + a4 & year + age = 2007

```