diff options
Diffstat (limited to 'src/nissy.c')
| -rw-r--r-- | src/nissy.c | 112 |
1 files changed, 46 insertions, 66 deletions
diff --git a/src/nissy.c b/src/nissy.c index 44efb83..4a4c0fd 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -12,13 +12,12 @@ | |||
| 12 | 12 | ||
| 13 | #include "nissy.h" | 13 | #include "nissy.h" |
| 14 | 14 | ||
| 15 | int parse_h48_options(const char *, uint8_t *, uint8_t *, uint8_t *); | 15 | int parse_h48_solver(const char *, uint8_t [static 1], uint8_t [static 1]); |
| 16 | STATIC int64_t write_result(cube_t, char [static 22]); | 16 | STATIC int64_t write_result(cube_t, char [static 22]); |
| 17 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], | 17 | STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], |
| 18 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); | 18 | const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); |
| 19 | STATIC bool checkdata(const void *, const tableinfo_t *); | 19 | STATIC bool checkdata(const void *, const tableinfo_t *); |
| 20 | 20 | ||
| 21 | /* TODO: add option to get DR, maybe C-only, E-only, eo... */ | ||
| 22 | #define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F } | 21 | #define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F } |
| 23 | struct { | 22 | struct { |
| 24 | char *option; | 23 | char *option; |
| @@ -29,40 +28,41 @@ struct { | |||
| 29 | }; | 28 | }; |
| 30 | 29 | ||
| 31 | int | 30 | int |
| 32 | parse_h48_options(const char *buf, uint8_t *h, uint8_t *k, uint8_t *maxdepth) | 31 | parse_h48_solver(const char *buf, uint8_t h[static 1], uint8_t k[static 1]) |
| 33 | { | 32 | { |
| 34 | bool h_valid, k_valid, maxdepth_valid; | 33 | const char *fullbuf = buf; |
| 35 | int i; | 34 | |
| 35 | buf += 3; | ||
| 36 | |||
| 37 | if (!strcmp(buf, "stats")) { | ||
| 38 | *h = 0; | ||
| 39 | *k = 4; | ||
| 40 | return 0; | ||
| 41 | } | ||
| 36 | 42 | ||
| 37 | /* TODO temporarily, options are in the form "h;k;maxdepth" */ | 43 | if (*buf != 'h') |
| 38 | if (h != NULL) | 44 | goto parse_h48_solver_error; |
| 39 | *h = atoi(buf); | 45 | buf++; |
| 40 | h_valid = h == NULL || *h <= 11; | ||
| 41 | 46 | ||
| 42 | for (i = 0; buf[i] != ';'; i++) | 47 | *h = atoi(buf); |
| 43 | if (buf[i] == 0) | ||
| 44 | goto parse_h48_options_error; | ||
| 45 | 48 | ||
| 46 | if (k != NULL) | 49 | for ( ; *buf >= 0 + '0' && *buf <= 9 + '0'; buf++) |
| 47 | *k = atoi(&buf[i+1]); | 50 | if (*buf == 0) |
| 48 | k_valid = k == NULL || (*k == 2 || *k == 4); | 51 | goto parse_h48_solver_error; |
| 49 | 52 | ||
| 50 | for (i = i+1; buf[i] != ';'; i++) | 53 | if (*buf != 'k') |
| 51 | if (buf[i] == 0) | 54 | goto parse_h48_solver_error; |
| 52 | goto parse_h48_options_error; | 55 | buf++; |
| 53 | 56 | ||
| 54 | if (maxdepth != NULL) | 57 | *k = atoi(buf); |
| 55 | *maxdepth = atoi(&buf[i+1]); | ||
| 56 | maxdepth_valid = maxdepth == NULL || *maxdepth <= 20; | ||
| 57 | 58 | ||
| 58 | return h_valid && k_valid && maxdepth_valid ? 0 : 1; | 59 | return *h < 12 && (*k == 2 || (*k == 4 && *h == 0)) ? 0 : 1; |
| 59 | 60 | ||
| 60 | parse_h48_options_error: | 61 | parse_h48_solver_error: |
| 61 | *h = 0; | 62 | *h = 0; |
| 62 | *k = 0; | 63 | *k = 0; |
| 63 | *maxdepth = 0; | 64 | LOG("Error parsing solver: must be in \"h48h*k*\" format" |
| 64 | LOG("Error parsing options: must be in \"h;k;maxdepth\" format " | 65 | " or \"h48stats\", but got %s\n", fullbuf); |
| 65 | " (instead it was \"%s\")\n", buf); | ||
| 66 | return -1; | 66 | return -1; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| @@ -103,13 +103,7 @@ distribution_equal( | |||
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | if (wrong > 0) { | 106 | return wrong == 0; |
| 107 | LOG("checkdata: %d wrong values\n", wrong); | ||
| 108 | } else { | ||
| 109 | LOG("checkdata: table is consistent with info\n"); | ||
| 110 | } | ||
| 111 | |||
| 112 | return wrong > 0; | ||
| 113 | } | 107 | } |
| 114 | 108 | ||
| 115 | STATIC int64_t | 109 | STATIC int64_t |
| @@ -238,12 +232,11 @@ nissy_getcube( | |||
| 238 | 232 | ||
| 239 | int64_t | 233 | int64_t |
| 240 | nissy_datasize( | 234 | nissy_datasize( |
| 241 | const char *solver, | 235 | const char *solver |
| 242 | const char *options | ||
| 243 | ) | 236 | ) |
| 244 | { | 237 | { |
| 245 | /* gendata() handles a NULL *data as a "dryrun" request */ | 238 | /* gendata() handles a NULL *data as a "dryrun" request */ |
| 246 | return nissy_gendata(solver, options, NULL); | 239 | return nissy_gendata(solver, NULL); |
| 247 | } | 240 | } |
| 248 | 241 | ||
| 249 | int64_t | 242 | int64_t |
| @@ -294,7 +287,6 @@ nissy_datainfo( | |||
| 294 | int64_t | 287 | int64_t |
| 295 | nissy_gendata( | 288 | nissy_gendata( |
| 296 | const char *solver, | 289 | const char *solver, |
| 297 | const char *options, | ||
| 298 | void *data | 290 | void *data |
| 299 | ) | 291 | ) |
| 300 | { | 292 | { |
| @@ -303,21 +295,12 @@ nissy_gendata( | |||
| 303 | gendata_h48_arg_t arg; | 295 | gendata_h48_arg_t arg; |
| 304 | 296 | ||
| 305 | arg.buf = data; | 297 | arg.buf = data; |
| 306 | if (!strcmp(solver, "h48")) { | 298 | if (!strncmp(solver, "h48", 3)) { |
| 307 | p = parse_h48_options(options, &arg.h, &arg.k, &arg.maxdepth); | 299 | p = parse_h48_solver(solver, &arg.h, &arg.k); |
| 308 | if (p != 0) { | ||
| 309 | LOG("gendata: could not parse options\n"); | ||
| 310 | ret = -1; | ||
| 311 | } else { | ||
| 312 | ret = gendata_h48(&arg); | ||
| 313 | } | ||
| 314 | } else if (!strcmp(solver, "h48stats")) { | ||
| 315 | arg.h = 0; | ||
| 316 | arg.k = 4; | ||
| 317 | arg.maxdepth = 20; | 300 | arg.maxdepth = 20; |
| 318 | ret = gendata_h48(&arg); | 301 | ret = p == 0 ? (int64_t)gendata_h48(&arg) : -1; |
| 319 | } else { | 302 | } else { |
| 320 | LOG("gendata: implemented only for h48 solver\n"); | 303 | LOG("gendata: unknown solver %s\n", solver); |
| 321 | ret = -1; | 304 | ret = -1; |
| 322 | } | 305 | } |
| 323 | 306 | ||
| @@ -327,7 +310,6 @@ nissy_gendata( | |||
| 327 | int64_t | 310 | int64_t |
| 328 | nissy_checkdata( | 311 | nissy_checkdata( |
| 329 | const char *solver, | 312 | const char *solver, |
| 330 | const char *options, | ||
| 331 | const void *data | 313 | const void *data |
| 332 | ) | 314 | ) |
| 333 | { | 315 | { |
| @@ -335,8 +317,11 @@ nissy_checkdata( | |||
| 335 | tableinfo_t info; | 317 | tableinfo_t info; |
| 336 | 318 | ||
| 337 | for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) { | 319 | for (buf = (char *)data; readtableinfo(buf, &info); buf += info.next) { |
| 338 | if (!checkdata(buf, &info)) | 320 | if (!checkdata(buf, &info)) { |
| 321 | LOG("Error: data for %s is inconsistent with info!\n", | ||
| 322 | info.solver); | ||
| 339 | return 1; | 323 | return 1; |
| 324 | } | ||
| 340 | if (info.next == 0) | 325 | if (info.next == 0) |
| 341 | break; | 326 | break; |
| 342 | } | 327 | } |
| @@ -348,7 +333,6 @@ int64_t | |||
| 348 | nissy_solve( | 333 | nissy_solve( |
| 349 | const char cube[static 22], | 334 | const char cube[static 22], |
| 350 | const char *solver, | 335 | const char *solver, |
| 351 | const char *options, | ||
| 352 | const char *nisstype, | 336 | const char *nisstype, |
| 353 | int8_t minmoves, | 337 | int8_t minmoves, |
| 354 | int8_t maxmoves, | 338 | int8_t maxmoves, |
| @@ -360,7 +344,6 @@ nissy_solve( | |||
| 360 | { | 344 | { |
| 361 | cube_t c; | 345 | cube_t c; |
| 362 | int p; | 346 | int p; |
| 363 | int64_t ret; | ||
| 364 | uint8_t h, k; | 347 | uint8_t h, k; |
| 365 | 348 | ||
| 366 | c = readcube_B32(cube); | 349 | c = readcube_B32(cube); |
| @@ -395,28 +378,25 @@ nissy_solve( | |||
| 395 | return -1; | 378 | return -1; |
| 396 | } | 379 | } |
| 397 | 380 | ||
| 398 | /* TODO define and use solve_options_t */ | 381 | if (!strncmp(solver, "h48", 3)) { |
| 399 | if (!strcmp(solver, "h48")) { | 382 | if (!strcmp(solver, "h48stats")) |
| 400 | p = parse_h48_options(options, &h, &k, NULL); | 383 | return solve_h48stats(c, maxmoves, data, solutions); |
| 384 | |||
| 385 | p = parse_h48_solver(solver, &h, &k); | ||
| 401 | if (p != 0) { | 386 | if (p != 0) { |
| 402 | LOG("gendata: could not parse options\n"); | 387 | return -1; |
| 403 | ret = -1; | ||
| 404 | } else { | 388 | } else { |
| 405 | ret = THREADS > 1 ? | 389 | return THREADS > 1 ? |
| 406 | solve_h48_multithread(c, minmoves, maxmoves, maxsolutions, data, solutions) : | 390 | solve_h48_multithread(c, minmoves, maxmoves, maxsolutions, data, solutions) : |
| 407 | solve_h48(c, minmoves, maxmoves, maxsolutions, data, solutions); | 391 | solve_h48(c, minmoves, maxmoves, maxsolutions, data, solutions); |
| 408 | } | 392 | } |
| 409 | } else if (!strcmp(solver, "h48stats")) { | ||
| 410 | ret = solve_h48stats(c, maxmoves, data, solutions); | ||
| 411 | } else if (!strcmp(solver, "simple")) { | 393 | } else if (!strcmp(solver, "simple")) { |
| 412 | ret = solve_simple( | 394 | return solve_simple( |
| 413 | c, minmoves, maxmoves, maxsolutions, optimal, solutions); | 395 | c, minmoves, maxmoves, maxsolutions, optimal, solutions); |
| 414 | } else { | 396 | } else { |
| 415 | LOG("solve: unknown solver '%s'\n", solver); | 397 | LOG("solve: unknown solver '%s'\n", solver); |
| 416 | ret = -1; | 398 | return -1; |
| 417 | } | 399 | } |
| 418 | |||
| 419 | return ret; | ||
| 420 | } | 400 | } |
| 421 | 401 | ||
| 422 | void | 402 | void |
