/* Pizzas in Picat. From https://en.wikibooks.org/wiki/Puzzles/Logic_puzzles/Pizzas """ Aaron, Betty, Charlie, Debbie, and Eric each ordered a pizza with three of the following five toppings: green pepper, mushrooms, onions, pepperoni, and sausage. The only topping that Aaron and Charlie had in common was sausage. The only topping Debbie and Eric had in common was pepperoni. The only topping Charlie and Betty had in common was mushrooms. The only topping Debbie and Betty had in common was green pepper. Which toppings did each of them have on their pizza? """ Aaron : [Green Pepper,Onions,Sausage] Bettty : [Green Pepper,Mushrooms,Onions] Charlie: [Mushrooms,Pepperoni,Sausage] Debbie : [Green Pepper,Pepperoni,Sausage] Eric : [Mushrooms,Onions,Pepperoni] This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> Toppings = [GreenPepper, Mushrooms, _Onions, Pepperoni, Sausage], Toppings = [1,2,3,4,5], ToppingsS = ["Green Pepper", "Mushrooms", "Onions", "Pepperoni", "Sausage"], Names = ["Aaron","Bettty","Charlie","Debbie","Eric"], NumToppings = 3, NumPeople = Names.len, People = new_array(NumPeople,NumToppings), {Aaron,Betty,Charlie,Debbie,Eric} = People, People :: Toppings, foreach(P in People) increasing_strict(P) end, % The specific constraints Cs = [ [Aaron,Charlie,Sausage], [Debbie,Eric,Pepperoni], [Charlie,Betty,Mushrooms], [Debbie,Betty,GreenPepper]], foreach([A,B,Topping] in Cs) % Exact one topping in common element(_,A,Topping), element(_,B,Topping), count_same(A,B,1) end, solve(People), foreach(P in 1..NumPeople) printf("%-7s: %w\n", Names[P],[ToppingsS[I] : I in People[P]]) end, nl, fail, nl. go => true. count_same(A,B,N) => Len = A.len, N #= sum([A[I] #= B[J] : I in 1..Len, J in 1..Len]).