Home More Samples
```
///////////////////////////////////////////////////////////////////////////////
// Magic magic
///////////////////////////////////////////////////////////////////////////////
// Enigma 1492 Adrian Somerfield, New Scientist magazine, May 3, 2008
///////////////////////////////////////////////////////////////////////////////
//
// I asked Albert and Berkeley to find 3 x 3 magic squares (i.e. containing
// nine different positive integeres with the sum in each row, each column
// and main diagonal the same). They each found one. I then asked them to
// replace numbers with letters using A=1, B=2, and so on. Both their squares
// contained the letters M,A,G,I,C, but only in Albert's case was one of those
// letters at the centre of the square.
//
// A. Which other four letters were used in Albert's square?
// B. Which other four letters were used in Berkeley's square?
//
// In each case, give the letters in alphabetical order.
//
///////////////////////////////////////////////////////////////////////////////
//
// Solve the problem by running the query:
//
//          all Enigma_1492()
//
///////////////////////////////////////////////////////////////////////////////
//
// Results:
//
//  Albert:   EKOQ
//  ___ Solution: 1 __________________________________
//
//  Berkeley: BHNO
//  ___ Solution: 2 __________________________________
//
//  Number of solutions: 2   Number of backtracks: 343
//  Elapsed time: 00:00:00
//
//
///////////////////////////////////////////////////////////////////////////////

local Magic :< [0..4]->L = ["M","A","G","I","C"]

pred Enigma_1492() iff
// Magic square 3x3 (9 elements), ranging from A to Z
ms::[0..8]->>L["A".."Z"] &

// view the array elements as separate variables in order
// to simplify the typing...
ms = [a1, a2, a3,
b1, b2, b3,
c1, c2, c3] &

// Sum the rows
a1 + a2 + a3 = sum &
b1 + b2 + b3 = sum &
c1 + c2 + c3 = sum &

// Sum the colums
a1 + b1 + c1 = sum &
a2 + b2 + c2 = sum &
a3 + b3 + c3 = sum &

// Sum the main diagonals
a1 + b2 + c3 = sum &
c1 + b2 + a3 = sum &

// Remove symmetries, they would lead to multiple identical solutions
a1 < a3 & a1 < c1 & a1 < c3 & a3 < c1 &

// We know each solution must contain all the letters M,A,G,I,C
ms(_) = "M" & ms(_) = "A" & ms(_) = "G" & ms(_) = "I" & ms(_) = "C" &

// All constraints are set up now, print the solutions...
PrettyPrintResults(ms)

///////////////////////////////////////////////////////////////////////////////
/// Check if the center of the square is one of the letters M,A,G,I,C.
/// If so, the square is Albert's, otherwise it is Berkeley's.
/// Sort the array in ascending order and call a routine to print
/// all the remaining letters.
local proc PrettyPrintResults(ms:<[0..8]->L) iff
if ms(4) in Magic then
Print('\nAlbert:   ')
else
Print('\nBerkeley: ')
end &
PrintRemainingLetters(RtlSortAscending(ms),0)

///////////////////////////////////////////////////////////////////////////////
/// Go through all array elements and if the array element is not one of the
/// M,A,G,I,C then print it (as a string).
/// (We convert the bignum L to number I and convert I to string)
local proc PrintRemainingLetters(x:<[0..8]->L,i:<I) iff
if i < 9 then
if ~x(i) in Magic then
Print((x(i):I):S)
end & PrintRemainingLetters(x,i+1)
end

```