/* The Ten barrels puzzle in Picat. Puzzle #462 from Dudeney "536 Puzzles and curious problems": """ A merchant had ten barrels of sugar, which he placed in the form of a pyramid, as shown below in the left picture. Every barrel bore a different number, except one, which was not marked. It will be seen that he had accidentally arranged them so that the numbers in the three sides added up alike, that is, to 16. Can you rearrange them so that the three sides shall sum up to the smallest number possible? Of course the central barrel (which happens to be 7 in the illustration) does not come into the count. 1 8 9 4 7 0 3 5 2 6 """ Indexes for the constraints: 1 2 3 4 5 6 7 8 9 10 Without symmetry breaking there are 96 optimal solutions with sum=13. With symmetry breaking there are 8 optimal solutions: sum = 13 1 3 4 7 9 8 2 5 6 0 sum = 13 1 3 4 7 9 8 2 6 5 0 sum = 13 1 4 5 6 9 7 2 3 8 0 sum = 13 1 4 5 6 9 7 2 8 3 0 sum = 13 1 6 7 4 9 5 2 3 8 0 sum = 13 1 6 7 4 9 5 2 8 3 0 sum = 13 1 7 8 3 9 4 2 5 6 0 sum = 13 1 7 8 3 9 4 2 6 5 0 Num solutions = 8 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 ?=> ten_barrels(X,Sum), print_solution(X,Sum), println("\nFind all optimal solutions (w symmetry breaking):"), All = findall(X2,ten_barrels(X2,Sum)), foreach(Sol in All) print_solution(Sol,Sum), nl end, nl, println("Num solutions"=All.len), nl. go => true. print_solution(X,Sum) => println(x=X), println(sum=Sum), printf(" %d\n",X[1]), printf(" %d %d\n",X[2],X[3]), printf(" %d %d %d\n",X[4],X[5],X[6]), printf(" %d %d %d %d\n",X[7],X[8],X[9],X[10]), nl. ten_barrels(X,Sum) => N = 10, Indices = [[1,2,4,7],[1,3,6,10],[7,8,9,10]], if var(Sum) then println(sum=Sum), Sum :: 0..9*4 end, X = new_list(N), X :: 0..9, all_different(X), foreach(S in Indices) sum([X[I] : I in S]) #= Sum end, % Symmetry breaking X[1] #< X[2], X[2] #< X[3], X[4] #< X[6], if var(Sum) then println(varSum), Vars = X ++ [Sum], solve($[min(Sum)],Vars) else solve(X) end.