diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | TODO.txt | 9 | ||||
| -rw-r--r-- | src/cube_public.h | 21 | ||||
| -rw-r--r-- | src/solve_h48.h | 94 | ||||
| -rw-r--r-- | test/103_gendata_h48/00_h_0.in | 1 | ||||
| -rw-r--r-- | test/103_gendata_h48/01_h_1.in | 1 | ||||
| -rw-r--r-- | test/103_gendata_h48/01_h_1.out | 23 | ||||
| -rw-r--r-- | test/103_gendata_h48_h0/00_h_0.in | 0 | ||||
| -rw-r--r-- | test/103_gendata_h48_h0/00_h_0.out (renamed from test/103_gendata_h48/00_h_0.out) | 0 | ||||
| -rw-r--r-- | test/103_gendata_h48_h0/gendata_h48_tests.c (renamed from test/103_gendata_h48/gendata_h48_tests.c) | 13 | ||||
| -rwxr-xr-x | tools/run_tool.sh | 14 | ||||
| -rw-r--r-- | tools/stats_tables_h48/stats_tables_h48.c | 85 |
13 files changed, 150 insertions, 119 deletions
| @@ -10,5 +10,6 @@ tables/* | |||
| 10 | test/*/runtest | 10 | test/*/runtest |
| 11 | test/run | 11 | test/run |
| 12 | test/last.* | 12 | test/last.* |
| 13 | tools/results | ||
| 13 | *.o | 14 | *.o |
| 14 | *.s | 15 | *.s |
| @@ -18,8 +18,13 @@ test: debugcube.o | |||
| 18 | CUBETYPE=${CUBETYPE} TEST=${TEST} ./test/test.sh | 18 | CUBETYPE=${CUBETYPE} TEST=${TEST} ./test/test.sh |
| 19 | 19 | ||
| 20 | tool: cube.o | 20 | tool: cube.o |
| 21 | mkdir -p tools/results | ||
| 21 | CUBETYPE=${CUBETYPE} ./tools/run_tool.sh | 22 | CUBETYPE=${CUBETYPE} ./tools/run_tool.sh |
| 22 | 23 | ||
| 24 | debugtool: debugcube.o | ||
| 25 | mkdir -p tools/results | ||
| 26 | CUBETYPE=${CUBETYPE} DEBUG=1 ./tools/run_tool.sh | ||
| 27 | |||
| 23 | shell: cube.o | 28 | shell: cube.o |
| 24 | mkdir -p tables | 29 | mkdir -p tables |
| 25 | ${CC} ${CFLAGS} -o run cube.o shell.c | 30 | ${CC} ${CFLAGS} -o run cube.o shell.c |
| @@ -28,4 +33,4 @@ debugshell: debugcube.o | |||
| 28 | mkdir -p tables | 33 | mkdir -p tables |
| 29 | ${CC} ${DBGFLAGS} -o run debugcube.o shell.c | 34 | ${CC} ${DBGFLAGS} -o run debugcube.o shell.c |
| 30 | 35 | ||
| 31 | .PHONY: all clean test tool shell debugshell | 36 | .PHONY: all clean test tool debugtool shell debugshell |
| @@ -1,7 +1,5 @@ | |||
| 1 | Check stats for all tables using H48stats solver | 1 | Check stats for all tables using H48stats solver |
| 2 | - optional: dr states (includes "fix" option) | 2 | - what now? |
| 3 | - implement tool for stats | ||
| 4 | - output to file, only write cocsep to stdout | ||
| 5 | 3 | ||
| 6 | Bug in esep table generation | 4 | Bug in esep table generation |
| 7 | - Fails for UFRUFU, try command | 5 | - Fails for UFRUFU, try command |
| @@ -18,8 +16,9 @@ Bug in esep table generation | |||
| 18 | 16 | ||
| 19 | Solver | 17 | Solver |
| 20 | - cleanup h48 solver | 18 | - cleanup h48 solver |
| 21 | - do not copy dfsarg, change and undo | 19 | - do not copy dfsarg, change and undo |
| 22 | - implement and use premove (and test) instead of inverting | 20 | - implement and use premove (and test) instead of inverting |
| 21 | - improve name of tables file in shell.c (include h value, maybe k, max) | ||
| 23 | - benchmark for solve | 22 | - benchmark for solve |
| 24 | table generation, where to keep tables? in benchmark folder or in tables/? | 23 | table generation, where to keep tables? in benchmark folder or in tables/? |
| 25 | - more tricks for solver, optimize, try larger tables | 24 | - more tricks for solver, optimize, try larger tables |
diff --git a/src/cube_public.h b/src/cube_public.h index b537019..e080f40 100644 --- a/src/cube_public.h +++ b/src/cube_public.h | |||
| @@ -156,17 +156,22 @@ nissy_gendata( | |||
| 156 | int64_t ret; | 156 | int64_t ret; |
| 157 | uint8_t maxdepth, h, i, j; | 157 | uint8_t maxdepth, h, i, j; |
| 158 | 158 | ||
| 159 | if (!strcmp(solver, "H48")) { | 159 | if (!strcmp(solver, "h48")) { |
| 160 | /* options are in the form "h;maxdepth" */ | 160 | /* options are in the form "h;maxdepth" */ |
| 161 | for (i = 0; options[i] != ';'; i++) ; | 161 | for (i = 0; options[i] != ';'; i++) ; |
| 162 | for (j = i; options[j]; j++) ; | 162 | for (j = i; options[j]; j++) ; |
| 163 | h = atoi(options); | 163 | h = atoi(options); |
| 164 | maxdepth = atoi(&options[i+1]); | 164 | if (h != 0) { |
| 165 | ret = gendata_h48(data, h, maxdepth); | 165 | LOG("Temporarily only h=0 is supported\n"); |
| 166 | } else if (!strcmp(solver, "H48stats")) { | 166 | ret = -1; |
| 167 | ret = gendata_cocsep(data, NULL, NULL); | 167 | } else { |
| 168 | maxdepth = atoi(&options[i+1]); | ||
| 169 | ret = gendata_h48h0k4(data, maxdepth); | ||
| 170 | } | ||
| 171 | } else if (!strcmp(solver, "h48stats")) { | ||
| 172 | ret = gendata_h48h0k4(data, 20); | ||
| 168 | } else { | 173 | } else { |
| 169 | LOG("gendata: implemented only for H48 solver\n"); | 174 | LOG("gendata: implemented only for h48 solver\n"); |
| 170 | ret = -1; | 175 | ret = -1; |
| 171 | } | 176 | } |
| 172 | 177 | ||
| @@ -224,13 +229,13 @@ nissy_solve( | |||
| 224 | } | 229 | } |
| 225 | 230 | ||
| 226 | /* TODO define and use solve_options_t */ | 231 | /* TODO define and use solve_options_t */ |
| 227 | if (!strcmp(solver, "H48")) { | 232 | if (!strcmp(solver, "h48")) { |
| 228 | h = atoi(options); /* TODO: better parsing */ | 233 | h = atoi(options); /* TODO: better parsing */ |
| 229 | ret = solve_h48( | 234 | ret = solve_h48( |
| 230 | c, minmoves, maxmoves, maxsolutions, | 235 | c, minmoves, maxmoves, maxsolutions, |
| 231 | (uint8_t)h, data, solutions); | 236 | (uint8_t)h, data, solutions); |
| 232 | ret = -1; | 237 | ret = -1; |
| 233 | } else if (!strcmp(solver, "H48stats")) { | 238 | } else if (!strcmp(solver, "h48stats")) { |
| 234 | ret = solve_h48stats(c, maxmoves, data, solutions); | 239 | ret = solve_h48stats(c, maxmoves, data, solutions); |
| 235 | } else if (!strcmp(solver, "simple")) { | 240 | } else if (!strcmp(solver, "simple")) { |
| 236 | ret = solve_simple( | 241 | ret = solve_simple( |
diff --git a/src/solve_h48.h b/src/solve_h48.h index c2c541d..5f99d15 100644 --- a/src/solve_h48.h +++ b/src/solve_h48.h | |||
| @@ -36,7 +36,6 @@ typedef struct { | |||
| 36 | 36 | ||
| 37 | typedef struct { | 37 | typedef struct { |
| 38 | uint8_t depth; | 38 | uint8_t depth; |
| 39 | uint8_t h; | ||
| 40 | uint32_t *cocsepdata; | 39 | uint32_t *cocsepdata; |
| 41 | uint32_t *buf32; | 40 | uint32_t *buf32; |
| 42 | uint64_t *selfsim; | 41 | uint64_t *selfsim; |
| @@ -63,6 +62,7 @@ typedef struct { | |||
| 63 | int8_t depth; | 62 | int8_t depth; |
| 64 | uint8_t moves[MAX_SOLUTION_LENGTH]; | 63 | uint8_t moves[MAX_SOLUTION_LENGTH]; |
| 65 | uint32_t *cocsepdata; | 64 | uint32_t *cocsepdata; |
| 65 | uint32_t *h48data; | ||
| 66 | char *s; | 66 | char *s; |
| 67 | } dfsarg_solveh48stats_t; | 67 | } dfsarg_solveh48stats_t; |
| 68 | 68 | ||
| @@ -72,8 +72,8 @@ _static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); | |||
| 72 | 72 | ||
| 73 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); | 73 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); |
| 74 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); | 74 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); |
| 75 | _static size_t gendata_h48(void *, uint8_t, uint8_t); | 75 | _static size_t gendata_h48h0k4(void *, uint8_t); |
| 76 | _static uint64_t gendata_esep_bfs(bfsarg_esep_t *); | 76 | _static uint64_t gendata_h48h0k4_bfs(bfsarg_esep_t *); |
| 77 | 77 | ||
| 78 | _static_inline bool get_visited(const uint8_t *, int64_t); | 78 | _static_inline bool get_visited(const uint8_t *, int64_t); |
| 79 | _static_inline void set_visited(uint8_t *, int64_t); | 79 | _static_inline void set_visited(uint8_t *, int64_t); |
| @@ -88,7 +88,7 @@ _static int64_t solve_h48_dfs(dfsarg_solveh48_t *); | |||
| 88 | _static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *); | 88 | _static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *); |
| 89 | 89 | ||
| 90 | _static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | 90 | _static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); |
| 91 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 13]); | 91 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); |
| 92 | 92 | ||
| 93 | _static_inline int64_t | 93 | _static_inline int64_t |
| 94 | coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) | 94 | coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) |
| @@ -119,12 +119,6 @@ coord_h48_edges(cube_t c, int64_t coclass, uint8_t t, uint8_t h) | |||
| 119 | edges = (esep << 11) + eo; | 119 | edges = (esep << 11) + eo; |
| 120 | 120 | ||
| 121 | return (coclass * H48_ESIZE(11) + edges) >> (11 - (int64_t)h); | 121 | return (coclass * H48_ESIZE(11) + edges) >> (11 - (int64_t)h); |
| 122 | |||
| 123 | /* | ||
| 124 | TODO: decide which alternative is better, if above or below | ||
| 125 | edges = (esep << (int64_t)h) + (eo >> (11 - (int64_t)h)); | ||
| 126 | return coclass * H48_ESIZE(h) + edges; | ||
| 127 | */ | ||
| 128 | } | 122 | } |
| 129 | 123 | ||
| 130 | /* | 124 | /* |
| @@ -133,7 +127,8 @@ the given value, because it works up to symmetry. This means that the | |||
| 133 | returned cube is a transformed cube of one that gives the correct value. | 127 | returned cube is a transformed cube of one that gives the correct value. |
| 134 | */ | 128 | */ |
| 135 | _static_inline cube_t | 129 | _static_inline cube_t |
| 136 | invcoord_h48(int64_t i, const cube_t *crep, uint8_t h) { | 130 | invcoord_h48(int64_t i, const cube_t *crep, uint8_t h) |
| 131 | { | ||
| 137 | cube_t ret; | 132 | cube_t ret; |
| 138 | int64_t hh, coclass, ee, esep, eo; | 133 | int64_t hh, coclass, ee, esep, eo; |
| 139 | 134 | ||
| @@ -274,9 +269,8 @@ TODO description | |||
| 274 | generating fixed table with h=0, k=4 | 269 | generating fixed table with h=0, k=4 |
| 275 | */ | 270 | */ |
| 276 | _static size_t | 271 | _static size_t |
| 277 | gendata_h48(void *buf, uint8_t h, uint8_t maxdepth) | 272 | gendata_h48h0k4(void *buf, uint8_t maxdepth) |
| 278 | { | 273 | { |
| 279 | const int k = 4; /* TODO: other cases? */ | ||
| 280 | uint32_t j, *buf32, *info, *cocsepdata; | 274 | uint32_t j, *buf32, *info, *cocsepdata; |
| 281 | bfsarg_esep_t arg; | 275 | bfsarg_esep_t arg; |
| 282 | int64_t sc, cc, tot, esep_max; | 276 | int64_t sc, cc, tot, esep_max; |
| @@ -290,19 +284,18 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth) | |||
| 290 | infosize = 88; | 284 | infosize = 88; |
| 291 | 285 | ||
| 292 | if (buf == NULL) | 286 | if (buf == NULL) |
| 293 | goto gendata_h48_return_size; | 287 | goto gendata_h48h0k4_return_size; |
| 294 | 288 | ||
| 295 | esep_max = (int64_t)ESEP_MAX(h); | 289 | esep_max = (int64_t)ESEP_MAX(0); |
| 296 | cocsepdata = (uint32_t *)buf; | 290 | cocsepdata = (uint32_t *)buf; |
| 297 | buf32 = cocsepdata + cocsepsize / 4; | 291 | buf32 = cocsepdata + cocsepsize / 4; |
| 298 | info = buf32 + (ESEP_TABLESIZE(h, k) / sizeof(uint32_t)); | 292 | info = buf32 + (ESEP_TABLESIZE(0, 4) / sizeof(uint32_t)); |
| 299 | memset(buf32, 0xFF, ESEP_TABLESIZE(h, k)); | 293 | memset(buf32, 0xFF, ESEP_TABLESIZE(0, 4)); |
| 300 | 294 | ||
| 301 | sc = coord_h48(solved, cocsepdata, h); | 295 | sc = coord_h48(solved, cocsepdata, 0); |
| 302 | set_esep_pval(buf32, sc, 0); | 296 | set_esep_pval(buf32, sc, 0); |
| 303 | info[1] = 1; | 297 | info[1] = 1; |
| 304 | arg = (bfsarg_esep_t) { | 298 | arg = (bfsarg_esep_t) { |
| 305 | .h = h, | ||
| 306 | .cocsepdata = cocsepdata, | 299 | .cocsepdata = cocsepdata, |
| 307 | .buf32 = buf32, | 300 | .buf32 = buf32, |
| 308 | .crep = crep, | 301 | .crep = crep, |
| @@ -314,7 +307,7 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth) | |||
| 314 | arg.depth++ | 307 | arg.depth++ |
| 315 | ) { | 308 | ) { |
| 316 | LOG("esep: generating depth %" PRIu8 "\n", arg.depth); | 309 | LOG("esep: generating depth %" PRIu8 "\n", arg.depth); |
| 317 | cc = gendata_esep_bfs(&arg); | 310 | cc = gendata_h48h0k4_bfs(&arg); |
| 318 | tot += cc; | 311 | tot += cc; |
| 319 | info[arg.depth+1] = cc; | 312 | info[arg.depth+1] = cc; |
| 320 | LOG("found %" PRIu64 "\n", cc); | 313 | LOG("found %" PRIu64 "\n", cc); |
| @@ -328,25 +321,25 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth) | |||
| 328 | for (j = 0; j <= info[0]; j++) | 321 | for (j = 0; j <= info[0]; j++) |
| 329 | LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+1]); | 322 | LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+1]); |
| 330 | 323 | ||
| 331 | gendata_h48_return_size: | 324 | gendata_h48h0k4_return_size: |
| 332 | return cocsepsize + ESEP_TABLESIZE(h, k) + infosize; | 325 | return cocsepsize + ESEP_TABLESIZE(0, 4) + infosize; |
| 333 | } | 326 | } |
| 334 | 327 | ||
| 335 | _static uint64_t | 328 | _static uint64_t |
| 336 | gendata_esep_bfs(bfsarg_esep_t *arg) | 329 | gendata_h48h0k4_bfs(bfsarg_esep_t *arg) |
| 337 | { | 330 | { |
| 338 | uint8_t c, m, x; | 331 | uint8_t c, m, x; |
| 339 | uint32_t cc; | 332 | uint32_t cc; |
| 340 | int64_t i, j, k, t, cocsep_coord, sim, esep_max; | 333 | int64_t i, j, k, t, cocsep_coord, sim, esep_max; |
| 341 | cube_t cube, moved, transd; | 334 | cube_t cube, moved, transd; |
| 342 | 335 | ||
| 343 | esep_max = (uint64_t)ESEP_MAX(arg->h); | 336 | esep_max = (uint64_t)ESEP_MAX(0); |
| 344 | 337 | ||
| 345 | for (i = 0, cc = 0; i < esep_max; i++) { | 338 | for (i = 0, cc = 0; i < esep_max; i++) { |
| 346 | c = get_esep_pval(arg->buf32, i); | 339 | c = get_esep_pval(arg->buf32, i); |
| 347 | if (c != arg->depth - 1) | 340 | if (c != arg->depth - 1) |
| 348 | continue; | 341 | continue; |
| 349 | cube = invcoord_h48(i, arg->crep, arg->h); | 342 | cube = invcoord_h48(i, arg->crep, 0); |
| 350 | for (m = 0; m < 18; m++) { | 343 | for (m = 0; m < 18; m++) { |
| 351 | /* | 344 | /* |
| 352 | * TODO: here we can optimize by computing at first | 345 | * TODO: here we can optimize by computing at first |
| @@ -354,19 +347,19 @@ gendata_esep_bfs(bfsarg_esep_t *arg) | |||
| 354 | * the edge parts for each transformation. | 347 | * the edge parts for each transformation. |
| 355 | */ | 348 | */ |
| 356 | moved = move(cube, m); | 349 | moved = move(cube, m); |
| 357 | j = coord_h48(moved, arg->cocsepdata, arg->h); | 350 | j = coord_h48(moved, arg->cocsepdata, 0); |
| 358 | x = get_esep_pval(arg->buf32, j); | 351 | x = get_esep_pval(arg->buf32, j); |
| 359 | if (x <= arg->depth) | 352 | if (x <= arg->depth) |
| 360 | continue; | 353 | continue; |
| 361 | set_esep_pval(arg->buf32, j, arg->depth); | 354 | set_esep_pval(arg->buf32, j, arg->depth); |
| 362 | cc += x != arg->depth; | 355 | cc += x != arg->depth; |
| 363 | cocsep_coord = j / H48_ESIZE(arg->h); | 356 | cocsep_coord = j / H48_ESIZE(0); |
| 364 | sim = arg->selfsim[cocsep_coord] >> 1; | 357 | sim = arg->selfsim[cocsep_coord] >> 1; |
| 365 | for (t = 1; t < 48 && sim; t++, sim >>= 1) { | 358 | for (t = 1; t < 48 && sim; t++, sim >>= 1) { |
| 366 | if (!(sim & 1)) | 359 | if (!(sim & 1)) |
| 367 | continue; | 360 | continue; |
| 368 | transd = transform(moved, t); | 361 | transd = transform(moved, t); |
| 369 | k = coord_h48(transd, arg->cocsepdata, arg->h); | 362 | k = coord_h48(transd, arg->cocsepdata, 0); |
| 370 | x = get_esep_pval(arg->buf32, k); | 363 | x = get_esep_pval(arg->buf32, k); |
| 371 | if (x <= arg->depth) | 364 | if (x <= arg->depth) |
| 372 | continue; | 365 | continue; |
| @@ -539,46 +532,45 @@ solve_h48( | |||
| 539 | solve_h48_dfs(&arg); | 532 | solve_h48_dfs(&arg); |
| 540 | } | 533 | } |
| 541 | 534 | ||
| 542 | /* | ||
| 543 | for (int64_t i = 0; i < 4; i++) | ||
| 544 | LOG("Data for coord = %" PRId64 ": %" PRIu8 "\n", | ||
| 545 | i, get_esep_pval(arg.h48data, i)); | ||
| 546 | */ | ||
| 547 | return nsols; | 535 | return nsols; |
| 548 | } | 536 | } |
| 549 | 537 | ||
| 550 | /* | 538 | /* |
| 551 | The h48stats solver computes how many moves it takes to solve to each of | 539 | The h48stats solver computes how many moves it takes to solve to |
| 552 | the 13 h48 coordinates: the corner-only coordinate, and 12 cocsep+esep | 540 | each of the 12 h48 coordinates, one for each value of h from 0 to 11. |
| 553 | coordinates with h from 0 to 11. The solutions array is filled with | 541 | The solutions array is filled with the length of the solutions. The |
| 554 | the length of the solutions: solutions[0] contains the value for the | 542 | solution array is therefore not a printable string. |
| 555 | corner-only coordinate, and for i>0 solutions[i] contains the value for | ||
| 556 | the cocsep+esep coordinate with h=i-1. The solution array is therefore | ||
| 557 | not a printable string. | ||
| 558 | */ | 543 | */ |
| 559 | _static int64_t | 544 | _static int64_t |
| 560 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) | 545 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) |
| 561 | { | 546 | { |
| 547 | const int64_t limit = 11; | ||
| 548 | |||
| 562 | int8_t bound, u; | 549 | int8_t bound, u; |
| 563 | uint8_t m; | 550 | uint8_t m; |
| 564 | uint32_t d; | 551 | uint32_t d; |
| 565 | int64_t coord, h; | 552 | int64_t coord, h; |
| 566 | dfsarg_solveh48stats_t nextarg; | 553 | dfsarg_solveh48stats_t nextarg; |
| 567 | 554 | ||
| 555 | /* Check cocsep lower bound (corners only) */ | ||
| 568 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); | 556 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); |
| 569 | if (bound + arg->nmoves > arg->depth) | 557 | if (bound + arg->nmoves > arg->depth) |
| 570 | return 0; | 558 | return 0; |
| 571 | 559 | ||
| 572 | u = COCLASS(d) == 0 && arg->s[0] == 99; | 560 | /* Check h48 lower bound for h=0 (esep, but no eo) */ |
| 573 | arg->s[0] = u * arg->nmoves + (1-u) * arg->s[0]; | 561 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); |
| 562 | bound = get_esep_pval(arg->h48data, coord); | ||
| 563 | if (bound + arg->nmoves > arg->depth) | ||
| 564 | return 0; | ||
| 574 | 565 | ||
| 566 | /* Update all other values, if solved */ | ||
| 575 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); | 567 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); |
| 576 | for (h = 0; h <= 11; h++) { | 568 | for (h = 0; h <= limit; h++) { |
| 577 | u = coord >> (11-h) == 0 && arg->s[h+1] == 99; | 569 | u = coord >> (11-h) == 0 && arg->s[h] == 99; |
| 578 | arg->s[h+1] = u * arg->nmoves + (1-u) * arg->s[h+1]; | 570 | arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h]; |
| 579 | } | 571 | } |
| 580 | 572 | ||
| 581 | if (arg->s[12] != 99) | 573 | if (arg->s[limit] != 99) |
| 582 | return 0; | 574 | return 0; |
| 583 | 575 | ||
| 584 | nextarg = *arg; | 576 | nextarg = *arg; |
| @@ -603,23 +595,27 @@ solve_h48stats( | |||
| 603 | cube_t cube, | 595 | cube_t cube, |
| 604 | int8_t maxmoves, | 596 | int8_t maxmoves, |
| 605 | const void *data, | 597 | const void *data, |
| 606 | char solutions[static 13] | 598 | char solutions[static 12] |
| 607 | ) | 599 | ) |
| 608 | { | 600 | { |
| 609 | int i; | 601 | int i; |
| 602 | size_t cocsepsize; | ||
| 610 | dfsarg_solveh48stats_t arg; | 603 | dfsarg_solveh48stats_t arg; |
| 611 | 604 | ||
| 605 | cocsepsize = gendata_cocsep(NULL, NULL, NULL); | ||
| 606 | |||
| 612 | arg = (dfsarg_solveh48stats_t) { | 607 | arg = (dfsarg_solveh48stats_t) { |
| 613 | .cube = cube, | 608 | .cube = cube, |
| 614 | .cocsepdata = (uint32_t *)data, | 609 | .cocsepdata = (uint32_t *)data, |
| 610 | .h48data = ((uint32_t *)data) + (cocsepsize/4), | ||
| 615 | .s = solutions | 611 | .s = solutions |
| 616 | }; | 612 | }; |
| 617 | 613 | ||
| 618 | for (i = 0; i < 13; i++) | 614 | for (i = 0; i < 12; i++) |
| 619 | solutions[i] = (char)99; | 615 | solutions[i] = (char)99; |
| 620 | 616 | ||
| 621 | for (arg.depth = 0; | 617 | for (arg.depth = 0; |
| 622 | arg.depth <= maxmoves && solutions[12] == 99; | 618 | arg.depth <= maxmoves && solutions[11] == 99; |
| 623 | arg.depth++) | 619 | arg.depth++) |
| 624 | { | 620 | { |
| 625 | arg.nmoves = 0; | 621 | arg.nmoves = 0; |
diff --git a/test/103_gendata_h48/00_h_0.in b/test/103_gendata_h48/00_h_0.in deleted file mode 100644 index 573541a..0000000 --- a/test/103_gendata_h48/00_h_0.in +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | 0 | ||
diff --git a/test/103_gendata_h48/01_h_1.in b/test/103_gendata_h48/01_h_1.in deleted file mode 100644 index d00491f..0000000 --- a/test/103_gendata_h48/01_h_1.in +++ /dev/null | |||
| @@ -1 +0,0 @@ | |||
| 1 | 1 | ||
diff --git a/test/103_gendata_h48/01_h_1.out b/test/103_gendata_h48/01_h_1.out deleted file mode 100644 index bd0931c..0000000 --- a/test/103_gendata_h48/01_h_1.out +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | 118687330 | ||
| 2 | |||
| 3 | cocsepdata: | ||
| 4 | Classes: 3393 | ||
| 5 | Max value: 9 | ||
| 6 | 0: 1 | ||
| 7 | 1: 6 | ||
| 8 | 2: 63 | ||
| 9 | 3: 468 | ||
| 10 | 4: 3068 | ||
| 11 | 5: 15438 | ||
| 12 | 6: 53814 | ||
| 13 | 7: 71352 | ||
| 14 | 8: 8784 | ||
| 15 | 9: 96 | ||
| 16 | |||
| 17 | h48: | ||
| 18 | 0: 1 | ||
| 19 | 1: 1 | ||
| 20 | 2: 4 | ||
| 21 | 3: 34 | ||
| 22 | 4: 375 | ||
| 23 | 5: 4078 | ||
diff --git a/test/103_gendata_h48_h0/00_h_0.in b/test/103_gendata_h48_h0/00_h_0.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/103_gendata_h48_h0/00_h_0.in | |||
diff --git a/test/103_gendata_h48/00_h_0.out b/test/103_gendata_h48_h0/00_h_0.out index cc5cf9b..cc5cf9b 100644 --- a/test/103_gendata_h48/00_h_0.out +++ b/test/103_gendata_h48_h0/00_h_0.out | |||
diff --git a/test/103_gendata_h48/gendata_h48_tests.c b/test/103_gendata_h48_h0/gendata_h48_tests.c index 666f9f6..ed17915 100644 --- a/test/103_gendata_h48/gendata_h48_tests.c +++ b/test/103_gendata_h48_h0/gendata_h48_tests.c | |||
| @@ -2,21 +2,20 @@ | |||
| 2 | 2 | ||
| 3 | #define MAXDEPTH 5 | 3 | #define MAXDEPTH 5 |
| 4 | #define COCSEPSIZE 1119792 | 4 | #define COCSEPSIZE 1119792 |
| 5 | #define ETABLESIZE(h) (((3393 * 495 * 70) >> 1) << (size_t)(h)) | 5 | #define ETABLESIZE ((3393 * 495 * 70) >> 1) |
| 6 | 6 | ||
| 7 | size_t gendata_h48(void *, uint8_t, uint8_t); | 7 | size_t gendata_h48h0k4(void *, uint8_t); |
| 8 | 8 | ||
| 9 | void run(void) { | 9 | void run(void) { |
| 10 | char str[STRLENMAX]; | 10 | char str[STRLENMAX]; |
| 11 | uint8_t h, i; | 11 | uint8_t i; |
| 12 | uint32_t *buf, *h48info; | 12 | uint32_t *buf, *h48info; |
| 13 | size_t result; | 13 | size_t result; |
| 14 | 14 | ||
| 15 | fgets(str, STRLENMAX, stdin); | 15 | fgets(str, STRLENMAX, stdin); |
| 16 | h = atoi(str); | 16 | buf = (uint32_t *)malloc(sizeof(uint32_t) * 60000000); |
| 17 | buf = (uint32_t *)malloc(sizeof(uint32_t) * (60000000 << h)); | 17 | result = gendata_h48h0k4(buf, MAXDEPTH); |
| 18 | result = gendata_h48(buf, h, MAXDEPTH); | 18 | h48info = buf + (ETABLESIZE + COCSEPSIZE) / 4; |
| 19 | h48info = buf + (ETABLESIZE(h) + COCSEPSIZE) / 4; | ||
| 20 | 19 | ||
| 21 | printf("%zu\n\n", result); | 20 | printf("%zu\n\n", result); |
| 22 | 21 | ||
diff --git a/tools/run_tool.sh b/tools/run_tool.sh index 21b6ce9..14d0e45 100755 --- a/tools/run_tool.sh +++ b/tools/run_tool.sh | |||
| @@ -6,21 +6,29 @@ if [ -z "$TOOL" ]; then | |||
| 6 | fi | 6 | fi |
| 7 | 7 | ||
| 8 | CC="cc -std=c99 -pedantic -Wall -Wextra \ | 8 | CC="cc -std=c99 -pedantic -Wall -Wextra \ |
| 9 | -Wno-unused-parameter -Wno-unused-function -O3 -D$CUBETYPE \ | 9 | -Wno-unused-parameter -Wno-unused-function -D$CUBETYPE \ |
| 10 | -D_POSIX_C_SOURCE=199309L" | 10 | -D_POSIX_C_SOURCE=199309L" |
| 11 | 11 | ||
| 12 | if [ -n "$DEBUG" ]; then | ||
| 13 | CC="$CC -fsanitize=address -g3" | ||
| 14 | CUBEOBJ="debugcube.o" | ||
| 15 | else | ||
| 16 | CC="$CC -O3" | ||
| 17 | CUBEOBJ="cube.o" | ||
| 18 | fi | ||
| 19 | |||
| 12 | [ "$CUBETYPE" = "CUBE_AVX2" ] && CC="$CC -mavx2" | 20 | [ "$CUBETYPE" = "CUBE_AVX2" ] && CC="$CC -mavx2" |
| 13 | 21 | ||
| 14 | BIN="tools/run" | 22 | BIN="tools/run" |
| 15 | CUBEOBJ="cube.o" | ||
| 16 | d="$(date +'%Y-%m-%d-%H-%M-%S')" | 23 | d="$(date +'%Y-%m-%d-%H-%M-%S')" |
| 17 | 24 | ||
| 18 | for t in tools/*; do | 25 | for t in tools/*; do |
| 19 | if [ ! -d "$t" ] || [ -z "$(echo "$t" | grep "$TOOL")" ]; then | 26 | if [ ! -d "$t" ] || [ -z "$(echo "$t" | grep "$TOOL")" ]; then |
| 20 | continue | 27 | continue |
| 21 | fi | 28 | fi |
| 29 | toolname="$(basename "$t" .c)" | ||
| 22 | $CC -o $BIN $t/*.c $CUBEOBJ || exit 1; | 30 | $CC -o $BIN $t/*.c $CUBEOBJ || exit 1; |
| 23 | $BIN | 31 | $BIN | tee "tools/results/$toolname-$d.txt" |
| 24 | break | 32 | break |
| 25 | done | 33 | done |
| 26 | 34 | ||
diff --git a/tools/stats_tables_h48/stats_tables_h48.c b/tools/stats_tables_h48/stats_tables_h48.c index b349f63..33272c1 100644 --- a/tools/stats_tables_h48/stats_tables_h48.c +++ b/tools/stats_tables_h48/stats_tables_h48.c | |||
| @@ -1,10 +1,13 @@ | |||
| 1 | #include <stdarg.h> | ||
| 1 | #include <time.h> | 2 | #include <time.h> |
| 2 | #include "../timerun.h" | 3 | #include "../timerun.h" |
| 3 | #include "../../src/cube.h" | 4 | #include "../../src/cube.h" |
| 4 | 5 | ||
| 5 | #define MAXMOVES 20 | 6 | #define MAXMOVES 20 |
| 6 | #define NCUBES 1000 | 7 | #define NCUBES 10000 |
| 8 | #define LOG_EVERY (NCUBES / 20) | ||
| 7 | 9 | ||
| 10 | const char *filename = "tables/h48h0k4"; | ||
| 8 | char *buf; | 11 | char *buf; |
| 9 | 12 | ||
| 10 | uint64_t rand64(void) { | 13 | uint64_t rand64(void) { |
| @@ -16,22 +19,18 @@ uint64_t rand64(void) { | |||
| 16 | return ret; | 19 | return ret; |
| 17 | } | 20 | } |
| 18 | 21 | ||
| 19 | void output(int64_t v[13][100]) { | 22 | void log_stderr(const char *str, ...) { |
| 20 | /* TODO: write to file and output only cocsepdata table stats */ | 23 | va_list args; |
| 24 | |||
| 25 | va_start(args, str); | ||
| 26 | vfprintf(stderr, str, args); | ||
| 27 | va_end(args); | ||
| 21 | } | 28 | } |
| 22 | 29 | ||
| 23 | void run(void) { | 30 | void run(void) { |
| 24 | uint32_t *h48info; | 31 | int i, j, k; |
| 25 | int i, j; | 32 | char sols[12], cube[22]; |
| 26 | char sols[13], cube[22]; | 33 | int64_t ep, eo, cp, co, v[12][100] = {0}; |
| 27 | int64_t s, ep, eo, cp, co, v[13][100] = {0}; | ||
| 28 | |||
| 29 | s = nissy_gendata("H48stats", "", buf); | ||
| 30 | |||
| 31 | if (s == -1) { | ||
| 32 | printf("Error generating table\n"); | ||
| 33 | return; | ||
| 34 | } | ||
| 35 | 34 | ||
| 36 | for (i = 0; i < NCUBES; i++) { | 35 | for (i = 0; i < NCUBES; i++) { |
| 37 | ep = rand64(); | 36 | ep = rand64(); |
| @@ -39,13 +38,53 @@ void run(void) { | |||
| 39 | cp = rand64(); | 38 | cp = rand64(); |
| 40 | co = rand64(); | 39 | co = rand64(); |
| 41 | nissy_getcube(ep, eo, cp, co, "fix", cube); | 40 | nissy_getcube(ep, eo, cp, co, "fix", cube); |
| 42 | nissy_solve(cube, "H48stats", | 41 | nissy_solve(cube, "h48stats", "", "", |
| 43 | "", "", "", 0, MAXMOVES, 1, -1, buf, sols); | 42 | 0, MAXMOVES, 1, -1, buf, sols); |
| 44 | for (j = 0; j < 13; j++) | 43 | for (j = 0; j < 12; j++) |
| 45 | v[j][(int)sols[j]]++; | 44 | v[j][(int)sols[j]]++; |
| 45 | if ((i+1) % LOG_EVERY == 0) | ||
| 46 | fprintf(stderr, "%d cubes solved...\n", i+1); | ||
| 46 | } | 47 | } |
| 47 | 48 | ||
| 48 | output(v); | 49 | for (j = 0; j < 12; j++) { |
| 50 | printf("Data for h=%d\n", j); | ||
| 51 | for (k = 0; k <= 16; k++) | ||
| 52 | printf("%d\t%" PRId64 "\n", k, v[j][k]); | ||
| 53 | printf("\n"); | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | int getdata(int64_t size) { | ||
| 58 | int64_t s; | ||
| 59 | FILE *f; | ||
| 60 | |||
| 61 | buf = malloc(size); | ||
| 62 | |||
| 63 | if ((f = fopen(filename, "rb")) == NULL) { | ||
| 64 | fprintf(stderr, "Table file not found, generating them." | ||
| 65 | " This can take a while.\n"); | ||
| 66 | s = nissy_gendata("h48stats", "", buf); | ||
| 67 | if (s != size) { | ||
| 68 | fprintf(stderr, "Error generating table"); | ||
| 69 | if (s != -1) | ||
| 70 | fprintf(stderr, " (got %" PRId64 " bytes)", s); | ||
| 71 | fprintf(stderr, "\n"); | ||
| 72 | return 1; | ||
| 73 | } | ||
| 74 | if ((f = fopen(filename, "wb")) == NULL) { | ||
| 75 | fprintf(stderr, "Could not write tables to file %s" | ||
| 76 | ", will be regenerated next time.\n", filename); | ||
| 77 | } else { | ||
| 78 | fwrite(buf, size, 1, f); | ||
| 79 | fclose(f); | ||
| 80 | } | ||
| 81 | } else { | ||
| 82 | fprintf(stderr, "Reading tables from file %s\n", filename); | ||
| 83 | fread(buf, size, 1, f); | ||
| 84 | fclose(f); | ||
| 85 | } | ||
| 86 | |||
| 87 | return 0; | ||
| 49 | } | 88 | } |
| 50 | 89 | ||
| 51 | int main() { | 90 | int main() { |
| @@ -53,17 +92,21 @@ int main() { | |||
| 53 | 92 | ||
| 54 | srand(time(NULL)); | 93 | srand(time(NULL)); |
| 55 | 94 | ||
| 56 | size = nissy_datasize("H48", OPTIONS); | 95 | nissy_setlogger(log_stderr); |
| 96 | size = nissy_datasize("h48stats", ""); | ||
| 57 | if (size == -1) { | 97 | if (size == -1) { |
| 58 | printf("h48 stats: error in datasize\n"); | 98 | printf("h48 stats: error in datasize\n"); |
| 59 | return 1; | 99 | return 1; |
| 60 | } | 100 | } |
| 61 | 101 | ||
| 62 | buf = malloc(size); | 102 | if (getdata(size) != 0) { |
| 103 | printf("Error getting table, stopping\n"); | ||
| 104 | free(buf); | ||
| 105 | return 1; | ||
| 106 | } | ||
| 63 | 107 | ||
| 64 | timerun(run, "h48 table stats"); | 108 | timerun(run, "h48 table stats"); |
| 65 | 109 | ||
| 66 | free(buf); | 110 | free(buf); |
| 67 | |||
| 68 | return 0; | 111 | return 0; |
| 69 | } | 112 | } |
