Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groups of unique pairs where members appear once per group

I have this code:

from itertools import groupby
from itertools import combinations


teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
combo = list(combinations(teams, 2))

The output is a list of 45 tuples.

[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 7), (6, 8), (6, 9), (6, 10), (7, 8), (7, 9), (7, 10), (8, 9), (8, 10), (9, 10)]

I would like to divide 45 tuples into 9 groups of 5 tuples, each of which are unique items. For example like so:

list_1 = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
list_2 = [(1, 3), (2, 4), (5, 7), (6, 9), (8, 10)]
list_3 = 
list_4 = 
list_5 = 

So each list contains tuples with items from 1 to 10 without repetition.

like image 216
olyashevska Avatar asked Jun 03 '19 13:06

olyashevska


1 Answers

Here is a fairly straightforward approach based on a round robin tournament scheduling algorithm. Basically, this approach splits the list in half and pairs the first half of the list with a reversed version of the second half of the list. Then, for each stage it "rotates" all teams except for the first team in the list (the loop and list concatenation based on the stage or round number is simulating the rotation).

# even number of teams required
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
n = int(len(teams) / 2)

stages = []
for i in range(len(teams) - 1):
    t = teams[:1] + teams[-i:] + teams[1:-i] if i else teams
    stages.append(list(zip(t[:n], reversed(t[n:]))))

print(stages)
# [
#     [(1, 10), (2, 9), (3, 8), (4, 7), (5, 6)],
#     [(1, 9), (10, 8), (2, 7), (3, 6), (4, 5)],
#     [(1, 8), (9, 7), (10, 6), (2, 5), (3, 4)],
#     [(1, 7), (8, 6), (9, 5), (10, 4), (2, 3)],
#     [(1, 6), (7, 5), (8, 4), (9, 3), (10, 2)],
#     [(1, 5), (6, 4), (7, 3), (8, 2), (9, 10)],
#     [(1, 4), (5, 3), (6, 2), (7, 10), (8, 9)],
#     [(1, 3), (4, 2), (5, 10), (6, 9), (7, 8)],
#     [(1, 2), (3, 10), (4, 9), (5, 8), (6, 7)]
# ]
like image 96
benvc Avatar answered Nov 12 '22 05:11

benvc