author | Markus Bröker <mbroeker@largo.dyndns.tv> |
Thu, 16 Apr 2009 12:51:15 +0200 | |
changeset 79 | 1499176750b9 |
parent 78 | e87e0fe4a7db |
permissions | -rw-r--r-- |
75 | 1 |
/** |
77 | 2 |
* clplaner.c |
75 | 3 |
* Copyright (C) 2008 Markus Broeker |
4 |
*/ |
|
5 |
||
6 |
#include <stdio.h> |
|
7 |
#include <stdlib.h> |
|
8 |
#include <string.h> |
|
9 |
#include <time.h> |
|
10 |
#include <limits.h> |
|
11 |
||
12 |
#define MAXLOOP 25 |
|
13 |
#define MAXLINE 80 |
|
14 |
||
15 |
#ifndef MAXTEAM |
|
16 |
#define MAXTEAM 32 |
|
17 |
#endif |
|
18 |
||
19 |
#define getrandom(max) (1+(int)((float)(max)*rand()/RAND_MAX)) |
|
20 |
||
21 |
void swap (int *v, int i, int j) |
|
22 |
{ |
|
23 |
int temp; |
|
24 |
||
25 |
if (i == j) |
|
26 |
return; |
|
27 |
||
28 |
temp = v[i]; |
|
29 |
||
30 |
v[i] = v[j]; |
|
31 |
v[j] = temp; |
|
32 |
} |
|
33 |
||
34 |
void cleanup (char **first, char **second) |
|
35 |
{ |
|
36 |
int i; |
|
37 |
||
38 |
i = 0; |
|
39 |
while (first[i] != NULL) |
|
40 |
free (first[i++]); |
|
41 |
||
42 |
i = 0; |
|
43 |
while (second[i] != NULL) |
|
44 |
free (second[i++]); |
|
45 |
} |
|
46 |
||
47 |
unsigned int time_seed () |
|
48 |
{ |
|
49 |
time_t now = time (NULL); |
|
50 |
||
51 |
unsigned char *p = (unsigned char *)&now; |
|
52 |
unsigned int seed = 0; |
|
53 |
||
54 |
size_t i; |
|
55 |
||
56 |
for (i = 0; i < sizeof (now); i++) |
|
57 |
seed = seed * (UCHAR_MAX + 2U) + p[i]; |
|
58 |
||
59 |
return seed; |
|
60 |
} |
|
61 |
||
62 |
int getTeams (FILE * f, char **first, int *first_idx, char **second, int *second_idx) |
|
63 |
{ |
|
64 |
int i; |
|
65 |
char buffer[MAXLINE + 1]; |
|
66 |
char *ptr; |
|
67 |
||
68 |
i = 0; |
|
69 |
while ((i < MAXTEAM) && fgets (buffer, MAXLINE, f) != NULL) { |
|
70 |
if ((first[i] = malloc (MAXLINE + 1)) == NULL) { |
|
71 |
perror ("malloc"); |
|
72 |
break; |
|
73 |
} |
|
74 |
if ((ptr = strchr (buffer, '\n'))) |
|
75 |
*ptr = '\0'; |
|
76 |
||
77 |
strncpy (first[i], buffer, MAXLINE); |
|
78 |
first_idx[i] = i; |
|
79 |
||
80 |
if (fgets (buffer, MAXLINE, f) == NULL) { |
|
81 |
printf ("You need 2, 4, 6, ..., or %d teams in your file\n", 2 * MAXTEAM); |
|
82 |
second[i] = first[i + 1] = NULL; |
|
83 |
cleanup (first, second); |
|
84 |
fclose (f); |
|
85 |
exit (EXIT_FAILURE); |
|
86 |
} |
|
87 |
||
88 |
if ((second[i] = malloc (MAXLINE + 1)) == NULL) { |
|
89 |
perror ("malloc"); |
|
90 |
break; |
|
91 |
} |
|
92 |
if ((ptr = strchr (buffer, '\n'))) |
|
93 |
*ptr = '\0'; |
|
94 |
||
95 |
strncpy (second[i], buffer, MAXLINE); |
|
96 |
second_idx[i] = i; |
|
97 |
i++; |
|
98 |
} |
|
99 |
||
100 |
first[i] = second[i] = NULL; |
|
101 |
||
102 |
return i; |
|
103 |
} |
|
104 |
||
105 |
void shakeTeamIdx (int *first_idx, int *second_idx, int teams) |
|
106 |
{ |
|
107 |
int i, j, k; |
|
108 |
||
109 |
/* |
|
78
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
110 |
* Who wins the Title? |
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
111 |
*/ |
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
112 |
if (teams == 1) |
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
113 |
return; |
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
114 |
|
e87e0fe4a7db
clplaner: Avoid a segfault on Wed May 27 20:00 CET 2009
Markus Bröker <mbroeker@largo.dyndns.tv>
parents:
77
diff
changeset
|
115 |
/* |
75 | 116 |
* swap the index MAXLOOP times... |
117 |
*/ |
|
118 |
for (i = 0; i < MAXLOOP; i++) { |
|
119 |
for (j = 0; j < teams; j++) { |
|
120 |
k = getrandom (teams - 1); |
|
121 |
swap (second_idx, j, k); |
|
122 |
||
123 |
k = getrandom (teams - 1); |
|
124 |
swap (first_idx, j, k); |
|
125 |
} |
|
126 |
} |
|
127 |
||
128 |
/* |
|
129 |
* avoid group clashes |
|
130 |
*/ |
|
131 |
for (i = 0; i < teams - 1; i++) { |
|
132 |
if (first_idx[i] == second_idx[i]) |
|
133 |
swap (first_idx, i, i + 1); |
|
134 |
} |
|
135 |
||
136 |
if (first_idx[i] == second_idx[i]) |
|
137 |
swap (first_idx, i, i - 1); |
|
138 |
} |
|
139 |
||
140 |
int main (int argc, char **argv) |
|
141 |
{ |
|
142 |
FILE *f; |
|
143 |
||
144 |
char *first[MAXTEAM + 1]; |
|
145 |
char *second[MAXTEAM + 1]; |
|
146 |
||
147 |
int first_idx[MAXTEAM]; |
|
148 |
int second_idx[MAXTEAM]; |
|
149 |
||
150 |
int i, teams; |
|
151 |
||
152 |
if (argc != 2) { |
|
153 |
printf ("Usage: %s FILE\n\n", argv[0]); |
|
154 |
printf ("One Team per line, seperated by newline, n=2, 4, ..., or %d\n", 2 * MAXTEAM); |
|
155 |
printf ("Team n is the Groupwinner, n+1 is the Runners Up\n"); |
|
156 |
printf ("Report bugs to mbroeker@largo.homelinux.org\n"); |
|
157 |
return EXIT_FAILURE; |
|
158 |
} |
|
159 |
||
160 |
if ((f = fopen (argv[1], "r")) == NULL) { |
|
161 |
perror ("fopen"); |
|
162 |
return EXIT_FAILURE; |
|
163 |
} |
|
164 |
||
165 |
srand (time_seed ()); |
|
166 |
||
167 |
teams = getTeams (f, first, first_idx, second, second_idx); |
|
168 |
shakeTeamIdx (first_idx, second_idx, teams); |
|
169 |
||
170 |
for (i = 0; i < teams; i++) |
|
171 |
printf ("%30s vs %s\n", second[second_idx[i]], first[first_idx[i]]); |
|
172 |
||
173 |
cleanup (first, second); |
|
174 |
||
175 |
if (f != NULL) |
|
176 |
fclose (f); |
|
177 |
||
178 |
return EXIT_SUCCESS; |
|
179 |
} |