aboutsummaryrefslogtreecommitdiffstats
path: root/teams.c
diff options
context:
space:
mode:
authorSquibid <me@zacharyscheiman.com>2024-07-30 11:21:40 -0400
committerSquibid <me@zacharyscheiman.com>2024-07-30 11:25:33 -0400
commitbb52f5a54acc89afb936eda41daa473f15913a7b (patch)
tree15e2e659cc58fb64d64a2efbd5d35856344638d4 /teams.c
downloadteams-bb52f5a54acc89afb936eda41daa473f15913a7b.tar.gz
teams-bb52f5a54acc89afb936eda41daa473f15913a7b.tar.bz2
teams-bb52f5a54acc89afb936eda41daa473f15913a7b.zip
initial commitHEADmaster
Diffstat (limited to '')
-rw-r--r--teams.c169
1 files changed, 169 insertions, 0 deletions
diff --git a/teams.c b/teams.c
new file mode 100644
index 0000000..269096b
--- /dev/null
+++ b/teams.c
@@ -0,0 +1,169 @@
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+typedef struct Person {
+ char *name;
+ struct Person *opponent;
+} Person;
+
+static void
+die(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else
+ fputc('\n', stderr);
+ exit(1);
+}
+
+/**
+ * @brief get number of substr in str
+ *
+ * @param haystack str to search
+ * @param needle substr
+ * @return number of substr in str
+ */
+static inline int
+numsubstr(const char *haystack, const char *needle)
+{
+ int i = 0;
+ const char *tmp = haystack;
+
+ while((tmp = strstr(tmp, needle))) {
+ i++;
+ tmp++;
+ }
+
+ return i;
+}
+
+/**
+ * @brief cleanup people ptrs
+ *
+ * @param p pointer to person
+ * @param len number of people in p
+ */
+void
+destroypeopleptr(Person *p, size_t num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ if (p[i].name && p[i].name == NULL)
+ free(p[i].name);
+ free(p);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int j, i, l, t, c, a, r, min, numteams, numpeople, peopleperteam;
+ Person *people, **teams;
+
+ /* seed random number generator */
+ srand(time(NULL));
+
+ /* get number of people declared and allocate enough space for them */
+ for (i = numpeople = 0; i < argc; i++)
+ numpeople += numsubstr(argv[i], "-p");
+
+ /* allocate space for all people */
+ people = calloc(numpeople, sizeof(Person));
+
+ /* collect people and team numbers */
+ i = 0;
+ while ((c = getopt(argc, argv, "p:t:")) != -1) {
+ switch (c) {
+ case 'p':
+ people[i++] = (Person){
+ .name = optarg,
+ .opponent = NULL
+ };
+ break;
+ case 't':
+ numteams = atoi(optarg);
+ break;
+ }
+ }
+
+ /* exit if there aren't enough people for the number of teams */
+ if (floor((double)numpeople / (double)numteams) < 1)
+ die("%d people is not enough for %d teams", numpeople, numteams);
+
+ /* allocate space for teams */
+ teams = calloc(numteams, sizeof(Person *));
+
+ /* calculate maximum number of people per team */
+ peopleperteam = floor(((double)numpeople / (double)numteams) + 0.5);
+
+ /* allocate space for people in each team */
+ for (i = 0; i < numteams; i++)
+ teams[i] = calloc(peopleperteam, sizeof(Person));
+
+ /* randomize array */
+ for (i = 0; i < numpeople; i++) {
+ r = rand() / (RAND_MAX / numpeople);
+ Person tmp = people[r];
+ people[r] = people[i];
+ people[i] = tmp;
+ }
+
+ /* sort people into teams */
+ for (i = j = l = min = 0; i < numpeople; i++) {
+ if (l == peopleperteam) {
+ if (j < numteams - 1) {
+ j++;
+ l = min;
+ } else {
+ /* resize arrays */
+ for (t = 0; t < numteams; t++) {
+ Person *b = calloc(peopleperteam + 1, sizeof(Person));
+
+ for (a = 0; a < peopleperteam; a++) {
+ b[a].name = teams[t][a].name;
+ b[a].opponent = teams[t][a].opponent;
+ }
+
+ destroypeopleptr(teams[t], numpeople);
+ teams[t] = b;
+ b = NULL;
+ }
+
+ j = 0;
+ l = min = peopleperteam++;
+ }
+ }
+
+ /* assign person to team */
+ teams[j][l++] = people[i];
+ }
+
+ /* print out teams */
+ for (i = 0; i < numteams; i++) {
+ printf("team #%d:\n", i + 1);
+ for (j = 0; j < peopleperteam; j++)
+ if (teams[i][j].name)
+ puts(teams[i][j].name);
+ }
+
+ /* cleanup */
+ destroypeopleptr(people, numpeople);
+
+ for (i = 0; i < numteams; i++)
+ free(teams[i]);
+ free(teams);
+
+ return 0;
+}