Line data Source code
1 : /* Test program for EDAG01 Efficient C at Lund University
2 : *
3 : * See intopt.h, add your implementation in intopt.c, and type make.
4 : *
5 : * The input in test will be run until there is a timeout or a failed test.
6 : *
7 : */
8 :
9 : #include <ctype.h>
10 : #include <errno.h>
11 : #include <inttypes.h>
12 : #include <math.h>
13 : #include <signal.h>
14 : #include <stdbool.h>
15 : #include <stdint.h>
16 : #include <stdio.h>
17 : #include <string.h>
18 : #include <stdlib.h>
19 : #include <dirent.h>
20 : #include <unistd.h>
21 :
22 : #include "error.h"
23 : #include "intopt.h"
24 :
25 : #define N (20) /* max m and n. */
26 :
27 : char cwd[BUFSIZ]; /* dir where we started in main. */
28 : uint64_t pass[N+1]; /* pass[i] = passed cases for m = n = i. */
29 : bool fail; /* stopped due to failed case. */
30 : char* progname; /* name of this program. */
31 : unsigned test_time = 120; /* default 120 s. */
32 : static const double eps = 1e-6; /* epsilon. */
33 :
34 : static void make_score();
35 :
36 1 : static void timeout(int s)
37 : {
38 1 : make_score();
39 0 : }
40 :
41 5250 : static void cd(char* dir)
42 : {
43 5250 : if (chdir(dir) < 0)
44 0 : error("cd to \"%s\" failed", dir);
45 5250 : }
46 :
47 2612 : static void check(void)
48 : {
49 : int r;
50 : int m;
51 : int n;
52 : int i;
53 : int j;
54 : int k;
55 : int s;
56 : double** a;
57 : double* b;
58 : double* c;
59 : double* x;
60 : double z;
61 : double y;
62 : double z_sol;
63 : FILE* in;
64 : FILE* sol;
65 :
66 2612 : in = fopen("i", "r");
67 2612 : if (in == NULL)
68 0 : return;
69 :
70 2612 : r = fscanf(in, "%d", &m);
71 2612 : r = fscanf(in, "%d", &n);
72 :
73 2612 : a = calloc(m+n, sizeof(double*));
74 2612 : b = calloc(m+n, sizeof(double));
75 2612 : c = calloc(n+1, sizeof(double));
76 2612 : x = calloc(n+m+1, sizeof(double));
77 :
78 18388 : for (i = 0; i < n; i += 1)
79 15776 : r = fscanf(in, "%lf", &c[i]);
80 :
81 18388 : for (i = 0; i < m; i += 1) {
82 15776 : a[i] = calloc(n+1, sizeof(double));
83 138880 : for (j = 0; j < n; j += 1)
84 123104 : r = fscanf(in, "%lf", &a[i][j]);
85 : }
86 :
87 18388 : for (; i < n+m; i += 1)
88 15776 : a[i] = calloc(n+1, sizeof(double));
89 :
90 18388 : for (i = 0; i < m; i += 1)
91 15776 : r = fscanf(in, "%lf", &b[i]);
92 :
93 2612 : fclose(in);
94 :
95 2612 : z = intopt(m, n, a, b, c, x);
96 :
97 2611 : sol = fopen("intopt.sol", "r");
98 :
99 2611 : if (sol == NULL)
100 0 : goto dealloc;
101 :
102 2611 : s = fscanf(sol, "z = %lf", &z_sol);
103 :
104 2611 : fclose(sol);
105 :
106 2611 : if (s != 1)
107 0 : goto dealloc;
108 :
109 2611 : if ((isfinite(z) == 0) ^ (isfinite(z_sol) == 0)) {
110 0 : fail = 1;
111 0 : make_score();
112 2611 : } else if ((isnan(z) != 0) & (isnan(z_sol) != 0))
113 0 : pass[n] += 1;
114 2611 : else if (fabs(z-z_sol) <= eps)
115 2611 : pass[n] += 1;
116 : else {
117 0 : fail = 1;
118 0 : make_score();
119 : }
120 :
121 2611 : dealloc:
122 34135 : for (i = 0; i < n+m; i += 1)
123 31524 : free(a[i]);
124 2611 : free(a);
125 2611 : free(b);
126 2611 : free(c);
127 2611 : free(x);
128 : }
129 :
130 2625 : static void search(void)
131 : {
132 : DIR* dir;
133 : struct dirent* entry;
134 : char wd[BUFSIZ];
135 :
136 2625 : dir = opendir(".");
137 :
138 2625 : if (dir == NULL)
139 0 : error("cannot open .");
140 :
141 26153 : while ((entry = readdir(dir)) != NULL) {
142 :
143 23530 : if (getcwd(wd, sizeof wd) == NULL)
144 0 : error("getcwd failed");
145 23530 : if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
146 5250 : continue;
147 18280 : else if (strcmp(entry->d_name, "i") == 0)
148 2612 : check();
149 15668 : else if (isdigit(entry->d_name[0])) {
150 2612 : cd(entry->d_name);
151 2612 : search();
152 : }
153 : }
154 2623 : cd("..");
155 :
156 2623 : closedir(dir);
157 2623 : }
158 :
159 13 : static void eval(int n)
160 : {
161 : char dir[10];
162 :
163 13 : sprintf(dir, "%d", n);
164 :
165 13 : cd(dir);
166 13 : search();
167 12 : }
168 :
169 1 : static void make_score()
170 : {
171 : uint64_t i;
172 : uint64_t d;
173 : uint64_t s;
174 : FILE* fp;
175 : char dir[BUFSIZ];
176 :
177 1 : if (fail) {
178 0 : getcwd(dir, sizeof dir);
179 0 : printf("failed in %s\n", dir);
180 : }
181 :
182 1 : s = 0;
183 :
184 1 : printf("\n--- make score -------------------------\n");
185 :
186 20 : for (i = 2; i <= N; i += 1) {
187 19 : d = pass[i] << i;
188 19 : s += d;
189 19 : printf("n = %2" PRIu64 ", pass = %8" PRIu64 " value = %8" PRIu64 "\n", i, pass[i], d);
190 : }
191 :
192 1 : printf("score = %" PRIu64 " for t = %u s\n", s, test_time);
193 :
194 1 : cd(cwd);
195 :
196 1 : fp = fopen("score", "w");
197 1 : if (fp == NULL)
198 0 : error("cannot open score for writing");
199 1 : fprintf(fp, "%" PRIu64 "\n", s);
200 1 : fclose(fp);
201 :
202 1 : exit(0);
203 : }
204 :
205 0 : static void usage()
206 : {
207 0 : fprintf(stderr, "%s: usage: %s [-t seconds]\n", progname, progname);
208 0 : exit(1);
209 : }
210 :
211 1 : int main(int argc, char** argv)
212 : {
213 : int i;
214 :
215 1 : progname = argv[0];
216 :
217 1 : signal(SIGALRM, timeout);
218 :
219 1 : if (getcwd(cwd, sizeof cwd) == NULL)
220 0 : error("getcwd failed");
221 :
222 1 : for (i = 1; i < argc; i += 1) {
223 0 : switch (argv[i][1]) {
224 0 : case 't':
225 0 : if (argv[i+1] == NULL || sscanf(argv[i+1], "%u", &test_time) != 1)
226 0 : usage();
227 0 : i += 1;
228 0 : break;
229 :
230 0 : default:
231 0 : usage();
232 : }
233 : }
234 :
235 1 : alarm(test_time);
236 :
237 1 : cd("test");
238 :
239 13 : for (i = 2; i <= N; i += 1)
240 13 : eval(i);
241 :
242 0 : make_score();
243 :
244 0 : return 0;
245 : }
|