//------------------------------------------------------------------- // enigma1349.c (c) 2005 by Charles Petzold (www.charlespetzold.com) // // "Alphabetic Magic" by Colin Singleton, New Scientist, 16 July 2005, page 52. // // A 3-by-3 magic square of nine different non-consecutive numbers // less than 50. Horizontals, verticals, diagonals all total equally. // // The length of the text representations of the numbers also form // a magic square. What are the row/column/diagontal totals of each? //------------------------------------------------------------------- #include #include #define MAX 50 // If A is a 3-by-3 array of integers, check that the integers // are unique. int Unique(int A[][3]) { int i, Test[MAX]; for (i = 0; i < MAX; i++) Test[i] = 0; // For code ease, treat the array as a 9-element // one-dimensional array rather than a 3-by-3. // (A bonus for using C.) for (i = 0; i < 9; i++) { if (A[0][i] < 1 || A[0][1] >= MAX) return 0; if (Test[A[0][i]]) return 0; Test[A[0][i]] = 1; } return 1; } int main(void) { char * NumberNames[MAX] = { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty", "TwentyOne", "TwentyTwo", "TwentyThree", "TwentyFour", "TwentyFive", "TwentySix", "TwentySeven", "TwentyEight", "TwentyNine", "Thirty", "ThirtyOne", "ThirtyTwo", "ThirtyThree", "ThirtyFour", "ThirtyFive", "ThirtySix", "ThirtySeven", "ThirtyEight", "ThirtyNine", "Forty", "FortyOne", "FortyTwo", "FortyThree", "FortyFour", "FortyFive", "FortySix", "FortySeven", "FortyEight", "FortyNine" }; // A is the magic square of numbers. // B is the magic square of number name lengths. int i, A[3][3], B[3][3], Atotal, Btotal; // Loop through the first four elements. for (A[0][0] = 1; A[0][0] < MAX; A[0][0]++) for (A[0][1] = 1; A[0][1] < MAX; A[0][1]++) for (A[0][2] = 1; A[0][2] < MAX; A[0][2]++) for (A[1][0] = 1; A[1][0] < MAX; A[1][0]++) { // The row/col/diag total is implied by three cells. Atotal = A[0][0] + A[0][1] + A[0][2]; // Across 1 // The other squares are then implied. A[2][0] = Atotal - A[0][0] - A[1][0]; // down 1 A[1][1] = Atotal - A[0][2] - A[2][0]; // diag A[2][1] = Atotal - A[0][1] - A[1][1]; // down 2 A[1][2] = Atotal - A[1][0] - A[1][1]; // Across 2 A[2][2] = Atotal - A[0][2] - A[1][2]; // down 3 // Perform a couple consistency checks. if (A[2][0] + A[2][1] + A[2][2] != Atotal) // Across 3 continue; if (A[0][0] + A[1][1] + A[2][2] != Atotal) // diag continue; // Now determine if the numbers are unique. if (!Unique(A)) continue; // Now find the elements of the B array. for (i = 0; i < 9; i++) { B[0][i] = strlen(NumberNames[A[0][i]]); } // Again, check uniqueness. if (!Unique(B)) continue; // Do all the consistency checks. Btotal = B[0][0] + B[0][1] + B[0][2]; if (Btotal != B[1][0] + B[1][1] + B[1][2]) continue; if (Btotal != B[2][0] + B[2][1] + B[2][2]) continue; if (Btotal != B[0][0] + B[1][0] + B[2][0]) continue; if (Btotal != B[0][1] + B[1][1] + B[2][1]) continue; if (Btotal != B[0][2] + B[1][2] + B[2][2]) continue; if (Btotal != B[0][0] + B[1][1] + B[2][2]) continue; if (Btotal != B[2][0] + B[1][1] + B[0][2]) continue; // We found a solution. Print the cells and totals. printf("Number Square: "); for (i = 0; i < 9; i++) printf("%i ", A[0][i]); printf("= %i\n\n", Atotal); printf("Length Square: "); for (i = 0; i < 9; i++) printf("%i ", B[0][i]); printf("= %i\n", Btotal); return 0; } return 0; }