//--------------------------------------------------------------------------------- // Enigma1341.c (c) 2005 by Charles Petzold (www.charlespetzold.com) // // "Two, Three, Four" problem from "New Scientist" magazine, 21 May 2005, page 32. // // If letters stand for decimal digits (uniquely), TWO is prime, THREE is // triangular, and FOUR is a perfect square. None begin with 0. //--------------------------------------------------------------------------------- #include // Construct a 5-digit number from its five digits int Number(int i4, int i3, int i2, int i1, int i0) { return 10000 * i4 + 1000 * i3 + 100 * i2 + 10 * i1 + i0; } // Returns 1 if argument (> 1) is prime. int IsPrime(int i) { int j = 2; while (j * j <= i) { if (i % j == 0) return 0; j += 1; } return 1; } // Returns 1 if argument is triangular int IsTriangular(int i) { int j = 1; while (j * (j + 1) / 2 <= i) { if (j * (j + 1) / 2 == i) return 1; j++; } return 0; } // Returns 1 if argument is square int IsSquare(int i) { int j = 1; while (j * j <= i) { if (j * j == i) return 1; j++; } return 0; } // Function to prevent multiple letters being the same digit. // When setting a letter to a digit, pass the letter variable // as the first argument and 1 as the second. // If 1 is returned, the digit is already used. // When finished using a digit, pass 0 as the second argument. int DigitIsUsed(int Digit, int Insert) { static int Digits[10]; if (Insert && Digits[Digit]) return 1; Digits[Digit] = Insert; return 0; } int main(void) { int E, F, H, O, R, T, U, W, TWO, THREE, FOUR; for (E = 0; E <= 9; E ++) { DigitIsUsed(E, 1); for (F = 1; F <= 9; F++) // F can't be zero. { if (DigitIsUsed(F, 1)) continue; for (H = 0; H <= 9; H++) { if (DigitIsUsed(H, 1)) continue; for (O = 0; O <= 9; O++) { if (DigitIsUsed(O, 1)) continue; for (R = 0; R <= 9; R++) { if (DigitIsUsed(R, 1)) continue; for (T = 1; T <= 9; T++) // T can't be zero { if (DigitIsUsed(T, 1)) continue; for (U = 0; U <= 9; U++) { if (DigitIsUsed(U, 1)) continue; for (W = 0; W <= 9; W++) { if (DigitIsUsed(W, 1)) continue; TWO = Number(0, 0, T, W, O); THREE = Number(T, H, R, E, E); FOUR = Number(0, F, O, U, R); if (IsPrime(TWO) && IsTriangular(THREE) && IsSquare(FOUR)) printf("TWO = %i, THREE = %i, FOUR = %i\n", TWO, THREE, FOUR); DigitIsUsed(W, 0); } DigitIsUsed(U, 0); } DigitIsUsed(T, 0); } DigitIsUsed(R, 0); } DigitIsUsed(O, 0); } DigitIsUsed(H, 0); } DigitIsUsed(F, 0); } DigitIsUsed(E, 0); } return 0; }