2

I need to make a C program that creates/generates a schedule table for tournament "each against each other".
There are 16 teams (1 to 16 numbers) and 15 rounds. The table should contain the round where i-th and j-th team are playing agains one another and must be a 2D array, shown in rows and columns (see below).
Also if i == j then a[i][j] = 0, because no team plays against itself in any round.

The conditions of the task aren't very clear to me.
I've explained above the way I'm understanding it.
However, after hours of Googling seems like its basically round robin tournament.

I guess it should look like this:

teams   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16
    1   0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
    2   1   0   3   4   5   6   7   8   9   10  11  12  13  14  15  2
    3   2   3   0   5   6   7   8   9   10  11  12  13  14  15  1   4
    4   3   4   5   0   7   8   9   10  11  12  13  14  15  1   2   6
    5   4   5   6   7   0   9   10  11  12  13  14  15  1   2   3   8
    6   5   6   7   8   9   0   11  12  13  14  15  1   2   3   4   10
    7   6   7   8   9   10  11  0   13  14  15  1   2   3   4   5   12
    8   7   8   9   10  11  12  13  0   15  1   2   3   4   5   6   14
    9   8   9   10  11  12  13  14  15  0   2   3   4   5   6   7   1
    10  9   10  11  12  13  14  15  1   2   0   4   5   6   7   8   3
    11  10  11  12  13  14  15  1   2   3   4   0   6   7   8   9   5
    12  11  12  13  14  15  1   2   3   4   5   6   0   8   9   10  7
    13  12  13  14  15  1   2   3   4   5   6   7   8   0   10  11  9
    14  13  14  15  1   2   3   4   5   6   7   8   9   10  0   12  11
    15  14  15  1   2   3   4   5   6   7   8   9   10  11  12  0   13
    16  15  2   4   6   8   10  12  14  1   3   5   7   9   11  13  0

I don't know where to start, literally the only thing I can do is fill the main diagonal with zeros.

Here is my code, but it doesn't output quite well the table:

#include<stdio.h>

void print(int a[16][16]);
void schedule(int a[16][16]);

void main(){
    int a[16][16], i, j;
    schedule(a);
    print(a);
}

void schedule(int a[16][16]){
    for (int i = 0; i < 16; i++){
        for (int j = 0; j < 16; j++)
        if (i == j)
            a[i][j] = 0;
    }
}

void print(int a[16][16]){
   int k = 0;
   printf("teams: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16\n");
   for (int i = 0; i < 16; i++){
       k++;
       if (i < 10)
            printf("   %d   ", k);
       if (i >= 10)
            printf("   %d   ", k);

       for (int j = 0; j < 16; j++){
          if (a[i][j] == 0 && j < 10){
            printf("%d ", a[i][j]);
          }
          else if (a[i][j] == 0 && j >= 10) {
            printf(" %d ", a[i][j]);
          }
          if (j < 10)
            printf("  ");
          else
            printf("   ");
       }
       printf("\n");
   }

}

From looking at the table (by rows or columns) I noticed the numbers, that normally would be before the number in a[i][0], are at the end of the row + the number "covered" with 0. In other words, it seems to me that first row is shifting to the left, but that doesn't help me to come up with an algorithm.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
pollux552
  • 107
  • 1
  • 10
  • Do you want to output that table or any table which fits the description? – Yunnosch May 05 '18 at 05:46
  • Well I guess if it fits the description it will do the job. – pollux552 May 05 '18 at 05:47
  • Please show more code, the declaration of the array, the output, ... Something that compiles and can be run to use your basic table-filler as shown. – Yunnosch May 05 '18 at 05:49
  • See https://en.wikipedia.org/wiki/Round-robin_tournament#Scheduling_algorithm - in some sports pairing order is important and you also need to enforce an even distribution of colors (i.e., in chess each player gets half games as white and half as black). – FBergo May 05 '18 at 05:54
  • I've updated the code. – pollux552 May 05 '18 at 06:08

1 Answers1

1

Use this for filling the array:

const int NofTeams=16;
int a[NofTeams][NofTeams];
int i,j;
for(i = 0; i< NofTeams-1; i++)
{
    for(j =0; j < NofTeams-1; j++)
    {
        if(i==j)
        {
            /* edge cases */
            a[i][NofTeams-1]=((i+j)+(i+j)/NofTeams)%NofTeams;
            a[NofTeams-1][j]=((i+j)+(i+j)/NofTeams)%NofTeams;
            a[i][j]=0;
        } else
        {
            a[i][j]=((i+j)+(i+j)/NofTeams)%NofTeams;
        }
    }
}
/* corner cases; [0][0] is diagonal */
a[0][NofTeams-1]=NofTeams-1;
a[NofTeams-1][NofTeams-1]=0;
a[NofTeams-1][0]=NofTeams-1;

The trick is the sequence ((i+j)+(i+j)/NofTeams)%NofTeams.

This is for never printing too high a round number (maximum is number of teams minus 1):
%NofTeams.

This is for jumping the number of teams (which after % ends up as an unwanted 0):
+(i+j)/NofTeams.

This, in combination with the others, is for the basic round robin:
(i+j) (first of the two).

Otherwise the trick is to only fill the non-edge cases with the loops and do the edge cases specifically, i.e. the basic table-making concept.

Output (simple 2D table printing, with first row and first column according to your desired output):

    1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
 1  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 2  1  0  3  4  5  6  7  8  9 10 11 12 13 14 15  2
 3  2  3  0  5  6  7  8  9 10 11 12 13 14 15  1  4
 4  3  4  5  0  7  8  9 10 11 12 13 14 15  1  2  6
 5  4  5  6  7  0  9 10 11 12 13 14 15  1  2  3  8
 6  5  6  7  8  9  0 11 12 13 14 15  1  2  3  4 10
 7  6  7  8  9 10 11  0 13 14 15  1  2  3  4  5 12
 8  7  8  9 10 11 12 13  0 15  1  2  3  4  5  6 14
 9  8  9 10 11 12 13 14 15  0  2  3  4  5  6  7  1
10  9 10 11 12 13 14 15  1  2  0  4  5  6  7  8  3
11 10 11 12 13 14 15  1  2  3  4  0  6  7  8  9  5
12 11 12 13 14 15  1  2  3  4  5  6  0  8  9 10  7
13 12 13 14 15  1  2  3  4  5  6  7  8  0 10 11  9
14 13 14 15  1  2  3  4  5  6  7  8  9 10  0 12 11
15 14 15  1  2  3  4  5  6  7  8  9 10 11 12  0 13
16 15  2  4  6  8 10 12 14  1  3  5  7  9 11 13  0
Yunnosch
  • 26,130
  • 9
  • 42
  • 54