Skip to content

Instantly share code, notes, and snippets.

@MaxHalford
Last active September 1, 2023 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaxHalford/c24f50d4ed7bd7afcc87459f4fa76794 to your computer and use it in GitHub Desktop.
Save MaxHalford/c24f50d4ed7bd7afcc87459f4fa76794 to your computer and use it in GitHub Desktop.
Sports schedule planning
A friend of mine is a sports teacher teacher. He is organising a tournament, and gave me the following problem:
- 24 teams
- 12 sports
- Each sport takes place between 2 teams
- There are 12 time slots
- Each team needs to play each sports over the 12 time slots
- Ideally, each team should try to face every other team
This isn't possible, but there is a way to make each team play against 4 other teams over 3 sports.
It's easy to prove it isn't possible for every team to meet each other by looking at the case of 4 teams and 2 sports. If A and B play sport 1, and C opposes D on sport 2, then during the next session A will have to play B again on sport 2. The only way for all teams to meet each other is to have some sports repeat themselves.
import string
import numpy as np
import pandas as pd
teams = [c.upper() for c in string.ascii_lowercase[:24]]
activities = list(range(1, 13))
groups = [teams[0:6], teams[6:12], teams[12:18], teams[18:24]]
matches = []
for stage in range(4):
# Determine activities for each group during this stage
group_activities = np.roll([activities[0:3], activities[3:6], activities[6:9], activities[9:12]], stage, axis=0)
# Determine pairs within each group for this stage
if stage == 0:
group_pairs = [
[(group[0], group[1]),
(group[2], group[3]),
(group[4], group[5])]
for group in groups
]
if stage == 1:
group_pairs = [
[(group[0], group[2]),
(group[1], group[4]),
(group[2], group[5])]
for group in groups
]
if stage == 2:
group_pairs = [
[(group[0], group[3]),
(group[1], group[5]),
(group[2], group[4])]
for group in groups
]
if stage == 3:
group_pairs = [
[(group[0], group[4]),
(group[1], group[2]),
(group[3], group[5])]
for group in groups
]
# Determine matches for each hour of this stage
for hour in range(3):
for i, group in enumerate(group_pairs):
for j, pair in enumerate(group):
matches.append((stage, hour, pair[0], pair[1], group_activities[i][(hour + j) % 3]))
matches_df = pd.DataFrame(matches, columns=['stage', 'hour', 'team1', 'team2', 'activity'])
matches_df['step'] = matches_df['stage'] * 3 + matches_df['hour']
activities = {
1: 'Biathlon',
2: 'Karting',
3: 'Mur interactif',
4: 'Ultimate',
5: 'Golf',
6: 'Handball',
7: 'Beach volley',
8: 'Escalade',
9: 'Badminton',
10: 'Molky',
11: 'Béret',
12: 'Course à l\'aveugle'
}
def to_num(team):
return ord(team) - ord('A') + 1
# Mix it up
for i, step in enumerate([0, 3, 6, 9, 1, 4, 7, 10, 2, 5, 8, 11]):
print((t := f'Session #{i + 1}'))
print('-' * len(t))
for team1, team2, activity in matches_df.query('step == @step')[['team1', 'team2', 'activity']].values:
print(to_num(team1), 'vs', to_num(team2), '->', activities[activity])
print('')
Session #1
----------
1 vs 2 -> Biathlon
3 vs 4 -> Karting
5 vs 6 -> Mur interactif
7 vs 8 -> Ultimate
9 vs 10 -> Golf
11 vs 12 -> Handball
13 vs 14 -> Beach volley
15 vs 16 -> Escalade
17 vs 18 -> Badminton
19 vs 20 -> Molky
21 vs 22 -> Béret
23 vs 24 -> Course à l'aveugle
Session #2
----------
1 vs 3 -> Molky
2 vs 5 -> Béret
3 vs 6 -> Course à l'aveugle
7 vs 9 -> Biathlon
8 vs 11 -> Karting
9 vs 12 -> Mur interactif
13 vs 15 -> Ultimate
14 vs 17 -> Golf
15 vs 18 -> Handball
19 vs 21 -> Beach volley
20 vs 23 -> Escalade
21 vs 24 -> Badminton
Session #3
----------
1 vs 4 -> Beach volley
2 vs 6 -> Escalade
3 vs 5 -> Badminton
7 vs 10 -> Molky
8 vs 12 -> Béret
9 vs 11 -> Course à l'aveugle
13 vs 16 -> Biathlon
14 vs 18 -> Karting
15 vs 17 -> Mur interactif
19 vs 22 -> Ultimate
20 vs 24 -> Golf
21 vs 23 -> Handball
Session #4
----------
1 vs 5 -> Ultimate
2 vs 3 -> Golf
4 vs 6 -> Handball
7 vs 11 -> Beach volley
8 vs 9 -> Escalade
10 vs 12 -> Badminton
13 vs 17 -> Molky
14 vs 15 -> Béret
16 vs 18 -> Course à l'aveugle
19 vs 23 -> Biathlon
20 vs 21 -> Karting
22 vs 24 -> Mur interactif
Session #5
----------
1 vs 2 -> Karting
3 vs 4 -> Mur interactif
5 vs 6 -> Biathlon
7 vs 8 -> Golf
9 vs 10 -> Handball
11 vs 12 -> Ultimate
13 vs 14 -> Escalade
15 vs 16 -> Badminton
17 vs 18 -> Beach volley
19 vs 20 -> Béret
21 vs 22 -> Course à l'aveugle
23 vs 24 -> Molky
Session #6
----------
1 vs 3 -> Béret
2 vs 5 -> Course à l'aveugle
3 vs 6 -> Molky
7 vs 9 -> Karting
8 vs 11 -> Mur interactif
9 vs 12 -> Biathlon
13 vs 15 -> Golf
14 vs 17 -> Handball
15 vs 18 -> Ultimate
19 vs 21 -> Escalade
20 vs 23 -> Badminton
21 vs 24 -> Beach volley
Session #7
----------
1 vs 4 -> Escalade
2 vs 6 -> Badminton
3 vs 5 -> Beach volley
7 vs 10 -> Béret
8 vs 12 -> Course à l'aveugle
9 vs 11 -> Molky
13 vs 16 -> Karting
14 vs 18 -> Mur interactif
15 vs 17 -> Biathlon
19 vs 22 -> Golf
20 vs 24 -> Handball
21 vs 23 -> Ultimate
Session #8
----------
1 vs 5 -> Golf
2 vs 3 -> Handball
4 vs 6 -> Ultimate
7 vs 11 -> Escalade
8 vs 9 -> Badminton
10 vs 12 -> Beach volley
13 vs 17 -> Béret
14 vs 15 -> Course à l'aveugle
16 vs 18 -> Molky
19 vs 23 -> Karting
20 vs 21 -> Mur interactif
22 vs 24 -> Biathlon
Session #9
----------
1 vs 2 -> Mur interactif
3 vs 4 -> Biathlon
5 vs 6 -> Karting
7 vs 8 -> Handball
9 vs 10 -> Ultimate
11 vs 12 -> Golf
13 vs 14 -> Badminton
15 vs 16 -> Beach volley
17 vs 18 -> Escalade
19 vs 20 -> Course à l'aveugle
21 vs 22 -> Molky
23 vs 24 -> Béret
Session #10
-----------
1 vs 3 -> Course à l'aveugle
2 vs 5 -> Molky
3 vs 6 -> Béret
7 vs 9 -> Mur interactif
8 vs 11 -> Biathlon
9 vs 12 -> Karting
13 vs 15 -> Handball
14 vs 17 -> Ultimate
15 vs 18 -> Golf
19 vs 21 -> Badminton
20 vs 23 -> Beach volley
21 vs 24 -> Escalade
Session #11
-----------
1 vs 4 -> Badminton
2 vs 6 -> Beach volley
3 vs 5 -> Escalade
7 vs 10 -> Course à l'aveugle
8 vs 12 -> Molky
9 vs 11 -> Béret
13 vs 16 -> Mur interactif
14 vs 18 -> Biathlon
15 vs 17 -> Karting
19 vs 22 -> Handball
20 vs 24 -> Ultimate
21 vs 23 -> Golf
Session #12
-----------
1 vs 5 -> Handball
2 vs 3 -> Ultimate
4 vs 6 -> Golf
7 vs 11 -> Badminton
8 vs 9 -> Beach volley
10 vs 12 -> Escalade
13 vs 17 -> Course à l'aveugle
14 vs 15 -> Molky
16 vs 18 -> Béret
19 vs 23 -> Mur interactif
20 vs 21 -> Biathlon
22 vs 24 -> Karting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment