/* Game matrix "extraction" in Picat. Given a game/score matrix, extract the individual matches, Wins are 2 points, draws are 1 point. Example: - If the result/scores for four team is [3,3,0,6] then the score matrix is [0,1,2,0] % player 1 [1,0,2,0] % player 2 [0,0,0,0] % player 3 [2,2,2,0] % player 4 Matches: * 1 vs 2: tie, 1 points to each team * 1 vs 3: player 1 wins: 2 points to player 1, 0 points to player 3 * 1 vs 4: player 4 wins: 2 points to player 4 * 2 vs 3: player 2 wins: 2 points to player 2 * 2 vs 4: player 4 wins: 2 points to player 4 * 3 vs 4: player 4 wins: 2 points to player 4 Player 1: 1+2 points = 3 Player 2: 1+2 points = 3 Player 3: 0 points = 0 Player 4: 2+2+2 points = 6 The over all winner is player 4. - On the other hand, the game score of [5,3,2,2] has 7 solutions. The different number of solutions for N=1..6: 1, 3, 27, 729, 59049, 14348907 The number of solutions seems to follow http://oeis.org/A047656 A047656 3^((n^2-n)/2). """ The number of outcomes of a chess tournament with n players. """ Using the decreasing(Result) as symmetry breaking the number of solutions are: 1 = 1 2 = 2 3 = 8 4 = 75 5 = 1755 6 = 113302 7 = 18978011 1,2,8,75,1755,113302,18978011 However, this sequence is not in OEIS. This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. % % All solutions % go ?=> N = 4, % number of players % Result = [3,3,0,6], % unique solution Result = [5,3,2,2], % 7 solutions game(N, Result,X,Z), println(z=Z), println(result=Result), foreach(Row in X) println(Row.to_list()) end, nl, fail, nl. go => true. % % A sample solution for N = 1.. % go2 => foreach(N in 1..100) println(n=N), game(N,Result,X,Z), println(result=Result), println(z=Z), foreach(Row in X) println(Row.to_list()) end, nl end, nl. % % Number of solutions for N=1..10 % go3 => Res = [], foreach(N in 1..10) Sols = count_all(game(N,_Result,_X,_Z)), println(N=Sols), Res := Res ++ [Sols] end, println(res=Res), nl. % % Find result scores that has a unique solution for a certain size. % go4 => N=8, game(N,Result,X,Z), Sols = count_all(game(N,Result,_X2,_Z2)), Sols == 1, println(result=Result), println(z=Z), foreach(Row in X) println(Row.to_list()) end, nl, fail, nl. game(N,Result,X,Z) => Result = new_list(N), Result :: 0..N*N, X = new_array(N,N), X :: 0..2, Z #= sum(Result), Z #= N*(N-1), % decreasing(Result), % symmetry breaking foreach(I in 1..N) X[I,I] #= 0, foreach(J in 1..N, J != I) % X[I,J] #= 2 #<=> X[J,I] #= 0, % X[I,J] #= 1 #<=> X[J,I] #= 1, X[I,J] + X[J,I] #= 2 end, Result[I] #= sum([X[I,J] : J in 1..N] ) end, % Vars = Result ++ X.vars(), Vars = X.vars() ++ Result, solve($[rand_var],Vars). % Use this for "interesting" solutions % solve($[ff,split],Vars). % This is faster but give more boring solutions.