/************************************************
This program is a simple application of 2D arrays.
The purpose is to take a list of people, and randomly
create teams from them. The names come from a
file names.txt.
*************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
/************************************************
** PROTOTYPES
************************************************/
char** readnames(int* numptr);
char** makearray(int size);
void freearray(char** arr, int size);
/************************************************
** MAIN FUNCTION
************************************************/
int main() {
// seed the random number generator differently on each run
srand(time(0));
// Read file of names
int np;
char** names = readnames(&np);
// Get number of teams from user
int nt;
printf("There are %i people.\n", np);
printf("How many teams would you like? (make it evenly divide n) ");
fflush(stdout);
scanf(" %i", &nt);
if (np % nt != 0) {
printf("ERROR: Number of teams must evenly divide number of people\n");
return 1;
}
// Allocate array of teams
int teamSize = np / nt;
char*** teams = calloc(nt, sizeof(char**));
for (int i = 0; i < nt; ++i) {
teams[i] = makearray(teamSize);
}
// dole out people to teams
int npremaining = np;
for(int i = 0; i < teamSize; ++i) {
for(int it = 0; it < nt; ++it) {
int inext = rand() % npremaining;
// copy next name to their team
strcpy(teams[it][i], names[inext]);
// effectively shrink size of names array by copying the
// last remaining name to the place we just copied from
--npremaining;
if (inext < npremaining) {
strcpy(names[inext], names[npremaining]);
}
}
}
// print teams
for(int it = 0; it < nt; ++it) {
printf("Team %i:", it+1);
for (int i=0; i < teamSize; ++i) {
printf(" %s", teams[it][i]);
}
printf("\n");
}
// clean-up
freearray(names, np);
for (int i=0; i < nt; ++i) {
freearray(teams[i], teamSize);
}
free(teams);
return 0;
}
/************************************************
** FUNCTION DEFINITIONS
************************************************/
// reads names from "names.txt" and returns an array of
// strings for each name. Also assigns the number of names
// to the int that numptr points to.
char** readnames(int* numptr) {
FILE* fin = fopen("names.txt", "r");
fscanf(fin, " N = %i", numptr);
char** result = makearray(*numptr);
for (int i=0; i < *numptr; ++i) {
fscanf(fin, " %s", result[i]);
}
fclose(fin);
return result;
}
// allocates an array of that many size-128 strings
char** makearray(int size) {
char** result = calloc(size, sizeof(char*));
for (int i=0; i < size; ++i) {
result[i] = calloc(128, sizeof(char));
}
return result;
}
// de-allocates an array of strings
void freearray(char** arr, int size) {
for (int i=0; i < size; ++i) {
free(arr[i]);
}
free(arr);
}