/* PuzzlOR Coins Add up problem in Picat. https://www.informs.org/ORMS-Today/Public-Articles/February-Volume-42-Number-1/PUZZLOR """ Rearrange the coins in Figure 1 so that the sums of the coins across the rows and down the columns match the dollar amounts shown. [ A B C 0.11 B C B 0.12 A B A 0.25 0.21 0.16 0.11 ] Question: In what order do the coins need to be to solve the puzzle? """ Note: I don't know the denomination of the coins, and I'm not sure if this is part of the problem.... This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. import cp. main => go. % % Unknown denominations. % go ?=> N = 3, % convert to cents for easier handling Rows = [11,12,25], Cols = [21,16,11], % the denominations (cents) Denom = new_list(N), Denom :: 1..100, X = new_array(N,N), X :: 1..N, global_cardinality2(X.vars(), [3,3,3]), foreach(I in 1..N) sum([DX : J in 1..N, element(X[I,J], Denom, DX)]) #= Rows[I], sum([DX : J in 1..N, element(X[J,I], Denom, DX)]) #= Cols[I] end, % symmetry breaking increasing(Denom), Vars = X.vars() ++ Denom, solve($[split],Vars), println(denom=Denom), foreach(Row in X) foreach(C in Row) printf("%2d ", Denom[C]) end, nl end, fail, % checking for unicity nl. go => true. % % Variant with known denominations of 1, 5, and 10 cent. % go2 => N = 3, % convert to cents for easier handling Rows = [11,12,25], Cols = [21,16,11], X = new_array(N,N), X :: [1,5,10], global_cardinality(X.vars(), $[1-3,5-3,10-3]), foreach(I in 1..N) sum([X[I,J] : J in 1..N]) #= Rows[I], sum([X[J,I] : J in 1..N]) #= Cols[I] end, Vars = X.vars(), solve($[split],Vars), foreach(Row in X) foreach(C in Row) printf("%2d ", C) end, nl end, nl, fail, % checking for unicity nl. global_cardinality2(A, Gcc) => Len = length(A), Max = length(Gcc), Gcc :: 0..Len, foreach(I in 1..Max) count(I,A,#=,Gcc[I]) end. increasing(List) => foreach(I in 2..List.length) List[I-1] #=< List[I] end.