/* Enigma problem 843 (How many are whole?) in Picat. Problem formulation from http://magma.maths.usyd.edu.au/magma/Examples/node4.html """ The problem `How many are whole?', by Susan Denham, was taken from New Scientist No. 1998 (7 Oct 1995), in the Enigma problem section on p. 63. [...] The Problem: In what follows, digits have been consistently replaced by letters, with different letters being used for different digits: In the list ONE TWO THREE FOUR just the first and one other are perfect squares. In the list ONE+1 TWO+1 THREE+1 FOUR+1 just one is a perfect square. In the list ONE+2 TWO+2 THREE+2 FOUR+2 just one is a perfect square. If you want to win the prize send in your FORTUNE. ... The answer published a few weeks later was FORTUNE = 3701284. """ 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 ?=> X = [O,N,E,T,W,H,R,F,U], X :: 0..9, ONE :: 100..999, TWO :: 100..999, THREE :: 10000..99999, FOUR :: 1000..9999, FORTUNE :: 1000000..9999999, all_different(X), to_num([O,N,E], ONE), to_num([T,W,O], TWO), to_num([T,H,R,E,E], THREE), to_num([F,O,U,R], FOUR), to_num([F,O,R,T,U,N,E], FORTUNE), B = new_list(12), B :: 0..1, B[1] #= 1, % In the list ONE TWO THREE FOUR just the first and one other are perfect squares. square(ONE,B[1]), square(TWO,B[2]), square(THREE,B[3]), square(FOUR,B[4]), sum(B[2..4]) #= 1, % % % In the list ONE+1 TWO+1 THREE+1 FOUR+1 just one is a perfect square. square($(ONE+1),B[5]), square($(TWO+1),B[6]),square($(THREE+1),B[7]),square($(FOUR+1),B[8]), sum(B[5..8]) #= 1, % % In the list ONE+2 TWO+2 THREE+2 FOUR+2 just one is a perfect square. square($(ONE+2),B[9]), square($(TWO+2),B[10]),square($(THREE+2),B[11]),square($(FOUR+2),B[12]), sum(B[9..12]) #= 1, Vars = X ++ B ++ [ONE,TWO,THREE,FOUR,FORTUNE], solve($[ffd],Vars), println(x=X), println(one=ONE), println(two=TWO), println(three=THREE), println(four=FOUR), println(fortune=FORTUNE), nl, fail, nl. go => true. % base 10 to_num(List, Num) => Len = length(List), Num #= sum([List[I]*10**(Len-I) : I in 1..Len]). % % Ensure that X is an square. % We have to trick a little since "X" is not a single variable, but an expression, and % thus we cannot use fd_min_max/3. By creating XX #= X we make XX a single variable. % square(X, B) => XX #= X, fd_min_max(XX,Min,Max), Y :: ceiling(sqrt(Min))..ceiling(sqrt(Max)), Y*Y #= XX #<=> B #= 1.