/////////////////////////////////////////////////////////////////////////////// // // 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