HomeHome More SamplesMore Samples
///////////////////////////////////////////////////////////////////////////////
//
// Most-perfect magic square of order n is a magic square containing the 
// numbers 0 to n*n - 1 with two additional properties:
//
//   1. Each 2x2 subsquare sums to 2s, where s = n*n - 1.
//   2. All pairs of integers distant n/2 along a (major) diagonal sum to s.
//
// Note: The "additional" properties actualy define all the properties of the 
// Most Perfect Magic Squares. The usual constraints of ordinary magic squares 
// (sums of rows, columns and diagonals sum up to n*((n*n)-1)/2) are redundant
// in this case.
//
//
///////////////////////////////////////////////////////////////////////////////
//
// This program calculates all 368640  solutions in about 45 hours using an 
// Intel Core2 CPU at 2.4 GHz. The solutions are not distributed evenly in time,
// they come in bursts: You may get dozens of solutions within one second and
// then no solutions for tens of minutes. Expect about one minute to see the
// first solution.
//
///////////////////////////////////////////////////////////////////////////////
//
// To generate all 368640 solutions, run query: 
//
//      all MostPerfectMS8x8()
//
// To generate a single solution, run query: 
//
//      one MostPerfectMS8x8()
//
// You may want to generate only a subset of all magic squares, for example
// to generate only 100 solutions, use the following query:
//
//      all MostPerfectMS8x8() & RtlTrimSolutions(100)
//
///////////////////////////////////////////////////////////////////////////////

// Definitions for zero based MS (numbers ranging 0..63)
Square8x8 = [0..63]->>L[0..63]
Sum2S :< L = 126            // 2*(n*n-1)
SumS  :< L = 63             // (n*n)-1)
SumMS :< L = 252            // n*((n*n)-1)/2

