diff --git a/clplaner.c b/clplaner.c new file mode 100644 --- /dev/null +++ b/clplaner.c @@ -0,0 +1,173 @@ +/** + * test/demos/clplaner.c + * Copyright (C) 2008 Markus Broeker + */ + +#include +#include +#include +#include +#include + +#define MAXLOOP 25 +#define MAXLINE 80 + +#ifndef MAXTEAM +#define MAXTEAM 32 +#endif + +#define getrandom(max) (1+(int)((float)(max)*rand()/RAND_MAX)) + +void swap (int *v, int i, int j) +{ + int temp; + + if (i == j) + return; + + temp = v[i]; + + v[i] = v[j]; + v[j] = temp; +} + +void cleanup (char **first, char **second) +{ + int i; + + i = 0; + while (first[i] != NULL) + free (first[i++]); + + i = 0; + while (second[i] != NULL) + free (second[i++]); +} + +unsigned int time_seed () +{ + time_t now = time (NULL); + + unsigned char *p = (unsigned char *)&now; + unsigned int seed = 0; + + size_t i; + + for (i = 0; i < sizeof (now); i++) + seed = seed * (UCHAR_MAX + 2U) + p[i]; + + return seed; +} + +int getTeams (FILE * f, char **first, int *first_idx, char **second, int *second_idx) +{ + int i; + char buffer[MAXLINE + 1]; + char *ptr; + + i = 0; + while ((i < MAXTEAM) && fgets (buffer, MAXLINE, f) != NULL) { + if ((first[i] = malloc (MAXLINE + 1)) == NULL) { + perror ("malloc"); + break; + } + if ((ptr = strchr (buffer, '\n'))) + *ptr = '\0'; + + strncpy (first[i], buffer, MAXLINE); + first_idx[i] = i; + + if (fgets (buffer, MAXLINE, f) == NULL) { + printf ("You need 2, 4, 6, ..., or %d teams in your file\n", 2 * MAXTEAM); + second[i] = first[i + 1] = NULL; + cleanup (first, second); + fclose (f); + exit (EXIT_FAILURE); + } + + if ((second[i] = malloc (MAXLINE + 1)) == NULL) { + perror ("malloc"); + break; + } + if ((ptr = strchr (buffer, '\n'))) + *ptr = '\0'; + + strncpy (second[i], buffer, MAXLINE); + second_idx[i] = i; + i++; + } + + first[i] = second[i] = NULL; + + return i; +} + +void shakeTeamIdx (int *first_idx, int *second_idx, int teams) +{ + int i, j, k; + + /* + * swap the index MAXLOOP times... + */ + for (i = 0; i < MAXLOOP; i++) { + for (j = 0; j < teams; j++) { + k = getrandom (teams - 1); + swap (second_idx, j, k); + + k = getrandom (teams - 1); + swap (first_idx, j, k); + } + } + + /* + * avoid group clashes + */ + for (i = 0; i < teams - 1; i++) { + if (first_idx[i] == second_idx[i]) + swap (first_idx, i, i + 1); + } + + if (first_idx[i] == second_idx[i]) + swap (first_idx, i, i - 1); +} + +int main (int argc, char **argv) +{ + FILE *f; + + char *first[MAXTEAM + 1]; + char *second[MAXTEAM + 1]; + + int first_idx[MAXTEAM]; + int second_idx[MAXTEAM]; + + int i, teams; + + if (argc != 2) { + printf ("Usage: %s FILE\n\n", argv[0]); + printf ("One Team per line, seperated by newline, n=2, 4, ..., or %d\n", 2 * MAXTEAM); + printf ("Team n is the Groupwinner, n+1 is the Runners Up\n"); + printf ("Report bugs to mbroeker@largo.homelinux.org\n"); + return EXIT_FAILURE; + } + + if ((f = fopen (argv[1], "r")) == NULL) { + perror ("fopen"); + return EXIT_FAILURE; + } + + srand (time_seed ()); + + teams = getTeams (f, first, first_idx, second, second_idx); + shakeTeamIdx (first_idx, second_idx, teams); + + for (i = 0; i < teams; i++) + printf ("%30s vs %s\n", second[second_idx[i]], first[first_idx[i]]); + + cleanup (first, second); + + if (f != NULL) + fclose (f); + + return EXIT_SUCCESS; +}