/* Enigma #1577 (Happy New Year) in Picat. From New Scientist: http://www.newscientist.com/article/mg20527420.900-enigma-number-1577.html """ 06 January 2010 by Richard England Happy New Year I have written down three 3-digit numbers which between them use nine different digits. One of the numbers is a perfect square and another is a triangular number. The sum of the three numbers is 2010. What, in ascending order, are the three numbers? """ See another approach on this problem: http://hakank.org/picat/enigma_1577_happy_new_year.pi Note: Compare this with the Pandigital Numbers model: http://hakank.org/picat/pandigital_numbers.pi However, this problem is easier since we know that there are three 3 digit numbers. This current model is based on the MiniZinc model http://hakank.org/minizinc/enigma_1577_happy_new_year.mzn This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> N = 9, X = new_list(N), X :: 0..9, Nums = [Num1,Num2,Num3], Nums :: 100..999, % The three digit triangular numbers. % Cf http://www.research.att.com/~njas/sequences/A000217 Triangular = [S : I in 14..44, S=sum([J : J in 1..I])], % The three digit squares % Cf http://www.research.att.com/~njas/sequences/A000290 Squares = [S2 : I in 10..31, S2=I*I], % unique digits all_different(X), % % First: construct the pandigital numbers % to_num(X[1..3], 10, Num1), to_num(X[4..6], 10, Num2), to_num(X[7..9], 10, Num3), % symmetry breaking: ascending order increasing(Nums), % the sum of the three numbers is 2010 sum(Nums) #= 2010, % one of the numbers is a perfect square (Num1 in Squares #\/ Num2 in Squares #\/ Num3 in Squares), % and another is a triangular number (Num1 in Triangular #\/ Num2 in Triangular #\/ Num3 in Triangular), Vars = X ++ Nums, solve(Vars), println(x=X), println(nums=Nums), fail, nl. go => true. % % 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]).