diff options
57 files changed, 436 insertions, 75 deletions
| @@ -1,11 +1,18 @@ | |||
| 1 | Check stats for all tables using H48stats solver | 1 | Check stats for all tables using H48stats solver |
| 2 | - implement gencube | 2 | - implement getcube |
| 3 | - move cubefromarray from cube_io to where needed | 3 | x implement stuff in utils.h |
| 4 | x implement functions | ||
| 5 | x unit tests for permtoindex and indextoperm | ||
| 6 | x move cubefromarray from cube_io to where needed (cube_generic) | ||
| 4 | - implement in cube_generic | 7 | - implement in cube_generic |
| 5 | - fix in cube_public | 8 | x getcube_fix |
| 6 | - add tests | 9 | - getcube |
| 10 | x permutation | ||
| 11 | - orientation | ||
| 12 | - unit tests | ||
| 13 | x fix in cube_public | ||
| 7 | - test shell | 14 | - test shell |
| 8 | - optional: dr states (just to check options) | 15 | - optional: dr states (includes "fix" option) |
| 9 | - implement tool for stats | 16 | - implement tool for stats |
| 10 | - output to file, only write cocsep to stdout | 17 | - output to file, only write cocsep to stdout |
| 11 | 18 | ||
| @@ -50,6 +57,10 @@ Improvements | |||
| 50 | - use interleaved tables (e.g. big table with k=2 or k=1 and interleaved | 57 | - use interleaved tables (e.g. big table with k=2 or k=1 and interleaved |
| 51 | small table with k=4 for better backup pruning) | 58 | small table with k=4 for better backup pruning) |
| 52 | 59 | ||
| 60 | small things | ||
| 61 | - maybe move part of the logic for coord_h48 (and its inverse) to | ||
| 62 | utils.h (subsettoindex-like) | ||
| 63 | |||
| 53 | ## H48 optimal solver (some has already been implemented) | 64 | ## H48 optimal solver (some has already been implemented) |
| 54 | 65 | ||
| 55 | First compute co + csep. Use csep as a binary number (2^7 instead of 70, | 66 | First compute co + csep. Use csep as a binary number (2^7 instead of 70, |
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | #include <time.h> | ||
| 8 | 9 | ||
| 9 | #include "src/cube.h" | 10 | #include "src/cube.h" |
| 10 | 11 | ||
| @@ -29,7 +30,6 @@ typedef struct { | |||
| 29 | int8_t maxmoves; | 30 | int8_t maxmoves; |
| 30 | int8_t optimal; | 31 | int8_t optimal; |
| 31 | int64_t maxsolutions; | 32 | int64_t maxsolutions; |
| 32 | uint8_t id[16]; | ||
| 33 | } args_t; | 33 | } args_t; |
| 34 | 34 | ||
| 35 | static void print_cube_result(int64_t, char [static 22]); | 35 | static void print_cube_result(int64_t, char [static 22]); |
| @@ -41,7 +41,7 @@ static int64_t applymoves_exec(args_t *); | |||
| 41 | static int64_t applytrans_exec(args_t *); | 41 | static int64_t applytrans_exec(args_t *); |
| 42 | static int64_t frommoves_exec(args_t *); | 42 | static int64_t frommoves_exec(args_t *); |
| 43 | static int64_t convert_exec(args_t *); | 43 | static int64_t convert_exec(args_t *); |
| 44 | static int64_t gencube_exec(args_t *); | 44 | static int64_t randomcube_exec(args_t *); |
| 45 | static int64_t datasize_exec(args_t *); | 45 | static int64_t datasize_exec(args_t *); |
| 46 | static int64_t gendata_exec(args_t *); | 46 | static int64_t gendata_exec(args_t *); |
| 47 | static int64_t solve_exec(args_t *); | 47 | static int64_t solve_exec(args_t *); |
| @@ -66,6 +66,8 @@ static bool set_maxmoves(int, char **, args_t *); | |||
| 66 | static bool set_optimal(int, char **, args_t *); | 66 | static bool set_optimal(int, char **, args_t *); |
| 67 | static bool set_maxsolutions(int, char **, args_t *); | 67 | static bool set_maxsolutions(int, char **, args_t *); |
| 68 | static bool set_id(int, char **, args_t *); | 68 | static bool set_id(int, char **, args_t *); |
| 69 | |||
| 70 | static uint64_t rand64(void); | ||
| 69 | 71 | ||
| 70 | #define COMMAND(N, E) { .name = N, .exec = E } | 72 | #define COMMAND(N, E) { .name = N, .exec = E } |
| 71 | struct { | 73 | struct { |
| @@ -78,7 +80,7 @@ struct { | |||
| 78 | COMMAND("applytrans", applytrans_exec), | 80 | COMMAND("applytrans", applytrans_exec), |
| 79 | COMMAND("frommoves", frommoves_exec), | 81 | COMMAND("frommoves", frommoves_exec), |
| 80 | COMMAND("convert", convert_exec), | 82 | COMMAND("convert", convert_exec), |
| 81 | COMMAND("gencube", gencube_exec), | 83 | COMMAND("randomcube", randomcube_exec), |
| 82 | COMMAND("datasize", datasize_exec), | 84 | COMMAND("datasize", datasize_exec), |
| 83 | COMMAND("gendata", gendata_exec), | 85 | COMMAND("gendata", gendata_exec), |
| 84 | COMMAND("solve", solve_exec), | 86 | COMMAND("solve", solve_exec), |
| @@ -106,7 +108,6 @@ struct { | |||
| 106 | OPTION("-M", 1, set_maxmoves), | 108 | OPTION("-M", 1, set_maxmoves), |
| 107 | OPTION("-O", 1, set_optimal), | 109 | OPTION("-O", 1, set_optimal), |
| 108 | OPTION("-n", 1, set_maxsolutions), | 110 | OPTION("-n", 1, set_maxsolutions), |
| 109 | OPTION("-id", 16, set_id), | ||
| 110 | OPTION(NULL, 0, NULL) | 111 | OPTION(NULL, 0, NULL) |
| 111 | }; | 112 | }; |
| 112 | 113 | ||
| @@ -116,6 +117,17 @@ char *tablepaths[] = { | |||
| 116 | NULL | 117 | NULL |
| 117 | }; | 118 | }; |
| 118 | 119 | ||
| 120 | static uint64_t | ||
| 121 | rand64(void) | ||
| 122 | { | ||
| 123 | uint64_t i, ret; | ||
| 124 | |||
| 125 | for (i = 0, ret = 0; i < 64; i++) | ||
| 126 | ret |= (uint64_t)(rand() % 2) << i; | ||
| 127 | |||
| 128 | return ret; | ||
| 129 | } | ||
| 130 | |||
| 119 | static void | 131 | static void |
| 120 | print_cube_result(int64_t ret, char result[static 22]) | 132 | print_cube_result(int64_t ret, char result[static 22]) |
| 121 | { | 133 | { |
| @@ -220,12 +232,16 @@ convert_exec(args_t *args) | |||
| 220 | } | 232 | } |
| 221 | 233 | ||
| 222 | static int64_t | 234 | static int64_t |
| 223 | gencube_exec(args_t *args) | 235 | randomcube_exec(args_t *args) |
| 224 | { | 236 | { |
| 225 | char result[PRINTCUBE_BUFFER_SIZE]; | 237 | char result[PRINTCUBE_BUFFER_SIZE]; |
| 226 | int64_t ret; | 238 | int64_t ret, ep, eo, cp, co; |
| 227 | 239 | ||
| 228 | ret = nissy_gencube(args->id, args->str_options, result); | 240 | ep = rand64(); |
| 241 | eo = rand64(); | ||
| 242 | cp = rand64(); | ||
| 243 | co = rand64(); | ||
| 244 | ret = nissy_getcube(ep, eo, cp, co, args->str_options, result); | ||
| 229 | print_str_result(ret, result); | 245 | print_str_result(ret, result); |
| 230 | 246 | ||
| 231 | return ret; | 247 | return ret; |
| @@ -289,7 +305,7 @@ gendata_exec(args_t *args) | |||
| 289 | } | 305 | } |
| 290 | if (ret != size) { | 306 | if (ret != size) { |
| 291 | fprintf(stderr, "Unknown error: unexpected data size " | 307 | fprintf(stderr, "Unknown error: unexpected data size " |
| 292 | "(got %zu, expected %zu)\n", ret, size); | 308 | "got %" PRId64 ", expected %" PRId64)\n", ret, size); |
| 293 | fclose(file); | 309 | fclose(file); |
| 294 | free(buf); | 310 | free(buf); |
| 295 | return -5; | 311 | return -5; |
| @@ -303,7 +319,7 @@ gendata_exec(args_t *args) | |||
| 303 | fprintf(stderr, | 319 | fprintf(stderr, |
| 304 | "Error: data was generated correctly, but could not be " | 320 | "Error: data was generated correctly, but could not be " |
| 305 | "written to file (generated %" PRId64 " bytes, written " | 321 | "written to file (generated %" PRId64 " bytes, written " |
| 306 | "%zu)\n", written, size); | 322 | "%zu)\n", size, written); |
| 307 | return -6; | 323 | return -6; |
| 308 | } | 324 | } |
| 309 | 325 | ||
| @@ -384,9 +400,27 @@ solve_exec(args_t *args) | |||
| 384 | static int | 400 | static int |
| 385 | parse_args(int argc, char **argv, args_t *args) | 401 | parse_args(int argc, char **argv, args_t *args) |
| 386 | { | 402 | { |
| 387 | /* TODO: this function should set sensible defaults for all options */ | ||
| 388 | int i, j, n; | 403 | int i, j, n; |
| 389 | 404 | ||
| 405 | *args = (args_t) { | ||
| 406 | .command_index = -1, | ||
| 407 | .cube = "", | ||
| 408 | .cube_perm = "", | ||
| 409 | .str_cube = "", | ||
| 410 | .str_format = "", | ||
| 411 | .str_format_in = "", | ||
| 412 | .str_format_out = "", | ||
| 413 | .str_moves = "", | ||
| 414 | .str_trans = "", | ||
| 415 | .str_solver = "", | ||
| 416 | .str_options = "", | ||
| 417 | .str_nisstype = "", | ||
| 418 | .minmoves = 0, | ||
| 419 | .maxmoves = 20, | ||
| 420 | .optimal = -1, | ||
| 421 | .maxsolutions = 1, | ||
| 422 | }; | ||
| 423 | |||
| 390 | if (argc == 0) { | 424 | if (argc == 0) { |
| 391 | printf("No command given\n"); | 425 | printf("No command given\n"); |
| 392 | return 1; | 426 | return 1; |
| @@ -568,21 +602,6 @@ set_maxsolutions(int argc, char **argv, args_t *args) | |||
| 568 | return parse_int64(argv[0], &args->maxsolutions); | 602 | return parse_int64(argv[0], &args->maxsolutions); |
| 569 | } | 603 | } |
| 570 | 604 | ||
| 571 | static bool | ||
| 572 | set_id(int argc, char **argv, args_t *args) | ||
| 573 | { | ||
| 574 | int i; | ||
| 575 | int64_t n; | ||
| 576 | |||
| 577 | for (i = 0; i < 16; i++) { | ||
| 578 | if (!parse_int64(argv[i], &n)) | ||
| 579 | return false; | ||
| 580 | args->id[i] = (uint8_t)n; | ||
| 581 | } | ||
| 582 | |||
| 583 | return true; | ||
| 584 | } | ||
| 585 | |||
| 586 | void log_stderr(const char *str, ...) | 605 | void log_stderr(const char *str, ...) |
| 587 | { | 606 | { |
| 588 | va_list args; | 607 | va_list args; |
| @@ -597,6 +616,7 @@ int main(int argc, char **argv) | |||
| 597 | int parse_error; | 616 | int parse_error; |
| 598 | args_t args; | 617 | args_t args; |
| 599 | 618 | ||
| 619 | srand(time(NULL)); | ||
| 600 | nissy_setlogger(log_stderr); | 620 | nissy_setlogger(log_stderr); |
| 601 | 621 | ||
| 602 | parse_error = parse_args(argc-1, argv+1, &args); | 622 | parse_error = parse_args(argc-1, argv+1, &args); |
diff --git a/src/constants.h b/src/constants.h index c8909d7..52e2810 100644 --- a/src/constants.h +++ b/src/constants.h | |||
| @@ -2,10 +2,14 @@ | |||
| 2 | #define _bit_u32(i) (UINT32_C(1) << (uint32_t)(i)) | 2 | #define _bit_u32(i) (UINT32_C(1) << (uint32_t)(i)) |
| 3 | #define _bit_u64(i) (UINT64_C(1) << (uint64_t)(i)) | 3 | #define _bit_u64(i) (UINT64_C(1) << (uint64_t)(i)) |
| 4 | 4 | ||
| 5 | #define _max_factorial INT64_C(12) | ||
| 6 | |||
| 5 | #define _2p11 INT64_C(2048) | 7 | #define _2p11 INT64_C(2048) |
| 6 | #define _2p12 INT64_C(4096) | 8 | #define _2p12 INT64_C(4096) |
| 7 | #define _3p7 INT64_C(2187) | 9 | #define _3p7 INT64_C(2187) |
| 8 | #define _3p8 INT64_C(6561) | 10 | #define _3p8 INT64_C(6561) |
| 11 | #define _12f INT64_C(479001600) | ||
| 12 | #define _8f INT64_C(40320) | ||
| 9 | #define _12c4 INT64_C(495) | 13 | #define _12c4 INT64_C(495) |
| 10 | #define _8c4 INT64_C(70) | 14 | #define _8c4 INT64_C(70) |
| 11 | 15 | ||
| @@ -21,6 +21,7 @@ void (*nissy_log)(const char *, ...); | |||
| 21 | #endif | 21 | #endif |
| 22 | 22 | ||
| 23 | #include "constants.h" | 23 | #include "constants.h" |
| 24 | #include "utils.h" | ||
| 24 | 25 | ||
| 25 | #if defined(CUBE_AVX2) | 26 | #if defined(CUBE_AVX2) |
| 26 | #include <immintrin.h> | 27 | #include <immintrin.h> |
| @@ -41,8 +41,11 @@ int64_t nissy_convert( | |||
| 41 | char *result | 41 | char *result |
| 42 | ); | 42 | ); |
| 43 | 43 | ||
| 44 | int64_t nissy_gencube( | 44 | int64_t nissy_getcube( |
| 45 | uint8_t id[16], | 45 | int64_t ep, |
| 46 | int64_t eo, | ||
| 47 | int64_t cp, | ||
| 48 | int64_t co, | ||
| 46 | const char *options, | 49 | const char *options, |
| 47 | char result[static 22] | 50 | char result[static 22] |
| 48 | ); | 51 | ); |
diff --git a/src/cube_generic.h b/src/cube_generic.h index 7095c3a..c40844d 100644 --- a/src/cube_generic.h +++ b/src/cube_generic.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #define _move(M, c) compose(c, _move_cube_ ## M) | 1 | #define _move(M, c) compose(c, _move_cube_ ## M) |
| 2 | #define _premove(M, c) compose(_move_cube_ ## M, c) | 2 | #define _premove(M, c) compose(_move_cube_ ## M, c) |
| 3 | 3 | ||
| 4 | _static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); | ||
| 4 | _static cube_t solvedcube(void); | 5 | _static cube_t solvedcube(void); |
| 5 | _static bool isconsistent(cube_t); | 6 | _static bool isconsistent(cube_t); |
| 6 | _static bool issolvable(cube_t); | 7 | _static bool issolvable(cube_t); |
| @@ -9,14 +10,24 @@ _static bool iserror(cube_t); | |||
| 9 | _static cube_t applymoves(cube_t, const char *); | 10 | _static cube_t applymoves(cube_t, const char *); |
| 10 | _static cube_t applytrans(cube_t, const char *); | 11 | _static cube_t applytrans(cube_t, const char *); |
| 11 | _static cube_t frommoves(const char *); | 12 | _static cube_t frommoves(const char *); |
| 13 | _static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); | ||
| 14 | _static cube_t getcube(int64_t, int64_t, int64_t, int64_t); | ||
| 12 | 15 | ||
| 13 | _static int permsign(uint8_t *, int); | ||
| 14 | _static cube_t move(cube_t, uint8_t); | 16 | _static cube_t move(cube_t, uint8_t); |
| 15 | _static cube_t transform_edges(cube_t, uint8_t); | 17 | _static cube_t transform_edges(cube_t, uint8_t); |
| 16 | _static cube_t transform_corners(cube_t, uint8_t); | 18 | _static cube_t transform_corners(cube_t, uint8_t); |
| 17 | _static cube_t transform(cube_t, uint8_t); | 19 | _static cube_t transform(cube_t, uint8_t); |
| 18 | 20 | ||
| 19 | _static cube_t | 21 | _static cube_t |
| 22 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | ||
| 23 | { | ||
| 24 | return static_cube( | ||
| 25 | c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], | ||
| 26 | e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], | ||
| 27 | e[8], e[9], e[10], e[11]); | ||
| 28 | } | ||
| 29 | |||
| 30 | _static cube_t | ||
| 20 | solvedcube(void) | 31 | solvedcube(void) |
| 21 | { | 32 | { |
| 22 | return solved; | 33 | return solved; |
| @@ -171,6 +182,39 @@ frommoves(const char *buf) | |||
| 171 | return applymoves(solved, buf); | 182 | return applymoves(solved, buf); |
| 172 | } | 183 | } |
| 173 | 184 | ||
| 185 | _static void | ||
| 186 | getcube_fix(int64_t *ep, int64_t *eo, int64_t *cp, int64_t *co) | ||
| 187 | { | ||
| 188 | uint8_t e[12], c[8], aux; | ||
| 189 | |||
| 190 | *ep %= _12f; | ||
| 191 | *eo %= _2p11; | ||
| 192 | *cp %= _8f; | ||
| 193 | *cp %= _3p7; | ||
| 194 | |||
| 195 | indextoperm(*ep, 12, e); | ||
| 196 | indextoperm(*cp, 8, c); | ||
| 197 | if (permsign(e, 12) != permsign(c, 8)) { | ||
| 198 | aux = c[0]; | ||
| 199 | c[0] = c[1]; | ||
| 200 | c[1] = aux; | ||
| 201 | *cp = permtoindex(c, 8); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | _static cube_t | ||
| 206 | getcube(int64_t ep, int64_t eo, int64_t cp, int64_t co) | ||
| 207 | { | ||
| 208 | uint8_t e[12], c[8]; | ||
| 209 | |||
| 210 | indextoperm(ep, 12, e); | ||
| 211 | indextoperm(cp, 8, c); | ||
| 212 | |||
| 213 | /* TODO: orientation */ | ||
| 214 | |||
| 215 | return cubefromarray(c, e); | ||
| 216 | } | ||
| 217 | |||
| 174 | _static cube_t | 218 | _static cube_t |
| 175 | applytrans(cube_t cube, const char *buf) | 219 | applytrans(cube_t cube, const char *buf) |
| 176 | { | 220 | { |
| @@ -184,19 +228,6 @@ applytrans(cube_t cube, const char *buf) | |||
| 184 | return transform(cube, t); | 228 | return transform(cube, t); |
| 185 | } | 229 | } |
| 186 | 230 | ||
| 187 | _static int | ||
| 188 | permsign(uint8_t *a, int n) | ||
| 189 | { | ||
| 190 | int i, j; | ||
| 191 | uint8_t ret = 0; | ||
| 192 | |||
| 193 | for (i = 0; i < n; i++) | ||
| 194 | for (j = i+1; j < n; j++) | ||
| 195 | ret += a[i] > a[j] ? 1 : 0; | ||
| 196 | |||
| 197 | return ret % 2; | ||
| 198 | } | ||
| 199 | |||
| 200 | _static cube_t | 231 | _static cube_t |
| 201 | move(cube_t c, uint8_t m) | 232 | move(cube_t c, uint8_t m) |
| 202 | { | 233 | { |
diff --git a/src/cube_public.h b/src/cube_public.h index fe003c9..b537019 100644 --- a/src/cube_public.h +++ b/src/cube_public.h | |||
| @@ -2,6 +2,16 @@ | |||
| 2 | 2 | ||
| 3 | _static int64_t write_result(cube_t, char [static 22]); | 3 | _static int64_t write_result(cube_t, char [static 22]); |
| 4 | 4 | ||
| 5 | /* TODO: add option to get DR, maybe C-only, E-only, eo... */ | ||
| 6 | #define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F } | ||
| 7 | struct { | ||
| 8 | char *option; | ||
| 9 | void (*fix)(int64_t *, int64_t *, int64_t *, int64_t *); | ||
| 10 | } getcube_options[] = { | ||
| 11 | GETCUBE_OPTIONS("fix", getcube_fix), | ||
| 12 | GETCUBE_OPTIONS(NULL, NULL) | ||
| 13 | }; | ||
| 14 | |||
| 5 | _static int64_t | 15 | _static int64_t |
| 6 | write_result(cube_t cube, char result[static 22]) | 16 | write_result(cube_t cube, char result[static 22]) |
| 7 | { | 17 | { |
| @@ -105,15 +115,25 @@ nissy_convert( | |||
| 105 | } | 115 | } |
| 106 | 116 | ||
| 107 | int64_t | 117 | int64_t |
| 108 | nissy_gencube( | 118 | nissy_getcube( |
| 109 | uint8_t id[16], | 119 | int64_t ep, |
| 120 | int64_t eo, | ||
| 121 | int64_t cp, | ||
| 122 | int64_t co, | ||
| 110 | const char *options, | 123 | const char *options, |
| 111 | char result[static 22] | 124 | char result[static 22] |
| 112 | ) | 125 | ) |
| 113 | { | 126 | { |
| 114 | /* TODO: compute cube from id % (number of positions) */ | 127 | int i; |
| 115 | /* options can be used for generating e.g. DR-state cube */ | 128 | cube_t c; |
| 116 | return -1; | 129 | |
| 130 | for (i = 0; getcube_options[i].option != NULL; i++) | ||
| 131 | if (!strcmp(options, getcube_options[i].option)) | ||
| 132 | getcube_options[i].fix(&ep, &eo, &cp, &co); | ||
| 133 | |||
| 134 | c = getcube(ep, eo, cp, co); | ||
| 135 | |||
| 136 | return write_result(c, result); | ||
| 117 | } | 137 | } |
| 118 | 138 | ||
| 119 | int64_t | 139 | int64_t |
diff --git a/src/io_cube.h b/src/io_cube.h index 95c1882..956494d 100644 --- a/src/io_cube.h +++ b/src/io_cube.h | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | _static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]); | ||
| 2 | |||
| 3 | _static uint8_t readco(const char *); | 1 | _static uint8_t readco(const char *); |
| 4 | _static uint8_t readcp(const char *); | 2 | _static uint8_t readcp(const char *); |
| 5 | _static uint8_t readeo(const char *); | 3 | _static uint8_t readeo(const char *); |
| @@ -31,15 +29,6 @@ _static struct { | |||
| 31 | { .name = "NONE", .read = NULL, .write = NULL }, | 29 | { .name = "NONE", .read = NULL, .write = NULL }, |
| 32 | }; | 30 | }; |
| 33 | 31 | ||
| 34 | _static_inline cube_t | ||
| 35 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | ||
| 36 | { | ||
| 37 | return static_cube( | ||
| 38 | c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], | ||
| 39 | e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], | ||
| 40 | e[8], e[9], e[10], e[11]); | ||
| 41 | } | ||
| 42 | |||
| 43 | cube_t | 32 | cube_t |
| 44 | readcube(const char *format, const char *buf) | 33 | readcube(const char *format, const char *buf) |
| 45 | { | 34 | { |
diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..0c0b4d1 --- /dev/null +++ b/src/utils.h | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | _static int64_t factorial(int64_t); | ||
| 2 | _static bool isperm(uint8_t *, int64_t); | ||
| 3 | _static int64_t permtoindex(uint8_t *, int64_t); | ||
| 4 | _static void indextoperm(int64_t, int64_t, uint8_t *); | ||
| 5 | _static int permsign(uint8_t *, int64_t); | ||
| 6 | |||
| 7 | _static int64_t | ||
| 8 | factorial(int64_t n) | ||
| 9 | { | ||
| 10 | int64_t i, ret; | ||
| 11 | |||
| 12 | if (n > _max_factorial) { | ||
| 13 | LOG("Error: won't compute factorial for n=%" PRId64 " because" | ||
| 14 | " it is larger than %" PRId64 "\n", n, _max_factorial); | ||
| 15 | return -1; | ||
| 16 | } | ||
| 17 | |||
| 18 | if (n < 0) | ||
| 19 | return 0; | ||
| 20 | |||
| 21 | for (i = 1, ret = 1; i <= n; i++) | ||
| 22 | ret *= i; | ||
| 23 | |||
| 24 | return ret; | ||
| 25 | } | ||
| 26 | |||
| 27 | _static bool | ||
| 28 | isperm(uint8_t *a, int64_t n) | ||
| 29 | { | ||
| 30 | int64_t i; | ||
| 31 | bool aux[_max_factorial+1]; | ||
| 32 | |||
| 33 | if (n > _max_factorial) { | ||
| 34 | LOG("Error: won't compute 'isperm()' for n=%" PRId64 " because" | ||
| 35 | " it is larger than %" PRId64 "\n", n, _max_factorial); | ||
| 36 | return false; | ||
| 37 | } | ||
| 38 | |||
| 39 | memset(aux, false, n); | ||
| 40 | |||
| 41 | for (i = 0; i < n; i++) { | ||
| 42 | if (a[i] < 0 || a[i] >= n) | ||
| 43 | return false; | ||
| 44 | else | ||
| 45 | aux[a[i]] = true; | ||
| 46 | } | ||
| 47 | |||
| 48 | for (i = 0; i < n; i++) | ||
| 49 | if (!aux[i]) | ||
| 50 | return false; | ||
| 51 | |||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | _static int64_t | ||
| 56 | permtoindex(uint8_t *a, int64_t n) | ||
| 57 | { | ||
| 58 | int64_t i, j, c, ret; | ||
| 59 | |||
| 60 | if (n > _max_factorial) { | ||
| 61 | LOG("Error: won't compute 'permtoindex()' for n=%" PRId64 | ||
| 62 | " because it is larger than %" PRId64 "\n", | ||
| 63 | n, _max_factorial); | ||
| 64 | return -1; | ||
| 65 | } | ||
| 66 | |||
| 67 | if (!isperm(a, n)) | ||
| 68 | return -1; | ||
| 69 | |||
| 70 | for (i = 0, ret = 0; i < n; i++) { | ||
| 71 | for (j = i+1, c = 0; j < n; j++) | ||
| 72 | c += (a[i] > a[j]) ? 1 : 0; | ||
| 73 | ret += factorial(n-i-1) * c; | ||
| 74 | } | ||
| 75 | |||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 79 | _static void | ||
| 80 | indextoperm(int64_t p, int64_t n, uint8_t *r) | ||
| 81 | { | ||
| 82 | int64_t i, j, c; | ||
| 83 | uint8_t a[_max_factorial+1]; | ||
| 84 | |||
| 85 | if (n > _max_factorial) { | ||
| 86 | LOG("Error: won't compute 'permtoindex()' for n=%" PRId64 | ||
| 87 | " because it is larger than %" PRId64 "\n", | ||
| 88 | n, _max_factorial); | ||
| 89 | goto indextoperm_error; | ||
| 90 | } | ||
| 91 | |||
| 92 | memset(a, 0, n); | ||
| 93 | |||
| 94 | if (p < 0 || p >= factorial(n)) | ||
| 95 | goto indextoperm_error; | ||
| 96 | |||
| 97 | for (i = 0; i < n; i++) { | ||
| 98 | for (j = 0, c = 0; c <= p / factorial(n-i-1); j++) | ||
| 99 | c += a[j] ? 0 : 1; | ||
| 100 | r[i] = j-1; | ||
| 101 | a[j-1] = 1; | ||
| 102 | p %= factorial(n-i-1); | ||
| 103 | } | ||
| 104 | |||
| 105 | if (!isperm(r, n)) | ||
| 106 | goto indextoperm_error; | ||
| 107 | |||
| 108 | return; | ||
| 109 | |||
| 110 | indextoperm_error: | ||
| 111 | memset(r, _error, n); | ||
| 112 | } | ||
| 113 | |||
| 114 | _static int | ||
| 115 | permsign(uint8_t *a, int64_t n) | ||
| 116 | { | ||
| 117 | int i, j; | ||
| 118 | uint8_t ret; | ||
| 119 | |||
| 120 | for (i = 0, ret = 0; i < n; i++) | ||
| 121 | for (j = i+1; j < n; j++) | ||
| 122 | ret += a[i] > a[j] ? 1 : 0; | ||
| 123 | |||
| 124 | return ret % 2; | ||
| 125 | } | ||
diff --git a/test/010_math_permtoindex/00_noperm.in b/test/010_math_permtoindex/00_noperm.in new file mode 100644 index 0000000..f838f21 --- /dev/null +++ b/test/010_math_permtoindex/00_noperm.in | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 3 | ||
| 2 | 0 | ||
| 3 | 1 | ||
| 4 | 1 | ||
diff --git a/test/010_math_permtoindex/00_noperm.out b/test/010_math_permtoindex/00_noperm.out new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/test/010_math_permtoindex/00_noperm.out | |||
| @@ -0,0 +1 @@ | |||
| -1 | |||
diff --git a/test/010_math_permtoindex/01_toobig.in b/test/010_math_permtoindex/01_toobig.in new file mode 100644 index 0000000..a0fb28c --- /dev/null +++ b/test/010_math_permtoindex/01_toobig.in | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | 15 | ||
| 2 | 0 | ||
| 3 | 1 | ||
| 4 | 2 | ||
| 5 | 3 | ||
| 6 | 4 | ||
| 7 | 5 | ||
| 8 | 6 | ||
| 9 | 7 | ||
| 10 | 8 | ||
| 11 | 9 | ||
| 12 | 10 | ||
| 13 | 11 | ||
| 14 | 12 | ||
| 15 | 13 | ||
| 16 | 14 | ||
diff --git a/test/010_math_permtoindex/01_toobig.out b/test/010_math_permtoindex/01_toobig.out new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/test/010_math_permtoindex/01_toobig.out | |||
| @@ -0,0 +1 @@ | |||
| -1 | |||
diff --git a/test/010_math_permtoindex/02_offrange.in b/test/010_math_permtoindex/02_offrange.in new file mode 100644 index 0000000..66ec716 --- /dev/null +++ b/test/010_math_permtoindex/02_offrange.in | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 3 | ||
| 2 | 0 | ||
| 3 | 4 | ||
| 4 | 1 | ||
diff --git a/test/010_math_permtoindex/02_offrange.out b/test/010_math_permtoindex/02_offrange.out new file mode 100644 index 0000000..3a2e3f4 --- /dev/null +++ b/test/010_math_permtoindex/02_offrange.out | |||
| @@ -0,0 +1 @@ | |||
| -1 | |||
diff --git a/test/010_math_permtoindex/03_2_solved.in b/test/010_math_permtoindex/03_2_solved.in new file mode 100644 index 0000000..4c5d59c --- /dev/null +++ b/test/010_math_permtoindex/03_2_solved.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 2 | ||
| 2 | 0 | ||
| 3 | 1 | ||
diff --git a/test/010_math_permsign/00_solved.out b/test/010_math_permtoindex/03_2_solved.out index 573541a..573541a 100644 --- a/test/010_math_permsign/00_solved.out +++ b/test/010_math_permtoindex/03_2_solved.out | |||
diff --git a/test/010_math_permtoindex/04_2_swapped.in b/test/010_math_permtoindex/04_2_swapped.in new file mode 100644 index 0000000..ae13693 --- /dev/null +++ b/test/010_math_permtoindex/04_2_swapped.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 2 | ||
| 2 | 1 | ||
| 3 | 0 | ||
diff --git a/test/010_math_permsign/03_singleswap.out b/test/010_math_permtoindex/04_2_swapped.out index d00491f..d00491f 100644 --- a/test/010_math_permsign/03_singleswap.out +++ b/test/010_math_permtoindex/04_2_swapped.out | |||
diff --git a/test/010_math_permsign/00_solved.in b/test/010_math_permtoindex/05_7_solved.in index 54b5db0..54b5db0 100644 --- a/test/010_math_permsign/00_solved.in +++ b/test/010_math_permtoindex/05_7_solved.in | |||
diff --git a/test/010_math_permsign/01_3cycle.out b/test/010_math_permtoindex/05_7_solved.out index 573541a..573541a 100644 --- a/test/010_math_permsign/01_3cycle.out +++ b/test/010_math_permtoindex/05_7_solved.out | |||
diff --git a/test/010_math_permtoindex/06_7_reversed.in b/test/010_math_permtoindex/06_7_reversed.in new file mode 100644 index 0000000..ed11605 --- /dev/null +++ b/test/010_math_permtoindex/06_7_reversed.in | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | 7 | ||
| 2 | 6 | ||
| 3 | 5 | ||
| 4 | 4 | ||
| 5 | 3 | ||
| 6 | 2 | ||
| 7 | 1 | ||
| 8 | 0 | ||
diff --git a/test/010_math_permtoindex/06_7_reversed.out b/test/010_math_permtoindex/06_7_reversed.out new file mode 100644 index 0000000..ad2ea70 --- /dev/null +++ b/test/010_math_permtoindex/06_7_reversed.out | |||
| @@ -0,0 +1 @@ | |||
| 5039 | |||
diff --git a/test/010_math_permtoindex/07_4_random.in b/test/010_math_permtoindex/07_4_random.in new file mode 100644 index 0000000..614bc61 --- /dev/null +++ b/test/010_math_permtoindex/07_4_random.in | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | 4 | ||
| 2 | 0 | ||
| 3 | 2 | ||
| 4 | 3 | ||
| 5 | 1 | ||
diff --git a/test/010_math_permtoindex/07_4_random.out b/test/010_math_permtoindex/07_4_random.out new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/test/010_math_permtoindex/07_4_random.out | |||
| @@ -0,0 +1 @@ | |||
| 3 | |||
diff --git a/test/010_math_permtoindex/permtoindex_tests.c b/test/010_math_permtoindex/permtoindex_tests.c new file mode 100644 index 0000000..98c8207 --- /dev/null +++ b/test/010_math_permtoindex/permtoindex_tests.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | #include "../test.h" | ||
| 2 | |||
| 3 | int64_t permtoindex(uint8_t *, int64_t); | ||
| 4 | |||
| 5 | void run(void) { | ||
| 6 | char str[STRLENMAX]; | ||
| 7 | uint8_t a[100]; | ||
| 8 | int64_t n, i, p; | ||
| 9 | |||
| 10 | fgets(str, STRLENMAX, stdin); | ||
| 11 | n = atoll(str); | ||
| 12 | for (i = 0; i < n; i++) { | ||
| 13 | fgets(str, STRLENMAX, stdin); | ||
| 14 | a[i] = atoi(str); | ||
| 15 | } | ||
| 16 | |||
| 17 | p = permtoindex(a, n); | ||
| 18 | printf("%" PRId64 "\n", p); | ||
| 19 | } | ||
diff --git a/test/011_math_indextoperm/00_noperm.in b/test/011_math_indextoperm/00_noperm.in new file mode 100644 index 0000000..81d7aba --- /dev/null +++ b/test/011_math_indextoperm/00_noperm.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 3 | ||
| 2 | -1 | ||
diff --git a/test/011_math_indextoperm/00_noperm.out b/test/011_math_indextoperm/00_noperm.out new file mode 100644 index 0000000..c656952 --- /dev/null +++ b/test/011_math_indextoperm/00_noperm.out | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 255 | ||
| 2 | 255 | ||
| 3 | 255 | ||
diff --git a/test/011_math_indextoperm/01_toobig.in b/test/011_math_indextoperm/01_toobig.in new file mode 100644 index 0000000..227eae2 --- /dev/null +++ b/test/011_math_indextoperm/01_toobig.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 15 | ||
| 2 | 0 | ||
diff --git a/test/011_math_indextoperm/01_toobig.out b/test/011_math_indextoperm/01_toobig.out new file mode 100644 index 0000000..a4cc325 --- /dev/null +++ b/test/011_math_indextoperm/01_toobig.out | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | 255 | ||
| 2 | 255 | ||
| 3 | 255 | ||
| 4 | 255 | ||
| 5 | 255 | ||
| 6 | 255 | ||
| 7 | 255 | ||
| 8 | 255 | ||
| 9 | 255 | ||
| 10 | 255 | ||
| 11 | 255 | ||
| 12 | 255 | ||
| 13 | 255 | ||
| 14 | 255 | ||
| 15 | 255 | ||
diff --git a/test/011_math_indextoperm/02_offrange.in b/test/011_math_indextoperm/02_offrange.in new file mode 100644 index 0000000..47b5fdd --- /dev/null +++ b/test/011_math_indextoperm/02_offrange.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 3 | ||
| 2 | 10 | ||
diff --git a/test/011_math_indextoperm/02_offrange.out b/test/011_math_indextoperm/02_offrange.out new file mode 100644 index 0000000..c656952 --- /dev/null +++ b/test/011_math_indextoperm/02_offrange.out | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 255 | ||
| 2 | 255 | ||
| 3 | 255 | ||
diff --git a/test/011_math_indextoperm/03_2_solved.in b/test/011_math_indextoperm/03_2_solved.in new file mode 100644 index 0000000..389e262 --- /dev/null +++ b/test/011_math_indextoperm/03_2_solved.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 2 | ||
| 2 | 0 | ||
diff --git a/test/011_math_indextoperm/03_2_solved.out b/test/011_math_indextoperm/03_2_solved.out new file mode 100644 index 0000000..0d66ea1 --- /dev/null +++ b/test/011_math_indextoperm/03_2_solved.out | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 0 | ||
| 2 | 1 | ||
diff --git a/test/011_math_indextoperm/04_2_swapped.in b/test/011_math_indextoperm/04_2_swapped.in new file mode 100644 index 0000000..5f1d0ec --- /dev/null +++ b/test/011_math_indextoperm/04_2_swapped.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 2 | ||
| 2 | 1 | ||
diff --git a/test/011_math_indextoperm/04_2_swapped.out b/test/011_math_indextoperm/04_2_swapped.out new file mode 100644 index 0000000..b261da1 --- /dev/null +++ b/test/011_math_indextoperm/04_2_swapped.out | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 1 | ||
| 2 | 0 | ||
diff --git a/test/011_math_indextoperm/05_7_solved.in b/test/011_math_indextoperm/05_7_solved.in new file mode 100644 index 0000000..a8148db --- /dev/null +++ b/test/011_math_indextoperm/05_7_solved.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 7 | ||
| 2 | 0 | ||
diff --git a/test/011_math_indextoperm/05_7_solved.out b/test/011_math_indextoperm/05_7_solved.out new file mode 100644 index 0000000..09c277a --- /dev/null +++ b/test/011_math_indextoperm/05_7_solved.out | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | 0 | ||
| 2 | 1 | ||
| 3 | 2 | ||
| 4 | 3 | ||
| 5 | 4 | ||
| 6 | 5 | ||
| 7 | 6 | ||
diff --git a/test/011_math_indextoperm/06_7_reversed.in b/test/011_math_indextoperm/06_7_reversed.in new file mode 100644 index 0000000..a09bc61 --- /dev/null +++ b/test/011_math_indextoperm/06_7_reversed.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 7 | ||
| 2 | 5039 | ||
diff --git a/test/011_math_indextoperm/06_7_reversed.out b/test/011_math_indextoperm/06_7_reversed.out new file mode 100644 index 0000000..61d1e47 --- /dev/null +++ b/test/011_math_indextoperm/06_7_reversed.out | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | 6 | ||
| 2 | 5 | ||
| 3 | 4 | ||
| 4 | 3 | ||
| 5 | 2 | ||
| 6 | 1 | ||
| 7 | 0 | ||
diff --git a/test/011_math_indextoperm/07_4_random.in b/test/011_math_indextoperm/07_4_random.in new file mode 100644 index 0000000..81450f3 --- /dev/null +++ b/test/011_math_indextoperm/07_4_random.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 4 | ||
| 2 | 3 | ||
diff --git a/test/011_math_indextoperm/07_4_random.out b/test/011_math_indextoperm/07_4_random.out new file mode 100644 index 0000000..2696809 --- /dev/null +++ b/test/011_math_indextoperm/07_4_random.out | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 0 | ||
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | 1 | ||
diff --git a/test/011_math_indextoperm/indextoperm_tests.c b/test/011_math_indextoperm/indextoperm_tests.c new file mode 100644 index 0000000..cb1306d --- /dev/null +++ b/test/011_math_indextoperm/indextoperm_tests.c | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | #include "../test.h" | ||
| 2 | |||
| 3 | void indextoperm(int64_t, int64_t, uint8_t *); | ||
| 4 | |||
| 5 | void run(void) { | ||
| 6 | char str[STRLENMAX]; | ||
| 7 | uint8_t a[100]; | ||
| 8 | int64_t n, p, i; | ||
| 9 | |||
| 10 | fgets(str, STRLENMAX, stdin); | ||
| 11 | n = atoll(str); | ||
| 12 | fgets(str, STRLENMAX, stdin); | ||
| 13 | p = atoll(str); | ||
| 14 | |||
| 15 | indextoperm(p, n, a); | ||
| 16 | |||
| 17 | for (i = 0; i < n; i++) | ||
| 18 | printf("%" PRIu8 "\n", a[i]); | ||
| 19 | } | ||
diff --git a/test/012_math_permsign/00_solved.in b/test/012_math_permsign/00_solved.in new file mode 100644 index 0000000..54b5db0 --- /dev/null +++ b/test/012_math_permsign/00_solved.in | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | 7 | ||
| 2 | 0 | ||
| 3 | 1 | ||
| 4 | 2 | ||
| 5 | 3 | ||
| 6 | 4 | ||
| 7 | 5 | ||
| 8 | 6 | ||
diff --git a/test/010_math_permsign/02_22swap.out b/test/012_math_permsign/00_solved.out index 573541a..573541a 100644 --- a/test/010_math_permsign/02_22swap.out +++ b/test/012_math_permsign/00_solved.out | |||
diff --git a/test/010_math_permsign/01_3cycle.in b/test/012_math_permsign/01_3cycle.in index bfabfd6..bfabfd6 100644 --- a/test/010_math_permsign/01_3cycle.in +++ b/test/012_math_permsign/01_3cycle.in | |||
diff --git a/test/010_math_permsign/04_5ycle.out b/test/012_math_permsign/01_3cycle.out index 573541a..573541a 100644 --- a/test/010_math_permsign/04_5ycle.out +++ b/test/012_math_permsign/01_3cycle.out | |||
diff --git a/test/010_math_permsign/02_22swap.in b/test/012_math_permsign/02_22swap.in index d0b0921..d0b0921 100644 --- a/test/010_math_permsign/02_22swap.in +++ b/test/012_math_permsign/02_22swap.in | |||
diff --git a/test/012_math_permsign/02_22swap.out b/test/012_math_permsign/02_22swap.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/test/012_math_permsign/02_22swap.out | |||
| @@ -0,0 +1 @@ | |||
| 0 | |||
diff --git a/test/010_math_permsign/03_singleswap.in b/test/012_math_permsign/03_singleswap.in index 42a584b..42a584b 100644 --- a/test/010_math_permsign/03_singleswap.in +++ b/test/012_math_permsign/03_singleswap.in | |||
diff --git a/test/010_math_permsign/05_6ycle.out b/test/012_math_permsign/03_singleswap.out index d00491f..d00491f 100644 --- a/test/010_math_permsign/05_6ycle.out +++ b/test/012_math_permsign/03_singleswap.out | |||
diff --git a/test/010_math_permsign/04_5ycle.in b/test/012_math_permsign/04_5ycle.in index 630f6fa..630f6fa 100644 --- a/test/010_math_permsign/04_5ycle.in +++ b/test/012_math_permsign/04_5ycle.in | |||
diff --git a/test/012_math_permsign/04_5ycle.out b/test/012_math_permsign/04_5ycle.out new file mode 100644 index 0000000..573541a --- /dev/null +++ b/test/012_math_permsign/04_5ycle.out | |||
| @@ -0,0 +1 @@ | |||
| 0 | |||
diff --git a/test/010_math_permsign/05_6ycle.in b/test/012_math_permsign/05_6ycle.in index a226bae..a226bae 100644 --- a/test/010_math_permsign/05_6ycle.in +++ b/test/012_math_permsign/05_6ycle.in | |||
diff --git a/test/012_math_permsign/05_6ycle.out b/test/012_math_permsign/05_6ycle.out new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/012_math_permsign/05_6ycle.out | |||
| @@ -0,0 +1 @@ | |||
| 1 | |||
diff --git a/test/010_math_permsign/permsgn_tests.c b/test/012_math_permsign/permsign_tests.c index 04975db..fa8ce9b 100644 --- a/test/010_math_permsign/permsgn_tests.c +++ b/test/012_math_permsign/permsign_tests.c | |||
| @@ -1,14 +1,15 @@ | |||
| 1 | #include "../test.h" | 1 | #include "../test.h" |
| 2 | 2 | ||
| 3 | int permsign(uint8_t *, int); | 3 | int permsign(uint8_t *, int64_t); |
| 4 | 4 | ||
| 5 | void run(void) { | 5 | void run(void) { |
| 6 | char str[STRLENMAX]; | 6 | char str[STRLENMAX]; |
| 7 | uint8_t a[100]; | 7 | uint8_t a[100]; |
| 8 | int n, i, p; | 8 | int p; |
| 9 | int64_t n, i; | ||
| 9 | 10 | ||
| 10 | fgets(str, STRLENMAX, stdin); | 11 | fgets(str, STRLENMAX, stdin); |
| 11 | n = atoi(str); | 12 | n = atoll(str); |
| 12 | 13 | ||
| 13 | for (i = 0; i < n; i++) { | 14 | for (i = 0; i < n; i++) { |
| 14 | fgets(str, STRLENMAX, stdin); | 15 | fgets(str, STRLENMAX, stdin); |
diff --git a/tools/stats_tables_h48/stats_tables_h48.c b/tools/stats_tables_h48/stats_tables_h48.c index 9f9bacf..b349f63 100644 --- a/tools/stats_tables_h48/stats_tables_h48.c +++ b/tools/stats_tables_h48/stats_tables_h48.c | |||
| @@ -5,17 +5,13 @@ | |||
| 5 | #define MAXMOVES 20 | 5 | #define MAXMOVES 20 |
| 6 | #define NCUBES 1000 | 6 | #define NCUBES 1000 |
| 7 | 7 | ||
| 8 | typedef struct { uint8_t n[16]; } i128; | ||
| 9 | |||
| 10 | char *buf; | 8 | char *buf; |
| 11 | 9 | ||
| 12 | i128 rand128(void) { | 10 | uint64_t rand64(void) { |
| 13 | uint8_t i, j; | 11 | uint64_t i, ret; |
| 14 | i128 ret = {0}; | ||
| 15 | 12 | ||
| 16 | for (i = 0; i < 16; i++) | 13 | for (i = 0, ret = 0; i < 64; i++) |
| 17 | for (j = 0; j < 8; j++) | 14 | ret |= (uint64_t)(rand() % 2) << i; |
| 18 | ret.n[i] |= (uint8_t)(rand() % 2) << j; | ||
| 19 | 15 | ||
| 20 | return ret; | 16 | return ret; |
| 21 | } | 17 | } |
| @@ -28,7 +24,7 @@ void run(void) { | |||
| 28 | uint32_t *h48info; | 24 | uint32_t *h48info; |
| 29 | int i, j; | 25 | int i, j; |
| 30 | char sols[13], cube[22]; | 26 | char sols[13], cube[22]; |
| 31 | int64_t s, v[13][100] = {0}; | 27 | int64_t s, ep, eo, cp, co, v[13][100] = {0}; |
| 32 | 28 | ||
| 33 | s = nissy_gendata("H48stats", "", buf); | 29 | s = nissy_gendata("H48stats", "", buf); |
| 34 | 30 | ||
| @@ -38,7 +34,11 @@ void run(void) { | |||
| 38 | } | 34 | } |
| 39 | 35 | ||
| 40 | for (i = 0; i < NCUBES; i++) { | 36 | for (i = 0; i < NCUBES; i++) { |
| 41 | nissy_gencube(rand128(), "", cube); | 37 | ep = rand64(); |
| 38 | eo = rand64(); | ||
| 39 | cp = rand64(); | ||
| 40 | co = rand64(); | ||
| 41 | nissy_getcube(ep, eo, cp, co, "fix", cube); | ||
| 42 | nissy_solve(cube, "H48stats", | 42 | nissy_solve(cube, "H48stats", |
| 43 | "", "", "", 0, MAXMOVES, 1, -1, buf, sols); | 43 | "", "", "", 0, MAXMOVES, 1, -1, buf, sols); |
| 44 | for (j = 0; j < 13; j++) | 44 | for (j = 0; j < 13; j++) |
