Note that each team plays 3 others per match, so it takes at least 5 matches to play all 15 other teams. We hope, then, that there is a solution for 20 matches where each team plays 5 matches and plays each team exactly once.
With 16 teams it's possible to construct a solution by hand in the following way...
- Divide the 20 matches into 5 rounds
- Number the teams 1 to 16
- For each match in turn, for each of the 4 places in that match, allocate the first team which
- is still available to play in that round
- has not yet played any of the teams already allocated to that match
You can narrow the search for available teams somewhat by noting that each match must contain exactly one team from each match of the previous round, so for place n you need only consider the teams which played match n in the previous round.
If we want 24 matches then any random choice of matches will suffice in the sixth round to fit the original requirements. However, to also ensure that no exact matches are repeated we can switch pairs of teams between the matches in some previous round. That is, if {1,2,3,4} and {5,6,7,8} were matches in some round then in round 6 we'll have {1,2,7,8} and {3,4,5,6}. Since 1 and 2 played each other exactly once in rounds 1-5, in the match {1,2,3,4}, we certainly haven't played match {1,2,7,8} yet.
The choice of data structures to implement that efficiently is left as an exercise for the reader.