pred MostPerfectMS8x8() iff

    // An array of 64 variables of an 8x8 square
    a::Square8x8 &
    a = [ a1, a2, a3, a4, a5, a6, a7, a8,
          b1, b2, b3, b4, b5, b6, b7, b8,
          c1, c2, c3, c4, c5, c6, c7, c8,
          d1, d2, d3, d4, d5, d6, d7, d8,
          e1, e2, e3, e4, e5, e6, e7, e8,
          f1, f2, f3, f4, f5, f6, f7, f8,
          g1, g2, g3, g4, g5, g6, g7, g8,
          h1, h2, h3, h4, h5, h6, h7, h8] &

    // Constraints to to remove symmetries. 
    a1 > a8 & a1 > h1 & a1 > h8 & a8 > h1 & 
    
    // The four entries in every 2x2 subsquare sum to Sum2S.
    a1 + a2 + b1 + b2 = Sum2S & 
    a2 + a3 + b2 + b3 = Sum2S & 
    a3 + a4 + b3 + b4 = Sum2S & 
    a4 + a5 + b4 + b5 = Sum2S & 
    a5 + a6 + b5 + b6 = Sum2S & 
    a6 + a7 + b6 + b7 = Sum2S & 
    a7 + a8 + b7 + b8 = Sum2S & 
    a8 + a1 + b8 + b1 = Sum2S & // wrap

    b1 + b2 + c1 + c2 = Sum2S & 
    b2 + b3 + c2 + c3 = Sum2S & 
    b3 + b4 + c3 + c4 = Sum2S & 
    b4 + b5 + c4 + c5 = Sum2S & 
    b5 + b6 + c5 + c6 = Sum2S & 
    b6 + b7 + c6 + c7 = Sum2S & 
    b7 + b8 + c7 + c8 = Sum2S & 
    b8 + b1 + c8 + c1 = Sum2S & // wrap
   
    c1 + c2 + d1 + d2 = Sum2S & 
    c2 + c3 + d2 + d3 = Sum2S & 
    c3 + c4 + d3 + d4 = Sum2S & 
    c4 + c5 + d4 + d5 = Sum2S & 
    c5 + c6 + d5 + d6 = Sum2S & 
    c6 + c7 + d6 + d7 = Sum2S & 
    c7 + c8 + d7 + d8 = Sum2S & 
    c8 + c1 + d8 + d1 = Sum2S & // wrap

    d1 + d2 + e1 + e2 = Sum2S & 
    d2 + d3 + e2 + e3 = Sum2S & 
    d3 + d4 + e3 + e4 = Sum2S & 
    d4 + d5 + e4 + e5 = Sum2S & 
    d5 + d6 + e5 + e6 = Sum2S & 
    d6 + d7 + e6 + e7 = Sum2S & 
    d7 + d8 + e7 + e8 = Sum2S & 
    d8 + d1 + e8 + e1 = Sum2S & // wrap

    e1 + e2 + f1 + f2 = Sum2S & 
    e2 + e3 + f2 + f3 = Sum2S & 
    e3 + e4 + f3 + f4 = Sum2S & 
    e4 + e5 + f4 + f5 = Sum2S & 
    e5 + e6 + f5 + f6 = Sum2S & 
    e6 + e7 + f6 + f7 = Sum2S & 
    e7 + e8 + f7 + f8 = Sum2S & 
    e8 + e1 + f8 + f1 = Sum2S & // wrap

    f1 + f2 + g1 + g2 = Sum2S & 
    f2 + f3 + g2 + g3 = Sum2S & 
    f3 + f4 + g3 + g4 = Sum2S & 
    f4 + f5 + g4 + g5 = Sum2S & 
    f5 + f6 + g5 + g6 = Sum2S & 
    f6 + f7 + g6 + g7 = Sum2S & 
    f7 + f8 + g7 + g8 = Sum2S & 
    f8 + f1 + g8 + g1 = Sum2S & // wrap

    g1 + g2 + h1 + h2 = Sum2S & 
    g2 + g3 + h2 + h3 = Sum2S & 
    g3 + g4 + h3 + h4 = Sum2S & 
    g4 + g5 + h4 + h5 = Sum2S & 
    g5 + g6 + h5 + h6 = Sum2S & 
    g6 + g7 + h6 + h7 = Sum2S & 
    g7 + g8 + h7 + h8 = Sum2S & 
    g8 + g1 + h8 + h1 = Sum2S & // wrap

    h1 + h2 + a1 + a2 = Sum2S & 
    h2 + h3 + a2 + a3 = Sum2S & 
    h3 + h4 + a3 + a4 = Sum2S & 
    h4 + h5 + a4 + a5 = Sum2S & 
    h5 + h6 + a5 + a6 = Sum2S & 
    h6 + h7 + a6 + a7 = Sum2S & 
    h7 + h8 + a7 + a8 = Sum2S & 
    h8 + h1 + a8 + a1 = Sum2S & // wrap

    // All pairs of integers distant n/2 along a (major) diagonal sum to SumS
    a1 + e5 = SumS & 
    a2 + e6 = SumS &
    a3 + e7 = SumS & 
    a4 + e8 = SumS & 
    a5 + e1 = SumS & 
    a6 + e2 = SumS & 
    a7 + e3 = SumS & 
    a8 + e4 = SumS &

    b1 + f5 = SumS &
    b2 + f6 = SumS & 
    b3 + f7 = SumS & 
    b4 + f8 = SumS & 
    b5 + f1 = SumS & 
    b6 + f2 = SumS & 
    b7 + f3 = SumS & 
    b8 + f4 = SumS &

    c1 + g5 = SumS &     
    c2 + g6 = SumS & 
    c3 + g7 = SumS & 
    c4 + g8 = SumS & 
    c5 + g1 = SumS & 
    c6 + g2 = SumS & 
    c7 + g3 = SumS & 
    c8 + g4 = SumS &

    d1 + h5 = SumS & 
    d2 + h6 = SumS & 
    d3 + h7 = SumS & 
    d4 + h8 = SumS & 
    d5 + h1 = SumS & 
    d6 + h2 = SumS & 
    d7 + h3 = SumS & 
    d8 + h4 = SumS &

    e1 + a5 = SumS & 
    e2 + a6 = SumS & 
    e3 + a7 = SumS & 
    e4 + a8 = SumS & 
    e5 + a1 = SumS & 
    e6 + a2 = SumS & 
    e7 + a3 = SumS & 
    e8 + a4 = SumS &

    f1 + b5 = SumS & 
    f2 + b6 = SumS & 
    f3 + b7 = SumS & 
    f4 + b8 = SumS & 
    f5 + b1 = SumS & 
    f6 + b2 = SumS & 
    f7 + b3 = SumS & 
    f8 + b4 = SumS &

    g1 + c5 = SumS & 
    g2 + c6 = SumS & 
    g3 + c7 = SumS & 
    g4 + c8 = SumS & 
    g5 + c1 = SumS & 
    g6 + c2 = SumS & 
    g7 + c3 = SumS & 
    g8 + c4 = SumS &

    h1 + d5 = SumS & 
    h2 + d6 = SumS & 
    h3 + d7 = SumS & 
    h4 + d8 = SumS & 
    h5 + d1 = SumS & 
    h6 + d2 = SumS & 
    h7 + d3 = SumS & 
    h8 + d4 = SumS &

    {

    // Diagonals.
    // Commented out: These constraints are redundant.

    a1 + b2 + c3 + d4 + e5 + f6 + g7 + h8 = SumMS &
    a2 + b3 + c4 + d5 + e6 + f7 + g8 + h1 = SumMS &
    a3 + b4 + c5 + d6 + e7 + f8 + g1 + h2 = SumMS &
    a4 + b5 + c6 + d7 + e8 + f1 + g2 + h3 = SumMS &
    a5 + b6 + c7 + d8 + e1 + f2 + g3 + h4 = SumMS &
    a6 + b7 + c8 + d1 + e2 + f3 + g4 + h5 = SumMS &
    a7 + b8 + c1 + d2 + e3 + f4 + g5 + h6 = SumMS &
    a8 + b1 + c2 + d3 + e4 + f5 + g6 + h7 = SumMS &

    a8 + b7 + c6 + d5 + e4 + f3 + g2 + h1 = SumMS &
    a7 + b6 + c5 + d4 + e3 + f2 + g1 + h8 = SumMS &
    a6 + b5 + c4 + d3 + e2 + f1 + g8 + h7 = SumMS &
    a5 + b4 + c3 + d2 + e1 + f8 + g7 + h6 = SumMS &
    a4 + b3 + c2 + d1 + e8 + f7 + g6 + h5 = SumMS &
    a3 + b2 + c1 + d8 + e7 + f6 + g5 + h4 = SumMS &
    a2 + b1 + c8 + d7 + e6 + f5 + g4 + h3 = SumMS &
    a1 + b8 + c7 + d6 + e5 + f4 + g3 + h2 = SumMS &

    // Rows and colums.
    // Commented out: These constraints are redundant.
 
    a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 = SumMS &
    b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8 = SumMS &
    c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 = SumMS &
    d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 = SumMS &
    e1 + e2 + e3 + e4 + e5 + e6 + e7 + e8 = SumMS &
    f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 = SumMS &
    g1 + g2 + g3 + g4 + g5 + g6 + g7 + g8 = SumMS &
    h1 + h2 + h3 + h4 + h5 + h6 + h7 + h8 = SumMS &

    a1 + b1 + c1 + d1 + e1 + f1 + g1 + h1 = SumMS &
    a2 + b2 + c2 + d2 + e2 + f2 + g2 + h2 = SumMS &
    a3 + b3 + c3 + d3 + e3 + f3 + g3 + h3 = SumMS &
    a4 + b4 + c4 + d4 + e4 + f4 + g4 + h4 = SumMS &
    a5 + b5 + c5 + d5 + e5 + f5 + g5 + h5 = SumMS &
    a6 + b6 + c6 + d6 + e6 + f6 + g6 + h6 = SumMS &
    a7 + b7 + c7 + d7 + e7 + f7 + g7 + h7 = SumMS &
    a8 + b8 + c8 + d8 + e8 + f8 + g8 + h8 = SumMS &
    }

    PrettyPrint8x8(a,0)

//////////////////////////////////////////////////////////////////////
// Print the array in a form of an 8x8 square.
local proc PrettyPrint8x8(ms:<[0..]->L, i:<I) iff
    if i < 8 then
        j = i*8 &
        Print('\n') &
        PrintDigit(ms(j)) &
        PrintDigit(ms(j+1)) &
        PrintDigit(ms(j+2)) &
        PrintDigit(ms(j+3)) &
        PrintDigit(ms(j+4)) &
        PrintDigit(ms(j+5)) &
        PrintDigit(ms(j+6)) &
        PrintDigit(ms(j+7)) &
        PrettyPrint8x8(ms,i+1)
    else
        Print('\n') 
    end

local proc PrintDigit(d:<L) iff
    if d < 10 then
        Print(' ',d,' ')
    else
        Print(d,' ')
    end










This page was created by F1toHTML