Permutations of pairs vs pairs

67 Views Asked by At

I want to create a league for table football where there is two people vs two people. There would be a match for every combination of pair vs every combination of pair. So, given the following players: A, B, C, D and E, the following games would be generated (I only included the games which player A was in but there would be other games too):

A,B vs C,D
A,B vs C,E
A,B vs D,E
A,C vs B,D
A,C vs B,E
A,C vs D,E
A,D vs B,C
A,D vs B,E
A,D vs C,E
A,E vs B,C
A,E vs B,D
A,E vs C,E

Is there an algorithm to do this easily? I could do this by hand if there was only 5 players but there is likely to be 10+.

1

There are 1 best solutions below

0
On

You can do that automatically, yes.

Assume the players are numberd $1$ to $n$. Then:

  1. Take a first player in the list.
  2. Take a second player among the remaining players with a higher number.
  3. Take a third player among the remaining players with a higher number than the first, and different than the second.
  4. Take a fourth player among the remaining players with a higher number than the third, and different than the second.

That is, among all possible 4-tuples of different players, keep only [(a,b), (c,d)] with $a<b, a<c, c<d$. The purpose of picking only players "with a higher number" is to remove duplicates, as for instance, for playing purposes I assume [(1,2), (3,4)] is identical to [(3,4), (1,2)], [(2,1), (3,4)], [(1,2), (4,3)], [(2,1), (4,3)], [(4,3), (1,2)], [(3,4), (2,1)] and [(4,3), (2,1)]. But if you consider also the position of players within pairs, you can do that too: just change the conditions.

In Python:

def twopairs(n):
    for first in range(1, n + 1):
        for second in range(first + 1, n + 1):
            for third in range(first + 1, n + 1):
                if third != second:
                    for fourth in range(third + 1, n + 1):
                        if fourth != second:
                            yield [(first, second), (third, fourth)]

For instance:

>>> for p in twopairs(5): print(p)

[(1, 2), (3, 4)]
[(1, 2), (3, 5)]
[(1, 2), (4, 5)]
[(1, 3), (2, 4)]
[(1, 3), (2, 5)]
[(1, 3), (4, 5)]
[(1, 4), (2, 3)]
[(1, 4), (2, 5)]
[(1, 4), (3, 5)]
[(1, 5), (2, 3)]
[(1, 5), (2, 4)]
[(1, 5), (3, 4)]
[(2, 3), (4, 5)]
[(2, 4), (3, 5)]
[(2, 5), (3, 4)]

This can be done more shortly with:

import itertools
def twopairs2(n):
    for a, b, c, d in itertools.permutations(range(1, n + 1), 4):
        if a < b and a < c and c < d:
            yield [(a, b), (c, d)]

But note that the number of such games grows quite quickly. For instance:

>>> sum(1 for p in twopairs(10))
630
>>> sum(1 for p in twopairs(20))
14535
>>> sum(1 for p in twopairs(30))
82215