/* How much does each kid weigh? in Picat. From MindYourDecisions """ Singapore nice homework puzzle Four children were experimenting with a scale. As each did not want the others to know their individual mass, they agreed to weigh 3 people at a time. After trying all possible combinations, they kept getting the same four readings on the weighing scale. 63 kg 66 kg 69 kg 72 kg But then they realized the group weighings provided too much information! What is the mass of each child? """ Solution: [18,21,24,27] 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 ?=> W = [63,66,69,72], N = 4, X = new_list(N), X :: 1..W.min, C = 1, foreach(I in 1..N, J in I+1..N, K in J+1..N) T #= X[I] + X[J] + X[K], element(C,W,T), C := C + 1 end, solve(X), println(X), fail, nl. go => true. % Another approach go2 ?=> Ws = [63,66,69,72], N = 4, X = new_list(N), X :: 1..Ws.min, foreach({W,S} in zip(Ws,bool_subsets(N,N-1).sort)) scalar_product(S,X,#=,W) end, solve(X), println(X), fail, nl. go2 => true. % % Brute force, logic programming % Much slower: 1min28s (compared with go/0 and go2/0 which take 2ms). % go3 ?=> Ws = [63,66,69,72], N = 4, X = new_list(N), foreach(I in 1..N) member(X[I],1..Ws.min) end, foreach({W,S} in zip(Ws,bool_subsets(N,N-1).sort)) % scalar_product(S,X,#=,W) sum([S[I]*X[I] : I in 1..N]) == W end, println(X), fail, nl. go3 => true. % Return all boolean subsets of size N for M true values bool_subsets(N,M) = solve_all(S) => S = new_list(N), S :: 0..1, sum(S) #= M.