forked from LplusKira/repository_AI_project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathorganizer.c
276 lines (266 loc) · 6.45 KB
/
organizer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
//$./organizer j_num p_num
//Q: 怎樣可以複寫pipe ans: 無法, 要read掉
//Q: 為什麼原本的程式 run 下續就會block住? b.c. read 不到東西(which results from 對方沒把東西寫入)
//Rmk) 如果pipe的某一端被關掉, 但仍要做寫入, 會顯示broken pipe
//Rmk) 不要用: while((n = read[...]) != 0), 在pipe會出錯!!!
//如果有用STDlib, by fflush 把write的東西丟出去!!(b.c. fully buffered for standardio in pipe)
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
//supp we have at most 1000 players
const int Maxsize = 1000000;
const int buffSize = 1000;
const char initOread[] = "1 1 1 1 1";
const char initOwrite[] = "1 1 1 1";
const char theEnd[] = "0 0 0 0";
struct joblist
{
int value;
int first, second, third, fourth;
};
typedef struct joblist Joblist;
int power(int base, int exp)
{
int i;
int ans = 1;
for(i = 0;i<exp;i++)
ans = ans * base;
return ans;
}
Joblist NextJob(int n, int value, int min)
{
int i, j;
int ind[n];
for(i = 0;i<n;i++)
ind[i] = 0;
for(i = 0;i<4;i++)
ind[i] = 1;
int temp, NumOfOne, count;
value = value + power(2, min);
//TODO: translate to count in 2
for(i = 0;i<n;i++)
ind[i] = 0;
i = 0;
NumOfOne = 0;
temp = value;
while(1)
{
if(temp == 1)
{
ind[i] = 1;
NumOfOne = NumOfOne + 1;
break;
}
if(temp % 2 == 1)
{
ind[i] = 1;
NumOfOne = NumOfOne + 1;
}
temp = temp / 2;
i = i + 1;
}
//TODO: add more 1 if the ones in the representation are less than 4 ones
Joblist job;
if(ind[n-1] == ind[n-2] && ind[n-2] == ind[n-3] && ind[n-3] == ind[n-4] && ind[n-4] == 1)
{
job.first = n-4;
job.second = n-3; job.third = n-2; job.fourth = n-1;
}
else
{
for(i = 0;i < 4 - NumOfOne ;i++)
ind[i] = 1;
i = 0;
count = 0;
for(j = 0;j<4;j++)
{
count = count + 1;
while(ind[i] != 1)
i = i + 1;
if(count == 1)
job.first = i;
else if(count == 2)
job.second = i;
else if(count == 3)
job.third = i;
else
job.fourth = i;
i = i + 1;
}
}
//TODO: renew value
value = 0;
for(i = 0;i<n;i++)
if(ind[i] == 1)
value = value + power(2, i);
job.value = value;
return job;
}
int main(int argc, char *argv[])
{
//TODO: collect j_num & p_num; i.e. judgenum and playernum
int len, i, j, n;
int j_num = 0;
int p_num = 0;
len = strlen(argv[1]);
for(i = 0;i<len;i++)
j_num = j_num * 10 + (argv[1][i] - '0');
len = strlen(argv[2]);
for(i = 0;i<len;i++)
p_num = p_num * 10 + (argv[2][i] - '0');
int fd_Owrite[j_num][2];
int fd_Oread[j_num][2];
int pid[j_num];
for(i = 0; i<j_num;i++)
pid[i] = 0;
char OurBuf[buffSize];
int looserTable[p_num + 1], IhaveAjob[j_num];
for(i = 0; i<p_num+1;i++)
looserTable[i] = 0;
for(i = 0;i<j_num;i++)
IhaveAjob[i] = 0;
int id = 0;
//TODO: build pipe & fork, can use fd[i] to each connection btw parent and child i
while(id<j_num)
{
pipe(fd_Oread[id]);
pipe(fd_Owrite[id]);
pid[id] = fork();
if(pid[id]>0)
{
close(fd_Oread[id][1]);
close(fd_Owrite[id][0]);
id = id + 1;
}
else
{
close(fd_Oread[id][0]);
close(fd_Owrite[id][1]);
id = id + 1;
break;
}
}
id = id - 1;
sleep(1);
Joblist job; job.value = 15; job.first = 0; job.second = 1; job.third = 2; job.fourth = 3;
int rettemp[5];
int current_job = 0;
int final_job = p_num - 4;//by the use of job.first
int getout = 0;
fd_set readset;
if(pid[id]>0)
{
write(fd_Owrite[0][1], "1 2 3 4\n", 8);
IhaveAjob[0] = 1;
while(getout != 1)
{
if(current_job == final_job)
{
for(i = 0;i < j_num;i++)
{
//TODO: write the end
sprintf(OurBuf, "%s\n", theEnd);
write(fd_Owrite[i][1], OurBuf, strlen(OurBuf));
}
//TODO: read unread
n = 0;
for(i = 0;i<j_num;i++)
if(IhaveAjob[i] == 1)
n = n + 1;
for(i= 0;i<n;i++)
{
FD_ZERO(&readset);
for(i = 0;i<j_num;i++)
FD_SET(fd_Oread[i][0], &readset);
select(fd_Oread[j_num - 1][0] + 1, &readset, NULL, NULL, NULL);
for(i = 0;i<j_num;i++)
if(FD_ISSET(fd_Oread[i][0], &readset))//some data write in from judge i
break;
rettemp[0] = 0;
for(j = 0;j<1;j++)
{
while(1)
{
read(fd_Oread[i][0], OurBuf, 1);
if(OurBuf[0] - '\n' == 0 || OurBuf[0] - ' ' == 0)
break;
else
rettemp[j] = rettemp[j] * 10 + (OurBuf[0] - '0');
}
}
looserTable[rettemp[0]] = looserTable[rettemp[0]] - 1;
}
getout = 1;
//break;
}
else
{
//TODO: select fd(i.e. fd with read data available) to write new job
FD_ZERO(&readset);
for(i = 0;i<j_num;i++)
FD_SET(fd_Oread[i][0], &readset);
select(fd_Oread[j_num - 1][0] + 1, &readset, NULL, NULL, NULL);
for(i = 0;i<j_num;i++)
if(FD_ISSET(fd_Oread[i][0], &readset))//some data write in from judge i
break;
//TODO: write new job
job = NextJob(p_num, job.value, job.first);
sprintf(OurBuf, "%d %d %d %d\n", job.first+1, job.second+1, job.third+1, job.fourth+1);
write(fd_Owrite[i][1], OurBuf, strlen(OurBuf));
IhaveAjob[i] = 1;
current_job = job.first;
//TODO: read return data
rettemp[0] = 0;
for(j = 0;j<1;j++)
{
while(1)
{
read(fd_Oread[i][0], OurBuf, 1);
if(OurBuf[0] - '\n' == 0 || OurBuf[0] - ' ' == 0)
break;
else
rettemp[j] = rettemp[j] * 10 + (OurBuf[0] - '0');
}
}
looserTable[rettemp[0]] = looserTable[rettemp[0]] - 1;
}
}
for(i = 0;i<p_num;i++)
looserTable[i] = looserTable[i+1];
n = p_num;
int c, d, swap;
int winnerOrder[p_num];
for(i = 0;i<p_num;i++)
winnerOrder[i] = i+1;
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (looserTable[d] > looserTable[d+1]) /* For decreasing order use < */
{
swap = looserTable[d];
looserTable[d] = looserTable[d+1];
looserTable[d+1] = swap;
swap = winnerOrder[d];
winnerOrder[d] = winnerOrder[d+1];
winnerOrder[d+1] = swap;
}
}
}
for ( c = 0 ; c < n ; c++ )
printf("%d ", winnerOrder[c]);
printf("\n");
}
else
{
dup2(fd_Owrite[id][0],STDIN_FILENO);
dup2(fd_Oread[id][1],STDOUT_FILENO);
sprintf(OurBuf, "%d", id+1);
execlp("./judge", "./judge", OurBuf, (char*)0);
}
exit(0);
}