/* Pandigital numbers in Picat. From Albert H. Beiler "Recreations in the Theory of Numbers", quoted from http://www.worldofnumbers.com/ninedig1.htm """ [ Chapter VIII : Digits - and the magic of 9 ] [ I found the same exposé in Shakuntala Devi's book "Figuring : The Joy of Numbers" ] The following curious table shows how to arrange the 9 digits so that the product of 2 groups is equal to a number represented by the remaining digits." 12 x 483 = 5796 42 x 138 = 5796 18 x 297 = 5346 27 x 198 = 5346 39 x 186 = 7254 48 x 159 = 7632 28 x 157 = 4396 4 x 1738 = 6952 4 x 1963 = 7852 """ See also * MathWorld http://mathworld.wolfram.com/PandigitalNumber.html """ A number is said to be pandigital if it contains each of the digits from 0 to 9 (and whose leading digit must be nonzero). However, "zeroless" pandigital quantities contain the digits 1 through 9. Sometimes exclusivity is also required so that each digit is restricted to appear exactly once. """ * Wikipedia http://en.wikipedia.org/wiki/Pandigital_number Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => L = findall([X1,X2,X3], pandigital([X1,X2,X3])), Len = length(L), writeln(len=Len). scalar_product(A, X, Product) => Product #= sum([A[I]*X[I] : I in 1..A.length]). % % converts a number Num to/from a list of integer List given a base Base % to_num(List, Base, Num) => Len = length(List), Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]). pandigital([X1,X2,X3]) => % % length of numbers % % Len1 #>= 1, % Len1 #=< 4, % Len2 #>= 1, % Len2 #=< 4, % Len3 #= 4, Len1 :: 1..2, Len2 :: 3..4, Len3 #= 4, % Len1 #=< Len2, % symmetry breaking Len1 + Len2 + Len3 #= 9, indomain(Len1), % set length of lists X1 = new_list(Len1), X1 :: 1..9, X2 = new_list(Len2), X2 :: 1..9, X3 = new_list(Len3), % the result X3 :: 1..9, % convert to number Base = 10, to_num(X1, Base, Num1), to_num(X2, Base, Num2), to_num(X3, Base, Res), % calculate result Num1 * Num2 #= Res, Vars = X1 ++ X2 ++ X3, all_different(Vars), % search solve(Vars), writef("%2d * %4d = %4d\n",Num1,Num2,Res). % writeln([X1,X2,X3]).