/* Rolling three dice in Picat. From Chris Smith Math Newsletter #603 """ Levi rolled three dice and tells Shiloh that multiplying the numbers gives him a number that is twice as big as if he’d added them up. Shiloh says she can’t tell what Levi’s numbers are so he offers to show her the dice with the smallest number. Shiloh replies to say that she doesn’t need to – she now knows the three numbers. What did Levi roll?? """ Solution: [[1,4,5],[2,2,4]] this = [1,4,5] not_this = [2,2,4] The following configurations of number of dice and multiplications are also valid (go2/0): [num_dice = 2,mult = 2] [num_dice = 3,mult = 2] [num_dice = 3,mult = 3] [num_dice = 4,mult = 4] [num_dice = 5,mult = 4] [num_dice = 6,mult = 4] 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 => L=new_list(3), L::1..6, % Levi rolled three dice and tells Shiloh that multiplying the numbers % gives him a number that is twice as big as if he’d added them up. S #= sum(L), P #= prod(L), S*2 #= P, % symmetry breaking increasing(L), All=solve_all(L), println(All), % Shiloh says she can’t tell what Levi’s numbers are so he offers to show % her the dice with the smallest number. foreach(A in All) if A[1] < A[2] then println(this=A) else println(not_this=A) end end, nl. % General version go2 => OKs = [], foreach(NumDice in 2..6, Mult in 2..6) println([numDice=NumDice,mult=Mult]), rolling_dice(NumDice,Mult,All,OK), nl, if OK then OKs := OKs ++ [[num_dice=NumDice,mult=Mult]] end end, println("OKs:"), foreach(O in OKs) println(O) end, nl. % General version rolling_dice(NumDice,Mult ,All,OK) => L=new_list(NumDice), L::1..6, % Levi rolled dice and tells Shiloh that multiplying the numbers % gives him a number that is as big as if he’d added them up. S #= sum(L), P #= prod(L), S*Mult #= P, % symmetry breaking increasing(L), All=solve_all(L), println(All), % Shiloh says she can’t tell what Levi’s numbers are so he offers to show % her the dice with the smallest number. NumSols = 0, NumNotSols = 0, foreach(A in All) if A[1] < A[2] then println(this=A), NumSols := NumSols + 1 else println(not_this=A), NumNotSols := NumNotSols + 1 end end, if NumSols == 1, NumNotSols > 0 then println(ok), OK = true else println(not_ok), OK = false end, nl.