clplaner.c
author Markus Bröker <mbroeker@largo.dyndns.tv>
Mon, 21 Jun 2010 01:09:18 +0200
changeset 135 f837cf975e95
parent 78 e87e0fe4a7db
permissions -rw-r--r--
DBClient: update, query and metadata committer: Markus Bröker <mbroeker@largo.homelinux.org>

/**
 * clplaner.c
 * Copyright (C) 2008 Markus Broeker
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h>

#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;

    /*
     * Who wins the Title?
     */
    if (teams == 1)
        return;

    /*
     * 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;
}