# Stochastic problem

I have to organize a small sports league and I am puzzled on how to create the game plan.

We are 8 persons playing table soccer with 2 vs. 2 matches. The idea is that each person plays once with every other person. So e.g. person 1 will play once with person 2, 3, 4, 5, 6, 7 and 8. So there are 7 matchdays and 2 games on each. If a team wins both players receive a point. At the end of the season a player can have earned a max of 7 points.

E.g. matchday 1: p1&p2; p3&p4; p5&p6; p7&p8 E.g. matchday 2: p1&p3; p2&p4; p5&p7; p6&p8

How can I calculate the teams for each of the seven game days given the conditions above? Since the strongest two teams would play against each other depending on points collected in the earlier games I only need a set of 4 teams for each matchday.

I would be grateful for some smart help on calculating a game plan. I guess I am stuck here:

players = Range[1, 8]; teams = Select[Subsets[players , 2], Length[#] == 2 &];

Thanks a lot Patrick

• Not sure whether I understand the problem, but would this work? players = Range[1, 8]; teams = Subsets[players, {2}]? The {2} restricts the subsets to those of length 2. Commented Jun 3, 2013 at 21:25
• The tricky thing is to create a game plan where each player plays once with each other having all players play once per match day. Commented Jun 4, 2013 at 7:06
• In excel I can do this manually but I wonder if there are one or two formulas doing this automatically. Commented Jun 4, 2013 at 7:06

The number of players is relatively short, so we can brute-force the problem. There are only 8! = 40,320 different arrangements of players and it is easy enough to generate them all and then filter them:

longList = (Sort /@ Partition[#, 2]) & /@ Permutations[Range@8];

Union[longList, SameTest -> (Or @@ Flatten[Outer[Equal, #1, #2, 1]] &)]


{{{1, 2}, {3, 4}, {5, 6}, {7, 8}}, {{1, 3}, {2, 4}, {5, 7}, {6, 8}}, {{1, 4}, {2, 3}, {5, 8}, {6, 7}}, {{1, 5}, {2, 6}, {3, 7}, {4, 8}}, {{1, 6}, {2, 5}, {3, 8}, {4, 7}}, {{1, 7}, {2, 8}, {3, 5}, {4, 6}}, {{1, 8}, {2, 7}, {3, 6}, {4, 5}}}

It basically does the following:

1. Permutations are generated, partitioned in pairs, and sorted because {1,2} equals {2, 1} for our purposes
2. Union is then used to weed out any partitioned permutation that has at least one pair already seen before (the SameTest function is defined such that it is True if this is the case).
• Thanks! It is amazing every time what can be done with only a fraction of code. It is also a nice fraction to better understand short syntax like Range@8. Commented Jun 10, 2013 at 7:24
• Regards from Berlin! Commented Jun 10, 2013 at 7:25
• @PatrickBernhard You're welcome. Glad you like it. Commented Jun 10, 2013 at 7:41
• Well, by now I got 4 more colleagues from my company wanting to join the table soccer league - leaving me with the task create a match plan for 12 instead for 8 people. Both solutions work super cool for 8 - but for 12 my computer goes down. Any trick to cope with that performance issue? Commented Jun 19, 2013 at 15:15

Just a longer non-optimal alternative. This problem must have way cleaner solutions. I'll give it more thought in my sleep (or not)

SetAttributes[{team, matchDay}, Orderless];
players = player /@ Range@8;


There are only 7!!==105 possible match days you can build. One could build them up and then just find a combination in which every player plays only once with each other

Ugly way to build the candidates

matchDayCandidates =
matchDay @@@ (team @@@ Partition[#, 2] & /@ Permutations[players]);


Length@matchDayCandidates == 7!! gives True, good sign.

Ugly way to filter them to get a possible result

Reap[
NestWhile[(Sow[First@#];
DeleteCases[#, matchDay[Alternatives @@ First@#, __]]) &,
matchDayCandidates, # =!= {} &]
][[-1, 1]]