/* Target practice puzzle (Dudeney) in Picat. """ Colonel Crackham paid a visit one afternoon by invitation to the Slocomb- on-Sea Toxophilite Club, where he picked up the following little poser. Three men in a competition had each six shots at a target, and the result is shown in our illustration, where they all hit the target every time. The bull's- eye scores 50, the next ring 25, the next 20, the next 10, the next 5, the next 3, the next 2, and the outside ring scores only 1. It will be seen that the hits on the target are one bull's-eye, two 25's, three 20's, three lO's, three 1's, and two hits in every other ring. Now the three men tied with an equal score. Next morning the Colonel asked his family to show the exact scoring of each man. Will it take the reader many minutes to find the correct answer? """ This is puzzle #468 from Dudeney's "536 Puzzles and Curious Problems". Since we don't know the order of the people, there are 6 solutions (the permutation of 3 persons): score = 71 {{1,0,0,1,2,1,1,0},{1,1,1,0,0,2,1,0},{1,1,1,1,1,0,0,1}} {{1,0,0,1,2,1,1,0},{1,1,1,1,1,0,0,1},{1,1,1,0,0,2,1,0}} {{1,1,1,0,0,2,1,0},{1,0,0,1,2,1,1,0},{1,1,1,1,1,0,0,1}} {{1,1,1,0,0,2,1,0},{1,1,1,1,1,0,0,1},{1,0,0,1,2,1,1,0}} {{1,1,1,1,1,0,0,1},{1,0,0,1,2,1,1,0},{1,1,1,0,0,2,1,0}} {{1,1,1,1,1,0,0,1},{1,1,1,0,0,2,1,0},{1,0,0,1,2,1,1,0}} We break this symmetry by lex2/1 to get a unique solution: score = 71 {{1,0,0,1,2,1,1,0},{1,1,1,0,0,2,1,0},{1,1,1,1,1,0,0,1}} Person 1: 1x1 5x1 10x2 20x1 25x1 Person 2: 1x1 2x1 3x1 20x2 25x1 Person 3: 1x1 2x1 3x1 5x1 10x1 50x1 This model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> L = [1,2,3,5,10,20,25,50], % the points NumTargets = L.len, % Number of hits per score % "one bull's-eye, two 25's, three 20's, three lO's, three 1's, and two hits in every other ring." Scores = [3,2,2,2,3,3,2,1], NumPeople = 3, NumShots = 6, X = new_array(NumPeople,NumTargets), X :: 0..NumShots, % Same score for each person Score :: 0..NumPeople*max(L), % All get the same score foreach(I in 1..NumPeople) sum(X[I]) #= NumShots, sum([X[I,J]*L[J] : J in 1..NumTargets]) #= Score end, % Cardinality of the scores foreach(S in 1..NumTargets) sum([X[I,S] : I in 1..NumPeople]) #= Scores[S] end, % Symmetry breaking lex2(X), Vars = X.vars ++ [Score], solve(Vars), println(X), println(score=Score), foreach(I in 1..NumPeople) printf("Person %d:", I), foreach(J in 1..NumTargets) if X[I,J] > 0 then printf(" %dx%d ", L[J],X[I,J]) end end, nl end, nl, fail, nl. go => true. lex2(X) => Len = X[1].length, foreach(I in 2..X.length) lex_lt(X[I-1], X[I]) end.