/* Enigma 995 by Susan Denham (New Scientist 5/9/98) This is the layout of the digit buttons on my telephone. 1 2 3 My boss's telephone number uses each of the ten digits 4 5 6 once and it starts with 0. Furthermore each pair of 7 8 9 adjacent digits is also adjacent (horizontally, vertically 0 or diagonally) on the telephone keyboard. (By coincidence my own number, 0895632147, has the same properties.) I have just looked through my boss's telephone number and written down a list of all the two-figure numbers that can be seen in it by reading a pair of adjacent digits (which would be 89, 95, 56... in my number). In that list, some of the numbers are special in that they consist of two digits which are also consecutive (such as 89, 56, 32 and 21 in my number). I have worked out the product of those special numbers and it is the year in which my boss will be 50. And if I look at the number of the year in which she was born, no two adjacent digits are adjacent (either way round) in her telephone number. What is her telephone number? */ /* ECLiPSe solution by Joachim Schimpf, IC-Parc Note that there is an implicit assumption that the boss is not very young: there are a couple of solutions with a birth year of 1997 :-) */ :- lib(ic). solve(Number-YearOfBirth) :- length(Number, 10), % A 10-digit phone number Number :: 0..9, Number = [0|_], % the first is zero alldifferent(Number), % all 10 digits are used adjacent_pairs(Number, Pairs), % look at the pairs ( foreach(X-Y, Pairs), fromto(1, Product, Product*XYor1, Year50) do adjacent_on_keypad(X,Y), % each pair is adjacent, and XYor1 :: 1..98, % a potential factor for the pair_factor(X,Y,XYor1) % year computation ), YearOfBirth #= eval(Year50) - 50,% this is the year of birth YearOfBirth :: 1938..1996, % she's not yet 50 in 1998 [Y1,Y2,Y3,Y4] :: 0..9, % look at the year's digits YearOfBirth #= 1000*Y1+100*Y2+10*Y3+Y4, ( foreach(Yi-Yj, [Y1-Y2,Y2-Y3,Y3-Y4]), param(Pairs) do ( foreach(X-Y, Pairs), param(Yi,Yj) do X-Y ~= Yi-Yj, % pairs are not similar to X-Y ~= Yj-Yi % the phone number pairs ) ), labeling(Number). % find a solution! % build a list of pairs of adjacent elements in List adjacent_pairs(List, Pairs) :- ( fromto(List, [X,Y|Rest], [Y|Rest], [_]), fromto(Pairs, [X-Y|Pairs1], Pairs1, []) do true ). % wait until X and Y are instantiated, then bind XYor1 to X*Y or 1 delay pair_factor(X,Y,_XYor1) if var(X);var(Y). pair_factor(X, Y, XYor1) :- ( abs(X-Y) =:= 1 -> XYor1 is 10*X+Y ; XYor1 = 1 ). % wait until X and Y are instantiated, then check adjacency delay adjacent_on_keypad(X,Y) if var(X);var(Y). adjacent_on_keypad(X,Y) :- adjacent_on_keypad1(Y,X). adjacent_on_keypad(X,Y) :- adjacent_on_keypad1(X,Y). adjacent_on_keypad1(1,2). % horizontal adjacent_on_keypad1(2,3). adjacent_on_keypad1(4,5). adjacent_on_keypad1(5,6). adjacent_on_keypad1(7,8). adjacent_on_keypad1(8,9). adjacent_on_keypad1(1,4). % vertical adjacent_on_keypad1(4,7). adjacent_on_keypad1(2,5). adjacent_on_keypad1(5,8). adjacent_on_keypad1(8,0). adjacent_on_keypad1(3,6). adjacent_on_keypad1(6,9). adjacent_on_keypad1(2,6). % down diagonal adjacent_on_keypad1(1,5). adjacent_on_keypad1(5,9). adjacent_on_keypad1(4,8). adjacent_on_keypad1(7,0). adjacent_on_keypad1(2,4). % up diagonal adjacent_on_keypad1(3,5). adjacent_on_keypad1(5,7). adjacent_on_keypad1(6,8). adjacent_on_keypad1(9,0).