diff options
| -rw-r--r-- | TODO.md | 17 | ||||
| -rwxr-xr-x | nissy | bin | 192888 -> 320064 bytes | |||
| -rw-r--r-- | src/alg.c | 180 | ||||
| -rw-r--r-- | src/alg.h | 15 | ||||
| -rw-r--r-- | src/commands.c | 2 | ||||
| -rw-r--r-- | src/coord.c | 86 | ||||
| -rw-r--r-- | src/coord.h | 2 | ||||
| -rw-r--r-- | src/cubetypes.h | 23 | ||||
| -rw-r--r-- | src/moves.c | 51 | ||||
| -rw-r--r-- | src/moves.h | 2 | ||||
| -rw-r--r-- | src/pruning.c | 95 | ||||
| -rw-r--r-- | src/pruning.h | 1 | ||||
| -rw-r--r-- | src/solve.c | 80 | ||||
| -rw-r--r-- | src/steps.c | 246 | ||||
| -rw-r--r-- | src/symcoord.c | 85 | ||||
| -rw-r--r-- | src/symcoord.h | 2 |
16 files changed, 555 insertions, 332 deletions
| @@ -14,13 +14,11 @@ It's more of a personal reminder than anything else. | |||
| 14 | * invert an alg | 14 | * invert an alg |
| 15 | 15 | ||
| 16 | ### More steps for `solve` | 16 | ### More steps for `solve` |
| 17 | * QTM optimal solving | 17 | * QTM optimal solving (important: fix possible_next, which works only for HTM now) |
| 18 | * Block-building steps (cross, roux blocks, ...) | 18 | * Block-building steps (cross, roux blocks, ...) |
| 19 | * Other common steps (LSE, ...) | 19 | * Other common steps (LSE, ...) |
| 20 | 20 | ||
| 21 | ### Improvements to currently implemented commands | 21 | ### Improvements to currently implemented commands |
| 22 | * batch mode: add separator / info on which command it is executing | ||
| 23 | (also change man page for this) | ||
| 24 | * solve should re-orient first if needed and not just give up if centers are off | 22 | * solve should re-orient first if needed and not just give up if centers are off |
| 25 | * solve should try up to a small bound without loading the large pruning table | 23 | * solve should try up to a small bound without loading the large pruning table |
| 26 | * drfin for HTR scrambles should try all 3 axis and pick the best solutions; | 24 | * drfin for HTR scrambles should try all 3 axis and pick the best solutions; |
| @@ -42,7 +40,12 @@ It's more of a personal reminder than anything else. | |||
| 42 | 40 | ||
| 43 | ## Technical stuff | 41 | ## Technical stuff |
| 44 | 42 | ||
| 45 | ## Performance | 43 | ### Memory management |
| 44 | * Check if memory is enough for loading pruning tables; if not, abort | ||
| 45 | * For optimal solver: choose largest that fits in memory between | ||
| 46 | khuge, shug6 and light | ||
| 47 | |||
| 48 | ### Performance | ||
| 46 | * solve (allow_next): filter out based on base_move; only check once for each | 49 | * solve (allow_next): filter out based on base_move; only check once for each |
| 47 | triple of moves; how to deal with different movesets? | 50 | triple of moves; how to deal with different movesets? |
| 48 | * try htr corners + edges in slice but not oriented (300Mb table); | 51 | * try htr corners + edges in slice but not oriented (300Mb table); |
| @@ -51,12 +54,8 @@ It's more of a personal reminder than anything else. | |||
| 51 | (like in light optimal solver) | 54 | (like in light optimal solver) |
| 52 | * Another idea: DR + cornershtr (5Gb table); same as above, de Bondt's trick | 55 | * Another idea: DR + cornershtr (5Gb table); same as above, de Bondt's trick |
| 53 | does not work but I can use half-turn trick | 56 | does not work but I can use half-turn trick |
| 54 | * On the contrary: DR + separate UD corners allow dB's trick, but no ht-trick | ||
| 55 | 57 | ||
| 56 | ## Coordinates, symmetries, pruning tables | 58 | ### Coordinates, symmetries, pruning tables |
| 57 | * Cleanup symcoord.c: some coordinates and symdata are never actually used; | ||
| 58 | remove also sd_eofbepos and just use sd_coud for khuge (this changes the | ||
| 59 | coordinate so the whole table must be generated again!) or viceversa | ||
| 60 | * Use pruning values mod 4 instead of mod 16 (or maybe not, I like the | 59 | * Use pruning values mod 4 instead of mod 16 (or maybe not, I like the |
| 61 | current system) | 60 | current system) |
| 62 | 61 | ||
| Binary files differ | |||
| @@ -2,27 +2,76 @@ | |||
| 2 | 2 | ||
| 3 | /* Local functions ***********************************************************/ | 3 | /* Local functions ***********************************************************/ |
| 4 | 4 | ||
| 5 | static bool allowed_HTM(Move m); | ||
| 6 | static bool allowed_URF(Move m); | ||
| 7 | static bool allowed_eofb(Move m); | ||
| 8 | static bool allowed_drud(Move m); | ||
| 9 | static bool allowed_htr(Move m); | ||
| 10 | static bool allowed_next_HTM(Move l2, Move l1, Move m); | ||
| 11 | static int axis(Move m); | ||
| 12 | |||
| 5 | static void free_alglistnode(AlgListNode *aln); | 13 | static void free_alglistnode(AlgListNode *aln); |
| 6 | static void realloc_alg(Alg *alg, int n); | 14 | static void realloc_alg(Alg *alg, int n); |
| 7 | 15 | ||
| 8 | /* Movesets ******************************************************************/ | 16 | /* Movesets ******************************************************************/ |
| 9 | 17 | ||
| 10 | bool | 18 | Moveset |
| 11 | moveset_HTM(Move m) | 19 | moveset_HTM = { |
| 20 | .allowed = allowed_HTM, | ||
| 21 | .allowed_next = allowed_next_HTM, | ||
| 22 | }; | ||
| 23 | |||
| 24 | Moveset | ||
| 25 | moveset_URF = { | ||
| 26 | .allowed = allowed_URF, | ||
| 27 | .allowed_next = allowed_next_HTM, | ||
| 28 | }; | ||
| 29 | |||
| 30 | Moveset | ||
| 31 | moveset_eofb = { | ||
| 32 | .allowed = allowed_eofb, | ||
| 33 | .allowed_next = allowed_next_HTM, | ||
| 34 | }; | ||
| 35 | |||
| 36 | Moveset | ||
| 37 | moveset_drud = { | ||
| 38 | .allowed = allowed_drud, | ||
| 39 | .allowed_next = allowed_next_HTM, | ||
| 40 | }; | ||
| 41 | |||
| 42 | Moveset | ||
| 43 | moveset_htr = { | ||
| 44 | .allowed = allowed_htr, | ||
| 45 | .allowed_next = allowed_next_HTM, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static int nmoveset = 5; | ||
| 49 | static Moveset * all_ms[] = { | ||
| 50 | &moveset_HTM, | ||
| 51 | &moveset_URF, | ||
| 52 | &moveset_eofb, | ||
| 53 | &moveset_drud, | ||
| 54 | &moveset_htr, | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* Functions *****************************************************************/ | ||
| 58 | |||
| 59 | static bool | ||
| 60 | allowed_HTM(Move m) | ||
| 12 | { | 61 | { |
| 13 | return m >= U && m <= B3; | 62 | return m >= U && m <= B3; |
| 14 | } | 63 | } |
| 15 | 64 | ||
| 16 | bool | 65 | static bool |
| 17 | moveset_URF(Move m) | 66 | allowed_URF(Move m) |
| 18 | { | 67 | { |
| 19 | Move b = base_move(m); | 68 | Move b = base_move(m); |
| 20 | 69 | ||
| 21 | return b == U || b == R || b == F; | 70 | return b == U || b == R || b == F; |
| 22 | } | 71 | } |
| 23 | 72 | ||
| 24 | bool | 73 | static bool |
| 25 | moveset_eofb(Move m) | 74 | allowed_eofb(Move m) |
| 26 | { | 75 | { |
| 27 | Move b = base_move(m); | 76 | Move b = base_move(m); |
| 28 | 77 | ||
| @@ -30,8 +79,8 @@ moveset_eofb(Move m) | |||
| 30 | ((b == F || b == B) && m == b+1); | 79 | ((b == F || b == B) && m == b+1); |
| 31 | } | 80 | } |
| 32 | 81 | ||
| 33 | bool | 82 | static bool |
| 34 | moveset_drud(Move m) | 83 | allowed_drud(Move m) |
| 35 | { | 84 | { |
| 36 | Move b = base_move(m); | 85 | Move b = base_move(m); |
| 37 | 86 | ||
| @@ -39,16 +88,65 @@ moveset_drud(Move m) | |||
| 39 | ((b == R || b == L || b == F || b == B) && m == b + 1); | 88 | ((b == R || b == L || b == F || b == B) && m == b + 1); |
| 40 | } | 89 | } |
| 41 | 90 | ||
| 42 | bool | 91 | static bool |
| 43 | moveset_htr(Move m) | 92 | allowed_htr(Move m) |
| 44 | { | 93 | { |
| 45 | Move b = base_move(m); | 94 | Move b = base_move(m); |
| 46 | 95 | ||
| 47 | return moveset_HTM(m) && m == b + 1; | 96 | return moveset_HTM.allowed(m) && m == b + 1; |
| 48 | } | 97 | } |
| 49 | 98 | ||
| 99 | static bool | ||
| 100 | allowed_next_HTM(Move l2, Move l1, Move m) | ||
| 101 | { | ||
| 102 | bool p, q; | ||
| 50 | 103 | ||
| 51 | /* Functions *****************************************************************/ | 104 | p = l1 != NULLMOVE && base_move(l1) == base_move(m); |
| 105 | q = l2 != NULLMOVE && base_move(l2) == base_move(m); | ||
| 106 | |||
| 107 | return !(p || (commute(l1, l2) && q)); | ||
| 108 | } | ||
| 109 | |||
| 110 | static int | ||
| 111 | axis(Move m) | ||
| 112 | { | ||
| 113 | Move i; | ||
| 114 | |||
| 115 | static bool initialized = false; | ||
| 116 | static int aux[NMOVES]; | ||
| 117 | |||
| 118 | if (!initialized) { | ||
| 119 | for (i = 0; i < NMOVES; i++) { | ||
| 120 | if (i == NULLMOVE) | ||
| 121 | aux[i] = 0; | ||
| 122 | |||
| 123 | if (i >= U && i <= B3) | ||
| 124 | aux[i] = (i-1)/6 + 1; | ||
| 125 | |||
| 126 | if (i >= Uw && i <= Bw3) | ||
| 127 | aux[i] = (i-1)/6 - 2; | ||
| 128 | |||
| 129 | if (base_move(i) == E || base_move(i) == y) | ||
| 130 | aux[i] = 1; | ||
| 131 | |||
| 132 | if (base_move(i) == M || base_move(i) == x) | ||
| 133 | aux[i] = 2; | ||
| 134 | |||
| 135 | if (base_move(i) == S || base_move(i) == z) | ||
| 136 | aux[i] = 3; | ||
| 137 | } | ||
| 138 | |||
| 139 | initialized = true; | ||
| 140 | } | ||
| 141 | |||
| 142 | return aux[m]; | ||
| 143 | } | ||
| 144 | |||
| 145 | bool | ||
| 146 | commute(Move m1, Move m2) | ||
| 147 | { | ||
| 148 | return axis(m1) == axis(m2); | ||
| 149 | } | ||
| 52 | 150 | ||
| 53 | void | 151 | void |
| 54 | append_alg(AlgList *l, Alg *alg) | 152 | append_alg(AlgList *l, Alg *alg) |
| @@ -171,33 +269,6 @@ move_string(Move m) | |||
| 171 | return move_string_aux[m]; | 269 | return move_string_aux[m]; |
| 172 | } | 270 | } |
| 173 | 271 | ||
| 174 | void | ||
| 175 | movelist_to_position(Move *movelist, int *position) | ||
| 176 | { | ||
| 177 | Move m; | ||
| 178 | |||
| 179 | for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++) | ||
| 180 | position[movelist[m]] = m; | ||
| 181 | } | ||
| 182 | |||
| 183 | void | ||
| 184 | moveset_to_list(Moveset ms, Move *r) | ||
| 185 | { | ||
| 186 | int n = 0; | ||
| 187 | Move i; | ||
| 188 | |||
| 189 | if (ms == NULL) { | ||
| 190 | fprintf(stderr, "Error: no moveset given\n"); | ||
| 191 | return; | ||
| 192 | } | ||
| 193 | |||
| 194 | for (i = U; i < NMOVES; i++) | ||
| 195 | if (ms(i)) | ||
| 196 | r[n++] = i; | ||
| 197 | |||
| 198 | r[n] = NULLMOVE; | ||
| 199 | } | ||
| 200 | |||
| 201 | Alg * | 272 | Alg * |
| 202 | new_alg(char *str) | 273 | new_alg(char *str) |
| 203 | { | 274 | { |
| @@ -405,3 +476,34 @@ unniss(Alg *alg) | |||
| 405 | } | 476 | } |
| 406 | free(aux); | 477 | free(aux); |
| 407 | } | 478 | } |
| 479 | |||
| 480 | void | ||
| 481 | init_movesets() | ||
| 482 | { | ||
| 483 | int i, j; | ||
| 484 | uint64_t l, one; | ||
| 485 | Move m, l2, l1; | ||
| 486 | Moveset *ms; | ||
| 487 | |||
| 488 | one = 1; | ||
| 489 | |||
| 490 | for (i = 0; i < nmoveset; i++) { | ||
| 491 | ms = all_ms[i]; | ||
| 492 | |||
| 493 | for (j = 0, m = U; m < NMOVES; m++) | ||
| 494 | if (ms->allowed(m)) | ||
| 495 | ms->sorted_moves[j++] = m; | ||
| 496 | ms->sorted_moves[j] = NULLMOVE; | ||
| 497 | |||
| 498 | for (l1 = 0; l1 < NMOVES; l1++) { | ||
| 499 | for (l2 = 0; l2 < NMOVES; l2++) { | ||
| 500 | ms->mask[l2][l1] = 0; | ||
| 501 | for (l=0; ms->sorted_moves[l]!=NULLMOVE; l++) { | ||
| 502 | m = ms->sorted_moves[l]; | ||
| 503 | if (ms->allowed_next(l2, l1, m)) | ||
| 504 | ms->mask[l2][l1] |= (one<<m); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | } | ||
| 508 | } | ||
| 509 | } | ||
| @@ -8,16 +8,17 @@ | |||
| 8 | #include "cubetypes.h" | 8 | #include "cubetypes.h" |
| 9 | #include "utils.h" | 9 | #include "utils.h" |
| 10 | 10 | ||
| 11 | bool moveset_HTM(Move m); | 11 | extern Moveset moveset_HTM; |
| 12 | bool moveset_URF(Move m); | 12 | extern Moveset moveset_URF; |
| 13 | bool moveset_eofb(Move m); | 13 | extern Moveset moveset_eofb; |
| 14 | bool moveset_drud(Move m); | 14 | extern Moveset moveset_drud; |
| 15 | bool moveset_htr(Move m); | 15 | extern Moveset moveset_htr; |
| 16 | 16 | ||
| 17 | void append_alg(AlgList *l, Alg *alg); | 17 | void append_alg(AlgList *l, Alg *alg); |
| 18 | void append_move(Alg *alg, Move m, bool inverse); | 18 | void append_move(Alg *alg, Move m, bool inverse); |
| 19 | void compose_alg(Alg *alg1, Alg *alg2); | ||
| 20 | Move base_move(Move m); | 19 | Move base_move(Move m); |
| 20 | void compose_alg(Alg *alg1, Alg *alg2); | ||
| 21 | bool commute(Move m1, Move m2); | ||
| 21 | void free_alg(Alg *alg); | 22 | void free_alg(Alg *alg); |
| 22 | void free_alglist(AlgList *l); | 23 | void free_alglist(AlgList *l); |
| 23 | Alg * inverse_alg(Alg *alg); | 24 | Alg * inverse_alg(Alg *alg); |
| @@ -33,5 +34,7 @@ void print_alglist(AlgList *al, bool l); | |||
| 33 | void swapmove(Move *m1, Move *m2); | 34 | void swapmove(Move *m1, Move *m2); |
| 34 | void unniss(Alg *alg); | 35 | void unniss(Alg *alg); |
| 35 | 36 | ||
| 37 | void init_movesets(); | ||
| 38 | |||
| 36 | #endif | 39 | #endif |
| 37 | 40 | ||
diff --git a/src/commands.c b/src/commands.c index b90a7f5..9a2ad51 100644 --- a/src/commands.c +++ b/src/commands.c | |||
| @@ -259,6 +259,7 @@ solve_exec(CommandArgs *args) | |||
| 259 | Cube c; | 259 | Cube c; |
| 260 | AlgList *sols; | 260 | AlgList *sols; |
| 261 | 261 | ||
| 262 | init_movesets(); | ||
| 262 | init_symcoord(); | 263 | init_symcoord(); |
| 263 | 264 | ||
| 264 | c = apply_alg(args->scramble, (Cube){0}); | 265 | c = apply_alg(args->scramble, (Cube){0}); |
| @@ -274,6 +275,7 @@ gen_exec(CommandArgs *args) | |||
| 274 | int i; | 275 | int i; |
| 275 | 276 | ||
| 276 | fprintf(stderr, "Generating coordinates...\n"); | 277 | fprintf(stderr, "Generating coordinates...\n"); |
| 278 | init_movesets(); | ||
| 277 | init_symcoord(); | 279 | init_symcoord(); |
| 278 | 280 | ||
| 279 | fprintf(stderr, "Generating pruning tables...\n"); | 281 | fprintf(stderr, "Generating pruning tables...\n"); |
diff --git a/src/coord.c b/src/coord.c index c9a28c4..3bbda22 100644 --- a/src/coord.c +++ b/src/coord.c | |||
| @@ -13,6 +13,7 @@ static Cube antindex_drud(uint64_t ind); | |||
| 13 | static Cube antindex_drud_eofb(uint64_t ind); | 13 | static Cube antindex_drud_eofb(uint64_t ind); |
| 14 | static Cube antindex_htr_drud(uint64_t ind); | 14 | static Cube antindex_htr_drud(uint64_t ind); |
| 15 | static Cube antindex_htrfin(uint64_t ind); | 15 | static Cube antindex_htrfin(uint64_t ind); |
| 16 | static Cube antindex_cpud_separate(uint64_t ind); | ||
| 16 | 17 | ||
| 17 | static uint64_t index_eofb(Cube cube); | 18 | static uint64_t index_eofb(Cube cube); |
| 18 | static uint64_t index_eofbepos(Cube cube); | 19 | static uint64_t index_eofbepos(Cube cube); |
| @@ -27,6 +28,7 @@ static uint64_t index_drud(Cube cube); | |||
| 27 | static uint64_t index_drud_eofb(Cube cube); | 28 | static uint64_t index_drud_eofb(Cube cube); |
| 28 | static uint64_t index_htr_drud(Cube cube); | 29 | static uint64_t index_htr_drud(Cube cube); |
| 29 | static uint64_t index_htrfin(Cube cube); | 30 | static uint64_t index_htrfin(Cube cube); |
| 31 | static uint64_t index_cpud_separate(Cube cube); | ||
| 30 | 32 | ||
| 31 | static void init_cphtr_cosets(); | 33 | static void init_cphtr_cosets(); |
| 32 | static void init_cphtr_left_cosets_bfs(int i, int c); | 34 | static void init_cphtr_left_cosets_bfs(int i, int c); |
| @@ -135,6 +137,13 @@ coord_drud_eofb = { | |||
| 135 | .max = POW3TO7 * BINOM12ON4, | 137 | .max = POW3TO7 * BINOM12ON4, |
| 136 | }; | 138 | }; |
| 137 | 139 | ||
| 140 | Coordinate | ||
| 141 | coord_cpud_separate = { | ||
| 142 | .index = index_cpud_separate, | ||
| 143 | .cube = antindex_cpud_separate, | ||
| 144 | .max = BINOM8ON4, | ||
| 145 | }; | ||
| 146 | |||
| 138 | /* Antindexers ***************************************************************/ | 147 | /* Antindexers ***************************************************************/ |
| 139 | 148 | ||
| 140 | static Cube | 149 | static Cube |
| @@ -356,6 +365,31 @@ antindex_htrfin(uint64_t ind) | |||
| 356 | return ret; | 365 | return ret; |
| 357 | } | 366 | } |
| 358 | 367 | ||
| 368 | static Cube | ||
| 369 | antindex_cpud_separate(uint64_t ind) | ||
| 370 | { | ||
| 371 | /* Not consistent because of side corner orientations and cp */ | ||
| 372 | unsigned int ui; | ||
| 373 | int i, co[8], cp[8]; | ||
| 374 | Corner u, d; | ||
| 375 | |||
| 376 | static Cube aux[BINOM8ON4]; | ||
| 377 | static bool initialized = false; | ||
| 378 | |||
| 379 | if (!initialized) { | ||
| 380 | for (ui = 0; ui < BINOM8ON4; ui++) { | ||
| 381 | index_to_subset(ui, 8, 4, co); | ||
| 382 | for (i = 0, u = UFR, d = DFR; i < 8; i++) | ||
| 383 | cp[i] = co[i] ? d++ : u++; | ||
| 384 | aux[ui] = (Cube){.cp = perm_to_index(cp, 8)}; | ||
| 385 | } | ||
| 386 | |||
| 387 | initialized = true; | ||
| 388 | } | ||
| 389 | |||
| 390 | return aux[ind]; | ||
| 391 | } | ||
| 392 | |||
| 359 | /* Indexers ******************************************************************/ | 393 | /* Indexers ******************************************************************/ |
| 360 | 394 | ||
| 361 | static uint64_t | 395 | static uint64_t |
| @@ -477,6 +511,29 @@ index_htrfin(Cube cube) | |||
| 477 | return cp * 24 * 24 * 24 + ep; | 511 | return cp * 24 * 24 * 24 + ep; |
| 478 | } | 512 | } |
| 479 | 513 | ||
| 514 | static uint64_t | ||
| 515 | index_cpud_separate(Cube cube) | ||
| 516 | { | ||
| 517 | unsigned int ui; | ||
| 518 | int i, co[8]; | ||
| 519 | |||
| 520 | static int aux[FACTORIAL8]; | ||
| 521 | static bool initialized = false; | ||
| 522 | |||
| 523 | if (!initialized) { | ||
| 524 | for (ui = 0; ui < FACTORIAL8; ui++) { | ||
| 525 | for (i = 0; i < 8; i++) | ||
| 526 | co[i] = what_corner_at((Cube){.cp=ui},i)>UBR ? | ||
| 527 | 1 : 0; | ||
| 528 | aux[ui] = subset_to_index(co, 8, 4); | ||
| 529 | } | ||
| 530 | |||
| 531 | initialized = true; | ||
| 532 | } | ||
| 533 | |||
| 534 | return aux[cube.cp]; | ||
| 535 | } | ||
| 536 | |||
| 480 | /* Init functions implementation *********************************************/ | 537 | /* Init functions implementation *********************************************/ |
| 481 | 538 | ||
| 482 | /* | 539 | /* |
| @@ -528,7 +585,7 @@ init_cphtr_left_cosets_bfs(int i, int c) | |||
| 528 | while (n != 0) { | 585 | while (n != 0) { |
| 529 | for (j = 0, n2 = 0; j < n; j++) { | 586 | for (j = 0, n2 = 0; j < n; j++) { |
| 530 | for (k = U2; k < B3; k++) { | 587 | for (k = U2; k < B3; k++) { |
| 531 | if (!moveset_htr(k)) | 588 | if (!moveset_htr.allowed(k)) |
| 532 | continue; | 589 | continue; |
| 533 | jj = apply_move(k, (Cube){ .cp = next[j] }).cp; | 590 | jj = apply_move(k, (Cube){ .cp = next[j] }).cp; |
| 534 | 591 | ||
| @@ -578,7 +635,7 @@ init_cornershtrfin() | |||
| 578 | if (cornershtrfin_ind[j] == -1) | 635 | if (cornershtrfin_ind[j] == -1) |
| 579 | continue; | 636 | continue; |
| 580 | for (m = U; m < NMOVES; m++) { | 637 | for (m = U; m < NMOVES; m++) { |
| 581 | if (moveset_htr(m)) { | 638 | if (moveset_htr.allowed(m)) { |
| 582 | c = apply_move(m, (Cube){.cp = j}).cp; | 639 | c = apply_move(m, (Cube){.cp = j}).cp; |
| 583 | if (cornershtrfin_ind[c] == -1) { | 640 | if (cornershtrfin_ind[c] == -1) { |
| 584 | cornershtrfin_ind[c] = n; | 641 | cornershtrfin_ind[c] = n; |
| @@ -592,6 +649,31 @@ init_cornershtrfin() | |||
| 592 | } | 649 | } |
| 593 | 650 | ||
| 594 | void | 651 | void |
| 652 | test_coord(Coordinate *coord) | ||
| 653 | { | ||
| 654 | bool passed; | ||
| 655 | uint64_t ui, failcount; | ||
| 656 | |||
| 657 | if (!(passed = (coord->index((Cube){0}) == 0))) { | ||
| 658 | printf("Failed: coordinate of solved cube is " | ||
| 659 | "%" PRIu64 "\n", coord->index((Cube){0})); | ||
| 660 | } | ||
| 661 | |||
| 662 | printf("Testing %" PRIu64 " coordinates\n", coord->max); | ||
| 663 | for (failcount = 0, ui = 0; ui < coord->max; ui++) { | ||
| 664 | if (!(passed = (coord->index(coord->cube(ui)) == ui))) { | ||
| 665 | printf("Failed at %" PRIu64 "\n", ui); | ||
| 666 | failcount++; | ||
| 667 | } | ||
| 668 | } | ||
| 669 | |||
| 670 | if (passed) | ||
| 671 | printf("Ok\n"); | ||
| 672 | else | ||
| 673 | printf("Test failed in %" PRIu64 " cases\n", failcount); | ||
| 674 | } | ||
| 675 | |||
| 676 | void | ||
| 595 | init_coord() | 677 | init_coord() |
| 596 | { | 678 | { |
| 597 | static bool initialized = false; | 679 | static bool initialized = false; |
diff --git a/src/coord.h b/src/coord.h index be41b96..81e5866 100644 --- a/src/coord.h +++ b/src/coord.h | |||
| @@ -16,7 +16,9 @@ extern Coordinate coord_drud; | |||
| 16 | extern Coordinate coord_drud_eofb; | 16 | extern Coordinate coord_drud_eofb; |
| 17 | extern Coordinate coord_htr_drud; | 17 | extern Coordinate coord_htr_drud; |
| 18 | extern Coordinate coord_htrfin; | 18 | extern Coordinate coord_htrfin; |
| 19 | extern Coordinate coord_cpud_separate; | ||
| 19 | 20 | ||
| 21 | void test_coord(Coordinate *coord); | ||
| 20 | void init_coord(); | 22 | void init_coord(); |
| 21 | 23 | ||
| 22 | #endif | 24 | #endif |
diff --git a/src/cubetypes.h b/src/cubetypes.h index 3ad960b..d1d36b2 100644 --- a/src/cubetypes.h +++ b/src/cubetypes.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #define NMOVES 55 /* Actually 54, but one is NULLMOVE */ | 8 | #define NMOVES 55 /* Actually 54, but one is NULLMOVE */ |
| 9 | #define NTRANS 48 | 9 | #define NTRANS 48 |
| 10 | #define NROTATIONS 24 | 10 | #define NROTATIONS 24 |
| 11 | #define entry_group_t uint8_t /* For pruning tables */ | ||
| 11 | 12 | ||
| 12 | /* Enums *********************************************************************/ | 13 | /* Enums *********************************************************************/ |
| 13 | 14 | ||
| @@ -83,6 +84,7 @@ typedef struct cube Cube; | |||
| 83 | typedef struct cubearray CubeArray; | 84 | typedef struct cubearray CubeArray; |
| 84 | typedef struct dfsarg DfsArg; | 85 | typedef struct dfsarg DfsArg; |
| 85 | typedef struct estimatedata EstimateData; | 86 | typedef struct estimatedata EstimateData; |
| 87 | typedef struct moveset Moveset; | ||
| 86 | typedef struct piecefilter PieceFilter; | 88 | typedef struct piecefilter PieceFilter; |
| 87 | typedef struct prunedata PruneData; | 89 | typedef struct prunedata PruneData; |
| 88 | typedef struct solveoptions SolveOptions; | 90 | typedef struct solveoptions SolveOptions; |
| @@ -97,7 +99,6 @@ typedef int (*Estimator) (DfsArg *); | |||
| 97 | typedef bool (*Validator) (Alg *); | 99 | typedef bool (*Validator) (Alg *); |
| 98 | typedef void (*Exec) (CommandArgs *); | 100 | typedef void (*Exec) (CommandArgs *); |
| 99 | typedef uint64_t (*Indexer) (Cube); | 101 | typedef uint64_t (*Indexer) (Cube); |
| 100 | typedef bool (*Moveset) (Move); | ||
| 101 | typedef CommandArgs * (*ArgParser) (int, char **); | 102 | typedef CommandArgs * (*ArgParser) (int, char **); |
| 102 | typedef Trans (*TransDetector) (Cube); | 103 | typedef Trans (*TransDetector) (Cube); |
| 103 | typedef int (*TransFinder) (uint64_t, Trans *); | 104 | typedef int (*TransFinder) (uint64_t, Trans *); |
| @@ -215,8 +216,6 @@ dfsarg | |||
| 215 | AlgList * sols; | 216 | AlgList * sols; |
| 216 | pthread_mutex_t * sols_mutex; | 217 | pthread_mutex_t * sols_mutex; |
| 217 | Alg * current_alg; | 218 | Alg * current_alg; |
| 218 | Move * sorted_moves; | ||
| 219 | int * move_position; | ||
| 220 | }; | 219 | }; |
| 221 | 220 | ||
| 222 | struct | 221 | struct |
| @@ -233,6 +232,15 @@ estimatedata | |||
| 233 | }; | 232 | }; |
| 234 | 233 | ||
| 235 | struct | 234 | struct |
| 235 | moveset | ||
| 236 | { | ||
| 237 | bool (*allowed)(Move); | ||
| 238 | bool (*allowed_next)(Move, Move, Move); | ||
| 239 | Move sorted_moves[NMOVES+1]; | ||
| 240 | uint64_t mask[NMOVES][NMOVES]; | ||
| 241 | }; | ||
| 242 | |||
| 243 | struct | ||
| 236 | piecefilter | 244 | piecefilter |
| 237 | { | 245 | { |
| 238 | bool epose; | 246 | bool epose; |
| @@ -252,11 +260,11 @@ struct | |||
| 252 | prunedata | 260 | prunedata |
| 253 | { | 261 | { |
| 254 | char * filename; | 262 | char * filename; |
| 255 | uint8_t * ptable; | 263 | entry_group_t * ptable; |
| 256 | bool generated; | 264 | bool generated; |
| 257 | uint64_t n; | 265 | uint64_t n; |
| 258 | Coordinate * coord; | 266 | Coordinate * coord; |
| 259 | Moveset moveset; | 267 | Moveset * moveset; |
| 260 | }; | 268 | }; |
| 261 | 269 | ||
| 262 | struct | 270 | struct |
| @@ -284,7 +292,7 @@ step | |||
| 284 | Checker ready; | 292 | Checker ready; |
| 285 | char * ready_msg; | 293 | char * ready_msg; |
| 286 | Validator is_valid; | 294 | Validator is_valid; |
| 287 | Moveset moveset; | 295 | Moveset * moveset; |
| 288 | Trans pre_trans; | 296 | Trans pre_trans; |
| 289 | TransDetector detect; | 297 | TransDetector detect; |
| 290 | int ntables; | 298 | int ntables; |
| @@ -312,8 +320,6 @@ threaddatasolve | |||
| 312 | Cube cube; | 320 | Cube cube; |
| 313 | Step * step; | 321 | Step * step; |
| 314 | int depth; | 322 | int depth; |
| 315 | Move * sorted_moves; | ||
| 316 | int * move_position; | ||
| 317 | SolveOptions * opts; | 323 | SolveOptions * opts; |
| 318 | AlgList * start; | 324 | AlgList * start; |
| 319 | AlgListNode ** node; | 325 | AlgListNode ** node; |
| @@ -329,7 +335,6 @@ threaddatagenpt | |||
| 329 | int nthreads; | 335 | int nthreads; |
| 330 | PruneData * pd; | 336 | PruneData * pd; |
| 331 | int d; | 337 | int d; |
| 332 | Move * ms; | ||
| 333 | int nchunks; | 338 | int nchunks; |
| 334 | pthread_mutex_t ** mutex; | 339 | pthread_mutex_t ** mutex; |
| 335 | pthread_mutex_t * upmutex; | 340 | pthread_mutex_t * upmutex; |
diff --git a/src/moves.c b/src/moves.c index 5aca0ee..9547de9 100644 --- a/src/moves.c +++ b/src/moves.c | |||
| @@ -319,57 +319,6 @@ write_mtables_file() | |||
| 319 | return r; | 319 | return r; |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | bool | ||
| 323 | commute(Move m1, Move m2) | ||
| 324 | { | ||
| 325 | static bool initialized = false; | ||
| 326 | static bool commute_aux[NMOVES][NMOVES]; | ||
| 327 | |||
| 328 | if (!initialized) { | ||
| 329 | Cube c1, c2; | ||
| 330 | int i, j; | ||
| 331 | |||
| 332 | for (i = 0; i < NMOVES; i++) { | ||
| 333 | for (j = 0; j < NMOVES; j++) { | ||
| 334 | c1 = apply_move(i, apply_move(j, (Cube){0})); | ||
| 335 | c2 = apply_move(j, apply_move(i, (Cube){0})); | ||
| 336 | commute_aux[i][j] = equal(c1, c2) && i && j; | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | initialized = true; | ||
| 341 | } | ||
| 342 | |||
| 343 | return commute_aux[m1][m2]; | ||
| 344 | } | ||
| 345 | |||
| 346 | bool | ||
| 347 | possible_next(Move m1, Move m2, Move m3) | ||
| 348 | { | ||
| 349 | static bool initialized = false; | ||
| 350 | static bool paux[NMOVES][NMOVES][NMOVES]; | ||
| 351 | |||
| 352 | if (!initialized) { | ||
| 353 | int i, j, k; | ||
| 354 | bool p, q, c; | ||
| 355 | |||
| 356 | for (i = 0; i < NMOVES; i++) { | ||
| 357 | for (j = 0; j < NMOVES; j++) { | ||
| 358 | for (k = 0; k < NMOVES; k++) { | ||
| 359 | p = j && base_move(j) == base_move(k); | ||
| 360 | q = i && base_move(i) == base_move(k); | ||
| 361 | c = commute(i, j); | ||
| 362 | paux[i][j][k] = !(p || (c && q)); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | } | ||
| 366 | |||
| 367 | initialized = true; | ||
| 368 | } | ||
| 369 | |||
| 370 | return paux[m1][m2][m3]; | ||
| 371 | } | ||
| 372 | |||
| 373 | void | 322 | void |
| 374 | init_moves() { | 323 | init_moves() { |
| 375 | static bool initialized = false; | 324 | static bool initialized = false; |
diff --git a/src/moves.h b/src/moves.h index 082a080..4820f65 100644 --- a/src/moves.h +++ b/src/moves.h | |||
| @@ -8,8 +8,6 @@ | |||
| 8 | Cube apply_alg(Alg *alg, Cube cube); | 8 | Cube apply_alg(Alg *alg, Cube cube); |
| 9 | Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a); | 9 | Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a); |
| 10 | Cube apply_move(Move m, Cube cube); | 10 | Cube apply_move(Move m, Cube cube); |
| 11 | bool commute(Move m1, Move m2); | ||
| 12 | bool possible_next(Move m1, Move m2, Move m3); | ||
| 13 | 11 | ||
| 14 | void init_moves(); | 12 | void init_moves(); |
| 15 | 13 | ||
diff --git a/src/pruning.c b/src/pruning.c index b305a89..0a6e305 100644 --- a/src/pruning.c +++ b/src/pruning.c | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | #include "pruning.h" | 1 | #include "pruning.h" |
| 2 | 2 | ||
| 3 | /* Chunks for multithreading */ | 3 | #define NCHUNKS 100000 |
| 4 | /* TODO: try smaller */ | 4 | #define ENTRIES_PER_GROUP (2*sizeof(entry_group_t)) |
| 5 | #define NCHUNKS 100000 | ||
| 6 | 5 | ||
| 7 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); | 6 | static int findchunk(PruneData *pd, int nchunks, uint64_t i); |
| 8 | static void genptable_bfs(PruneData *pd,int d,Move *ms,int nt,int nc); | 7 | static void genptable_bfs(PruneData *pd, int d, int nt, int nc); |
| 9 | static void genptable_fixnasty(PruneData *pd, int d); | 8 | static void genptable_fixnasty(PruneData *pd, int d); |
| 10 | static void * instance_bfs(void *arg); | 9 | static void * instance_bfs(void *arg); |
| 11 | static void ptable_update(PruneData *pd, Cube cube, int m); | 10 | static void ptable_update(PruneData *pd, Cube cube, int m); |
| @@ -18,70 +17,77 @@ PruneData | |||
| 18 | pd_eofb_HTM = { | 17 | pd_eofb_HTM = { |
| 19 | .filename = "pt_eofb_HTM", | 18 | .filename = "pt_eofb_HTM", |
| 20 | .coord = &coord_eofb, | 19 | .coord = &coord_eofb, |
| 21 | .moveset = moveset_HTM, | 20 | .moveset = &moveset_HTM, |
| 22 | }; | 21 | }; |
| 23 | 22 | ||
| 24 | PruneData | 23 | PruneData |
| 25 | pd_coud_HTM = { | 24 | pd_coud_HTM = { |
| 26 | .filename = "pt_coud_HTM", | 25 | .filename = "pt_coud_HTM", |
| 27 | .coord = &coord_coud, | 26 | .coord = &coord_coud, |
| 28 | .moveset = moveset_HTM, | 27 | .moveset = &moveset_HTM, |
| 29 | }; | 28 | }; |
| 30 | 29 | ||
| 31 | PruneData | 30 | PruneData |
| 32 | pd_cornershtr_HTM = { | 31 | pd_cornershtr_HTM = { |
| 33 | .filename = "pt_cornershtr_HTM", | 32 | .filename = "pt_cornershtr_HTM", |
| 34 | .coord = &coord_cornershtr, | 33 | .coord = &coord_cornershtr, |
| 35 | .moveset = moveset_HTM, | 34 | .moveset = &moveset_HTM, |
| 36 | }; | 35 | }; |
| 37 | 36 | ||
| 38 | PruneData | 37 | PruneData |
| 39 | pd_corners_HTM = { | 38 | pd_corners_HTM = { |
| 40 | .filename = "pt_corners_HTM", | 39 | .filename = "pt_corners_HTM", |
| 41 | .coord = &coord_corners, | 40 | .coord = &coord_corners, |
| 42 | .moveset = moveset_HTM, | 41 | .moveset = &moveset_HTM, |
| 43 | }; | 42 | }; |
| 44 | 43 | ||
| 45 | PruneData | 44 | PruneData |
| 46 | pd_drud_sym16_HTM = { | 45 | pd_drud_sym16_HTM = { |
| 47 | .filename = "pt_drud_sym16_HTM", | 46 | .filename = "pt_drud_sym16_HTM", |
| 48 | .coord = &coord_drud_sym16, | 47 | .coord = &coord_drud_sym16, |
| 49 | .moveset = moveset_HTM, | 48 | .moveset = &moveset_HTM, |
| 50 | }; | 49 | }; |
| 51 | 50 | ||
| 52 | PruneData | 51 | PruneData |
| 53 | pd_drud_eofb = { | 52 | pd_drud_eofb = { |
| 54 | .filename = "pt_drud_eofb", | 53 | .filename = "pt_drud_eofb", |
| 55 | .coord = &coord_drud_eofb, | 54 | .coord = &coord_drud_eofb, |
| 56 | .moveset = moveset_eofb, | 55 | .moveset = &moveset_eofb, |
| 57 | }; | 56 | }; |
| 58 | 57 | ||
| 59 | PruneData | 58 | PruneData |
| 60 | pd_drudfin_noE_sym16_drud = { | 59 | pd_drudfin_noE_sym16_drud = { |
| 61 | .filename = "pt_drudfin_noE_sym16_drud", | 60 | .filename = "pt_drudfin_noE_sym16_drud", |
| 62 | .coord = &coord_drudfin_noE_sym16, | 61 | .coord = &coord_drudfin_noE_sym16, |
| 63 | .moveset = moveset_drud, | 62 | .moveset = &moveset_drud, |
| 64 | }; | 63 | }; |
| 65 | 64 | ||
| 66 | PruneData | 65 | PruneData |
| 67 | pd_htr_drud = { | 66 | pd_htr_drud = { |
| 68 | .filename = "pt_htr_drud", | 67 | .filename = "pt_htr_drud", |
| 69 | .coord = &coord_htr_drud, | 68 | .coord = &coord_htr_drud, |
| 70 | .moveset = moveset_drud, | 69 | .moveset = &moveset_drud, |
| 71 | }; | 70 | }; |
| 72 | 71 | ||
| 73 | PruneData | 72 | PruneData |
| 74 | pd_htrfin_htr = { | 73 | pd_htrfin_htr = { |
| 75 | .filename = "pt_htrfin_htr", | 74 | .filename = "pt_htrfin_htr", |
| 76 | .coord = &coord_htrfin, | 75 | .coord = &coord_htrfin, |
| 77 | .moveset = moveset_htr, | 76 | .moveset = &moveset_htr, |
| 78 | }; | 77 | }; |
| 79 | 78 | ||
| 80 | PruneData | 79 | PruneData |
| 81 | pd_khuge_HTM = { | 80 | pd_khuge_HTM = { |
| 82 | .filename = "pt_khuge_HTM", | 81 | .filename = "pt_khuge_HTM", |
| 83 | .coord = &coord_khuge, | 82 | .coord = &coord_khuge, |
| 84 | .moveset = moveset_HTM, | 83 | .moveset = &moveset_HTM, |
| 84 | }; | ||
| 85 | |||
| 86 | PruneData | ||
| 87 | pd_nxopt31_HTM = { | ||
| 88 | .filename = "pt_nxopt31_HTM", | ||
| 89 | .coord = &coord_nxopt31, | ||
| 90 | .moveset = &moveset_HTM, | ||
| 85 | }; | 91 | }; |
| 86 | 92 | ||
| 87 | PruneData * allpd[NPTABLES] = { | 93 | PruneData * allpd[NPTABLES] = { |
| @@ -95,6 +101,7 @@ PruneData * allpd[NPTABLES] = { | |||
| 95 | &pd_htr_drud, | 101 | &pd_htr_drud, |
| 96 | &pd_htrfin_htr, | 102 | &pd_htrfin_htr, |
| 97 | &pd_khuge_HTM, | 103 | &pd_khuge_HTM, |
| 104 | &pd_nxopt31_HTM, | ||
| 98 | }; | 105 | }; |
| 99 | 106 | ||
| 100 | /* Functions *****************************************************************/ | 107 | /* Functions *****************************************************************/ |
| @@ -105,8 +112,7 @@ findchunk(PruneData *pd, int nchunks, uint64_t i) | |||
| 105 | uint64_t chunksize; | 112 | uint64_t chunksize; |
| 106 | 113 | ||
| 107 | chunksize = pd->coord->max / (uint64_t)nchunks; | 114 | chunksize = pd->coord->max / (uint64_t)nchunks; |
| 108 | if (chunksize % 2 != 0) | 115 | chunksize += ENTRIES_PER_GROUP - (chunksize % ENTRIES_PER_GROUP); |
| 109 | chunksize++; | ||
| 110 | 116 | ||
| 111 | return MIN(nchunks-1, (int)(i / chunksize)); | 117 | return MIN(nchunks-1, (int)(i / chunksize)); |
| 112 | } | 118 | } |
| @@ -114,15 +120,14 @@ findchunk(PruneData *pd, int nchunks, uint64_t i) | |||
| 114 | void | 120 | void |
| 115 | genptable(PruneData *pd, int nthreads) | 121 | genptable(PruneData *pd, int nthreads) |
| 116 | { | 122 | { |
| 117 | Move *ms; | ||
| 118 | int d, nchunks; | 123 | int d, nchunks; |
| 119 | uint64_t j, oldn; | 124 | uint64_t oldn; |
| 120 | 125 | ||
| 121 | if (pd->generated) | 126 | if (pd->generated) |
| 122 | return; | 127 | return; |
| 123 | 128 | ||
| 124 | /* TODO: check if memory is enough, otherwise maybe exit gracefully? */ | 129 | /* TODO: check if memory is enough, otherwise maybe exit gracefully? */ |
| 125 | pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t)); | 130 | pd->ptable = malloc(ptablesize(pd) * sizeof(entry_group_t)); |
| 126 | 131 | ||
| 127 | if (read_ptable_file(pd)) { | 132 | if (read_ptable_file(pd)) { |
| 128 | pd->generated = true; | 133 | pd->generated = true; |
| @@ -130,17 +135,12 @@ genptable(PruneData *pd, int nthreads) | |||
| 130 | } | 135 | } |
| 131 | pd->generated = true; | 136 | pd->generated = true; |
| 132 | 137 | ||
| 133 | nchunks = MIN(pd->coord->max/2, NCHUNKS); | 138 | nchunks = MIN(pd->coord->max/ENTRIES_PER_GROUP, NCHUNKS); |
| 134 | fprintf(stderr, "Cannot load %s, generating it " | 139 | fprintf(stderr, "Cannot load %s, generating it " |
| 135 | "with %d threads and %d chunks\n", | 140 | "with %d threads and %d chunks\n", |
| 136 | pd->filename, nthreads, nchunks); | 141 | pd->filename, nthreads, nchunks); |
| 137 | 142 | ||
| 138 | ms = malloc(NMOVES * sizeof(Move)); | 143 | memset(pd->ptable, ~(uint8_t)0, ptablesize(pd)*sizeof(entry_group_t)); |
| 139 | moveset_to_list(pd->moveset, ms); | ||
| 140 | |||
| 141 | /* We use 4 bits per value, so any distance >= 15 is set to 15 */ | ||
| 142 | for (j = 0; j < pd->coord->max; j++) | ||
| 143 | ptable_update_index(pd, j, 15); | ||
| 144 | 144 | ||
| 145 | ptable_update(pd, (Cube){0}, 0); | 145 | ptable_update(pd, (Cube){0}, 0); |
| 146 | pd->n = 1; | 146 | pd->n = 1; |
| @@ -151,7 +151,7 @@ genptable(PruneData *pd, int nthreads) | |||
| 151 | 0, pd->n - oldn, pd->n, pd->coord->max); | 151 | 0, pd->n - oldn, pd->n, pd->coord->max); |
| 152 | oldn = pd->n; | 152 | oldn = pd->n; |
| 153 | for (d = 0; d < 15 && pd->n < pd->coord->max; d++) { | 153 | for (d = 0; d < 15 && pd->n < pd->coord->max; d++) { |
| 154 | genptable_bfs(pd, d, ms, nthreads, nchunks); | 154 | genptable_bfs(pd, d, nthreads, nchunks); |
| 155 | genptable_fixnasty(pd, d+1); | 155 | genptable_fixnasty(pd, d+1); |
| 156 | fprintf(stderr, "Depth %d done, generated %" | 156 | fprintf(stderr, "Depth %d done, generated %" |
| 157 | PRIu64 "\t(%" PRIu64 "/%" PRIu64 ")\n", | 157 | PRIu64 "\t(%" PRIu64 "/%" PRIu64 ")\n", |
| @@ -162,12 +162,10 @@ genptable(PruneData *pd, int nthreads) | |||
| 162 | 162 | ||
| 163 | if (!write_ptable_file(pd)) | 163 | if (!write_ptable_file(pd)) |
| 164 | fprintf(stderr, "Error writing ptable file\n"); | 164 | fprintf(stderr, "Error writing ptable file\n"); |
| 165 | |||
| 166 | free(ms); | ||
| 167 | } | 165 | } |
| 168 | 166 | ||
| 169 | static void | 167 | static void |
| 170 | genptable_bfs(PruneData *pd, int d, Move *ms, int nthreads, int nchunks) | 168 | genptable_bfs(PruneData *pd, int d, int nthreads, int nchunks) |
| 171 | { | 169 | { |
| 172 | int i; | 170 | int i; |
| 173 | pthread_t t[nthreads]; | 171 | pthread_t t[nthreads]; |
| @@ -186,7 +184,6 @@ genptable_bfs(PruneData *pd, int d, Move *ms, int nthreads, int nchunks) | |||
| 186 | td[i].nthreads = nthreads; | 184 | td[i].nthreads = nthreads; |
| 187 | td[i].pd = pd; | 185 | td[i].pd = pd; |
| 188 | td[i].d = d; | 186 | td[i].d = d; |
| 189 | td[i].ms = ms; | ||
| 190 | td[i].nchunks = nchunks; | 187 | td[i].nchunks = nchunks; |
| 191 | td[i].mutex = mtx; | 188 | td[i].mutex = mtx; |
| 192 | td[i].upmutex = upmtx; | 189 | td[i].upmutex = upmtx; |
| @@ -237,8 +234,10 @@ instance_bfs(void *arg) | |||
| 237 | uint64_t i, ii, blocksize, rmin, rmax, updated; | 234 | uint64_t i, ii, blocksize, rmin, rmax, updated; |
| 238 | int j, pval, ichunk; | 235 | int j, pval, ichunk; |
| 239 | Cube c, cc; | 236 | Cube c, cc; |
| 237 | Move *ms; | ||
| 240 | 238 | ||
| 241 | td = (ThreadDataGenpt *)arg; | 239 | td = (ThreadDataGenpt *)arg; |
| 240 | ms = td->pd->moveset->sorted_moves; | ||
| 242 | blocksize = td->pd->coord->max / (uint64_t)td->nthreads; | 241 | blocksize = td->pd->coord->max / (uint64_t)td->nthreads; |
| 243 | rmin = ((uint64_t)td->thid) * blocksize; | 242 | rmin = ((uint64_t)td->thid) * blocksize; |
| 244 | rmax = td->thid == td->nthreads - 1 ? | 243 | rmax = td->thid == td->nthreads - 1 ? |
| @@ -253,8 +252,8 @@ instance_bfs(void *arg) | |||
| 253 | pthread_mutex_unlock(td->mutex[ichunk]); | 252 | pthread_mutex_unlock(td->mutex[ichunk]); |
| 254 | if (pval == td->d) { | 253 | if (pval == td->d) { |
| 255 | c = td->pd->coord->cube(i); | 254 | c = td->pd->coord->cube(i); |
| 256 | for (j = 0; td->ms[j] != NULLMOVE; j++) { | 255 | for (j = 0; ms[j] != NULLMOVE; j++) { |
| 257 | cc = apply_move(td->ms[j], c); | 256 | cc = apply_move(ms[j], c); |
| 258 | ii = td->pd->coord->index(cc); | 257 | ii = td->pd->coord->index(cc); |
| 259 | ichunk = findchunk(td->pd, td->nchunks, ii); | 258 | ichunk = findchunk(td->pd, td->nchunks, ii); |
| 260 | pthread_mutex_lock(td->mutex[ichunk]); | 259 | pthread_mutex_lock(td->mutex[ichunk]); |
| @@ -296,7 +295,7 @@ print_ptable(PruneData *pd) | |||
| 296 | uint64_t | 295 | uint64_t |
| 297 | ptablesize(PruneData *pd) | 296 | ptablesize(PruneData *pd) |
| 298 | { | 297 | { |
| 299 | return (pd->coord->max + 1) / 2; | 298 | return (pd->coord->max + ENTRIES_PER_GROUP - 1) / ENTRIES_PER_GROUP; |
| 300 | } | 299 | } |
| 301 | 300 | ||
| 302 | static void | 301 | static void |
| @@ -308,14 +307,16 @@ ptable_update(PruneData *pd, Cube cube, int n) | |||
| 308 | static void | 307 | static void |
| 309 | ptable_update_index(PruneData *pd, uint64_t ind, int n) | 308 | ptable_update_index(PruneData *pd, uint64_t ind, int n) |
| 310 | { | 309 | { |
| 311 | uint8_t oldval2; | 310 | int sh; |
| 312 | int other; | 311 | entry_group_t mask; |
| 312 | uint64_t i; | ||
| 313 | 313 | ||
| 314 | oldval2 = pd->ptable[ind/2]; | 314 | sh = 4 * (ind % ENTRIES_PER_GROUP); |
| 315 | other = (ind % 2) ? oldval2 % 16 : oldval2 / 16; | 315 | mask = ((entry_group_t)15) << sh; |
| 316 | i = ind/ENTRIES_PER_GROUP; | ||
| 316 | 317 | ||
| 317 | pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n; | 318 | pd->ptable[i] &= ~mask; |
| 318 | /*pd->n++;*/ | 319 | pd->ptable[i] |= (((entry_group_t)n)&15) << sh; |
| 319 | } | 320 | } |
| 320 | 321 | ||
| 321 | int | 322 | int |
| @@ -327,6 +328,10 @@ ptableval(PruneData *pd, Cube cube) | |||
| 327 | static int | 328 | static int |
| 328 | ptableval_index(PruneData *pd, uint64_t ind) | 329 | ptableval_index(PruneData *pd, uint64_t ind) |
| 329 | { | 330 | { |
| 331 | int sh; | ||
| 332 | entry_group_t mask; | ||
| 333 | uint64_t i; | ||
| 334 | |||
| 330 | if (!pd->generated) { | 335 | if (!pd->generated) { |
| 331 | fprintf(stderr, "Warning: request pruning table value" | 336 | fprintf(stderr, "Warning: request pruning table value" |
| 332 | " for uninitialized table %s.\n It's fine, but it" | 337 | " for uninitialized table %s.\n It's fine, but it" |
| @@ -335,7 +340,11 @@ ptableval_index(PruneData *pd, uint64_t ind) | |||
| 335 | genptable(pd, 1); /* TODO: set default or remove this case */ | 340 | genptable(pd, 1); /* TODO: set default or remove this case */ |
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16; | 343 | sh = 4 * (ind % ENTRIES_PER_GROUP); |
| 344 | mask = ((entry_group_t)15) << sh; | ||
| 345 | i = ind/ENTRIES_PER_GROUP; | ||
| 346 | |||
| 347 | return (pd->ptable[i] & mask) >> sh; | ||
| 339 | } | 348 | } |
| 340 | 349 | ||
| 341 | static bool | 350 | static bool |
| @@ -354,7 +363,7 @@ read_ptable_file(PruneData *pd) | |||
| 354 | if ((f = fopen(fname, "rb")) == NULL) | 363 | if ((f = fopen(fname, "rb")) == NULL) |
| 355 | return false; | 364 | return false; |
| 356 | 365 | ||
| 357 | r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f); | 366 | r = fread(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); |
| 358 | fclose(f); | 367 | fclose(f); |
| 359 | 368 | ||
| 360 | return r == ptablesize(pd); | 369 | return r == ptablesize(pd); |
| @@ -376,7 +385,7 @@ write_ptable_file(PruneData *pd) | |||
| 376 | if ((f = fopen(fname, "wb")) == NULL) | 385 | if ((f = fopen(fname, "wb")) == NULL) |
| 377 | return false; | 386 | return false; |
| 378 | 387 | ||
| 379 | written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f); | 388 | written = fwrite(pd->ptable, sizeof(entry_group_t), ptablesize(pd), f); |
| 380 | fclose(f); | 389 | fclose(f); |
| 381 | 390 | ||
| 382 | return written == ptablesize(pd); | 391 | return written == ptablesize(pd); |
diff --git a/src/pruning.h b/src/pruning.h index da9e58a..0f20384 100644 --- a/src/pruning.h +++ b/src/pruning.h | |||
| @@ -15,6 +15,7 @@ extern PruneData pd_drudfin_noE_sym16_drud; | |||
| 15 | extern PruneData pd_htr_drud; | 15 | extern PruneData pd_htr_drud; |
| 16 | extern PruneData pd_htrfin_htr; | 16 | extern PruneData pd_htrfin_htr; |
| 17 | extern PruneData pd_khuge_HTM; | 17 | extern PruneData pd_khuge_HTM; |
| 18 | extern PruneData pd_nxopt31_HTM; | ||
| 18 | 19 | ||
| 19 | extern PruneData * allpd[NPTABLES]; | 20 | extern PruneData * allpd[NPTABLES]; |
| 20 | 21 | ||
diff --git a/src/solve.c b/src/solve.c index ea3b7ae..a8f9001 100644 --- a/src/solve.c +++ b/src/solve.c | |||
| @@ -8,7 +8,7 @@ static void copy_dfsarg(DfsArg *src, DfsArg *dst); | |||
| 8 | static void dfs(DfsArg *arg); | 8 | static void dfs(DfsArg *arg); |
| 9 | static void dfs_branch(DfsArg *arg); | 9 | static void dfs_branch(DfsArg *arg); |
| 10 | static bool dfs_check_solved(DfsArg *arg); | 10 | static bool dfs_check_solved(DfsArg *arg); |
| 11 | static bool dfs_switch_final(DfsArg *arg); | 11 | static bool dfs_switch(DfsArg *arg); |
| 12 | static void dfs_niss(DfsArg *arg); | 12 | static void dfs_niss(DfsArg *arg); |
| 13 | static bool dfs_stop(DfsArg *arg); | 13 | static bool dfs_stop(DfsArg *arg); |
| 14 | static void * instance_thread(void *arg); | 14 | static void * instance_thread(void *arg); |
| @@ -21,25 +21,43 @@ static bool niss_makes_sense(DfsArg *arg); | |||
| 21 | static bool | 21 | static bool |
| 22 | allowed_next(Move m, DfsArg *arg) | 22 | allowed_next(Move m, DfsArg *arg) |
| 23 | { | 23 | { |
| 24 | if ((1 << m) & arg->badmoves) | 24 | bool bad, allowed, order; |
| 25 | return false; | 25 | uint64_t mbit; |
| 26 | 26 | ||
| 27 | if (!possible_next(arg->last2, arg->last1, m)) | 27 | if (arg->last1 == NULLMOVE) |
| 28 | return false; | 28 | return true; |
| 29 | 29 | ||
| 30 | if (commute(arg->last1, m)) | 30 | mbit = ((uint64_t)1) << m; |
| 31 | return arg->move_position[arg->last1] < arg->move_position[m]; | 31 | bad = mbit & arg->badmoves; |
| 32 | allowed = mbit & arg->step->moveset->mask[arg->last2][arg->last1]; | ||
| 33 | order = !commute(arg->last1, m) || arg->last1 < m; | ||
| 32 | 34 | ||
| 33 | return true; | 35 | return allowed && !bad && order; |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | static bool | 38 | static bool |
| 37 | cancel_niss(DfsArg *arg) | 39 | cancel_niss(DfsArg *arg) |
| 38 | { | 40 | { |
| 39 | return !possible_next(arg->last2, arg->last1, arg->last1inv) && | 41 | Moveset *ms; |
| 40 | !(commute(arg->last1inv, arg->last2inv) && | 42 | Move i1, i2; |
| 41 | arg->last2inv != NULLMOVE && | 43 | bool p, p1, p2, q, q1, q2; |
| 42 | possible_next(arg->last2, arg->last1, arg->last2inv)); | 44 | |
| 45 | if (arg->last1inv == NULLMOVE) | ||
| 46 | return false; | ||
| 47 | |||
| 48 | ms = arg->step->moveset; | ||
| 49 | i1 = inverse_move(arg->last1inv); | ||
| 50 | i2 = inverse_move(arg->last2inv); | ||
| 51 | |||
| 52 | p1 = !ms->allowed_next(arg->last2, arg->last1, i1); | ||
| 53 | p2 = !ms->allowed_next(arg->last2, i1, arg->last1); | ||
| 54 | p = p1 || (commute(i1, arg->last1) && p2); | ||
| 55 | |||
| 56 | q1 = !ms->allowed_next(arg->last2, arg->last1, i2); | ||
| 57 | q2 = !ms->allowed_next(arg->last2, i2, arg->last1); | ||
| 58 | q = q1 || (commute(i2, arg->last1) && q2); | ||
| 59 | |||
| 60 | return p || (commute(i1, i2) && q); | ||
| 43 | } | 61 | } |
| 44 | 62 | ||
| 45 | static void | 63 | static void |
| @@ -60,8 +78,6 @@ copy_dfsarg(DfsArg *src, DfsArg *dst) | |||
| 60 | dst->sols = src->sols; | 78 | dst->sols = src->sols; |
| 61 | dst->sols_mutex = src->sols_mutex; | 79 | dst->sols_mutex = src->sols_mutex; |
| 62 | dst->current_alg = src->current_alg; | 80 | dst->current_alg = src->current_alg; |
| 63 | dst->sorted_moves = src->sorted_moves; | ||
| 64 | dst->move_position = src->move_position; | ||
| 65 | 81 | ||
| 66 | copy_estimatedata(src->ed, dst->ed); | 82 | copy_estimatedata(src->ed, dst->ed); |
| 67 | } | 83 | } |
| @@ -77,7 +93,7 @@ dfs(DfsArg *arg) | |||
| 77 | if (dfs_check_solved(arg)) | 93 | if (dfs_check_solved(arg)) |
| 78 | return; | 94 | return; |
| 79 | 95 | ||
| 80 | if (arg->step->final && (sw = dfs_switch_final(arg))) | 96 | if (arg->step->final && (sw = dfs_switch(arg))) |
| 81 | invert_branch(arg); | 97 | invert_branch(arg); |
| 82 | dfs_branch(arg); | 98 | dfs_branch(arg); |
| 83 | 99 | ||
| @@ -98,8 +114,8 @@ dfs_branch(DfsArg *arg) | |||
| 98 | newarg = malloc(sizeof(DfsArg)); | 114 | newarg = malloc(sizeof(DfsArg)); |
| 99 | newarg->ed = malloc(sizeof(EstimateData)); | 115 | newarg->ed = malloc(sizeof(EstimateData)); |
| 100 | 116 | ||
| 101 | for (i = 0; arg->sorted_moves[i] != NULLMOVE; i++) { | 117 | for (i = 0; arg->step->moveset->sorted_moves[i] != NULLMOVE; i++) { |
| 102 | m = arg->sorted_moves[i]; | 118 | m = arg->step->moveset->sorted_moves[i]; |
| 103 | if (allowed_next(m, arg)) { | 119 | if (allowed_next(m, arg)) { |
| 104 | copy_dfsarg(arg, newarg); | 120 | copy_dfsarg(arg, newarg); |
| 105 | newarg->last2 = arg->last1; | 121 | newarg->last2 = arg->last1; |
| @@ -181,20 +197,22 @@ dfs_stop(DfsArg *arg) | |||
| 181 | } | 197 | } |
| 182 | 198 | ||
| 183 | static bool | 199 | static bool |
| 184 | dfs_switch_final(DfsArg *arg) | 200 | dfs_switch(DfsArg *arg) |
| 185 | { | 201 | { |
| 186 | int i, bn, bi; | 202 | int i, bn, bi; |
| 187 | 203 | ||
| 188 | for (bn = 0, i = 0; arg->sorted_moves[i] != NULLMOVE; i++) | 204 | bn = 0; |
| 189 | if (allowed_next(arg->sorted_moves[i], arg)) | 205 | for (i = 0; arg->step->moveset->sorted_moves[i] != NULLMOVE; i++) |
| 206 | if (allowed_next(arg->step->moveset->sorted_moves[i], arg)) | ||
| 190 | bn++; | 207 | bn++; |
| 191 | 208 | ||
| 192 | swapmove(&(arg->last1), &(arg->last1inv)); | 209 | swapmove(&(arg->last1), &(arg->last1inv)); |
| 193 | swapmove(&(arg->last2), &(arg->last2inv)); | 210 | swapmove(&(arg->last2), &(arg->last2inv)); |
| 194 | swapu64(&(arg->badmoves), &(arg->badmovesinv)); | 211 | swapu64(&(arg->badmoves), &(arg->badmovesinv)); |
| 195 | 212 | ||
| 196 | for (bi = 0, i = 0; arg->sorted_moves[i] != NULLMOVE; i++) | 213 | bi = 0; |
| 197 | if (allowed_next(arg->sorted_moves[i], arg)) | 214 | for (i = 0; arg->step->moveset->sorted_moves[i] != NULLMOVE; i++) |
| 215 | if (allowed_next(arg->step->moveset->sorted_moves[i], arg)) | ||
| 198 | bi++; | 216 | bi++; |
| 199 | 217 | ||
| 200 | swapmove(&(arg->last1), &(arg->last1inv)); | 218 | swapmove(&(arg->last1), &(arg->last1inv)); |
| @@ -246,8 +264,6 @@ instance_thread(void *arg) | |||
| 246 | darg.current_alg = new_alg(""); | 264 | darg.current_alg = new_alg(""); |
| 247 | append_move(darg.current_alg, node->alg->move[0], | 265 | append_move(darg.current_alg, node->alg->move[0], |
| 248 | node->alg->inv[0]); | 266 | node->alg->inv[0]); |
| 249 | darg.sorted_moves = td->sorted_moves; | ||
| 250 | darg.move_position = td->move_position; | ||
| 251 | darg.ed = new_estimatedata(); | 267 | darg.ed = new_estimatedata(); |
| 252 | darg.badmoves = 0; | 268 | darg.badmoves = 0; |
| 253 | darg.badmovesinv = 0; | 269 | darg.badmovesinv = 0; |
| @@ -281,8 +297,7 @@ invert_branch(DfsArg *arg) | |||
| 281 | static void | 297 | static void |
| 282 | multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | 298 | multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) |
| 283 | { | 299 | { |
| 284 | int i, *move_position; | 300 | int i; |
| 285 | Move *sorted_moves; | ||
| 286 | Alg *alg; | 301 | Alg *alg; |
| 287 | AlgList *start; | 302 | AlgList *start; |
| 288 | AlgListNode **node; | 303 | AlgListNode **node; |
| @@ -290,8 +305,6 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 290 | ThreadDataSolve td[opts->nthreads]; | 305 | ThreadDataSolve td[opts->nthreads]; |
| 291 | pthread_mutex_t *start_mutex, *sols_mutex; | 306 | pthread_mutex_t *start_mutex, *sols_mutex; |
| 292 | 307 | ||
| 293 | move_position = malloc(NMOVES * sizeof(int)); | ||
| 294 | sorted_moves = malloc(NMOVES * sizeof(Move)); | ||
| 295 | node = malloc(sizeof(AlgListNode *)); | 308 | node = malloc(sizeof(AlgListNode *)); |
| 296 | start_mutex = malloc(sizeof(pthread_mutex_t)); | 309 | start_mutex = malloc(sizeof(pthread_mutex_t)); |
| 297 | sols_mutex = malloc(sizeof(pthread_mutex_t)); | 310 | sols_mutex = malloc(sizeof(pthread_mutex_t)); |
| @@ -300,14 +313,11 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 300 | pthread_mutex_init(start_mutex, NULL); | 313 | pthread_mutex_init(start_mutex, NULL); |
| 301 | pthread_mutex_init(sols_mutex, NULL); | 314 | pthread_mutex_init(sols_mutex, NULL); |
| 302 | 315 | ||
| 303 | moveset_to_list(s->moveset, sorted_moves); | 316 | for (i = 0; s->moveset->sorted_moves[i] != NULLMOVE; i++) { |
| 304 | movelist_to_position(sorted_moves, move_position); | ||
| 305 | |||
| 306 | for (i = 0; sorted_moves[i] != NULLMOVE; i++) { | ||
| 307 | alg = new_alg(""); | 317 | alg = new_alg(""); |
| 308 | /* TODO: start on inverse also in case of final step | 318 | /* TODO: start on inverse also in case of final step |
| 309 | and ed->sw true */ | 319 | and ed->sw true */ |
| 310 | append_move(alg, sorted_moves[i], false); | 320 | append_move(alg, s->moveset->sorted_moves[i], false); |
| 311 | append_alg(start, alg); | 321 | append_alg(start, alg); |
| 312 | if (opts->can_niss) { | 322 | if (opts->can_niss) { |
| 313 | alg->inv[0] = true; | 323 | alg->inv[0] = true; |
| @@ -322,8 +332,6 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 322 | td[i].cube = c; | 332 | td[i].cube = c; |
| 323 | td[i].step = s; | 333 | td[i].step = s; |
| 324 | td[i].depth = d; | 334 | td[i].depth = d; |
| 325 | td[i].sorted_moves = sorted_moves; | ||
| 326 | td[i].move_position = move_position; | ||
| 327 | td[i].opts = opts; | 335 | td[i].opts = opts; |
| 328 | td[i].start = start; | 336 | td[i].start = start; |
| 329 | td[i].node = node; | 337 | td[i].node = node; |
| @@ -340,8 +348,6 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 340 | free(node); | 348 | free(node); |
| 341 | free(start_mutex); | 349 | free(start_mutex); |
| 342 | free(sols_mutex); | 350 | free(sols_mutex); |
| 343 | free(move_position); | ||
| 344 | free(sorted_moves); | ||
| 345 | } | 351 | } |
| 346 | 352 | ||
| 347 | static bool | 353 | static bool |
diff --git a/src/steps.c b/src/steps.c index c4d1279..014b206 100644 --- a/src/steps.c +++ b/src/steps.c | |||
| @@ -36,8 +36,11 @@ static int estimate_drudfin_drud(DfsArg *arg); | |||
| 36 | static int estimate_htr_drud(DfsArg *arg); | 36 | static int estimate_htr_drud(DfsArg *arg); |
| 37 | static int estimate_htrfin_htr(DfsArg *arg); | 37 | static int estimate_htrfin_htr(DfsArg *arg); |
| 38 | static int estimate_optimal_HTM(DfsArg *arg); | 38 | static int estimate_optimal_HTM(DfsArg *arg); |
| 39 | static int estimate_nxopt31_HTM(DfsArg *arg); | ||
| 39 | static int estimate_light_HTM(DfsArg *arg); | 40 | static int estimate_light_HTM(DfsArg *arg); |
| 40 | 41 | ||
| 42 | static int estimate_nxoptlike(DfsArg *arg, PruneData *pd); | ||
| 43 | |||
| 41 | static bool always_valid(Alg *alg); | 44 | static bool always_valid(Alg *alg); |
| 42 | static bool validate_singlecw_ending(Alg *alg); | 45 | static bool validate_singlecw_ending(Alg *alg); |
| 43 | 46 | ||
| @@ -68,7 +71,7 @@ optimal_HTM = { | |||
| 68 | .ready = check_centers, | 71 | .ready = check_centers, |
| 69 | .ready_msg = check_centers_msg, | 72 | .ready_msg = check_centers_msg, |
| 70 | .is_valid = always_valid, | 73 | .is_valid = always_valid, |
| 71 | .moveset = moveset_HTM, | 74 | .moveset = &moveset_HTM, |
| 72 | 75 | ||
| 73 | .pre_trans = uf, | 76 | .pre_trans = uf, |
| 74 | 77 | ||
| @@ -77,6 +80,25 @@ optimal_HTM = { | |||
| 77 | }; | 80 | }; |
| 78 | 81 | ||
| 79 | Step | 82 | Step |
| 83 | optimal_nxopt31_HTM = { | ||
| 84 | .shortname = "nxopt31", | ||
| 85 | .name = "Optimal solve (in HTM), nxopt31 table", | ||
| 86 | |||
| 87 | .final = true, | ||
| 88 | .is_done = is_solved, | ||
| 89 | .estimate = estimate_nxopt31_HTM, | ||
| 90 | .ready = check_centers, | ||
| 91 | .ready_msg = check_centers_msg, | ||
| 92 | .is_valid = always_valid, | ||
| 93 | .moveset = &moveset_HTM, | ||
| 94 | |||
| 95 | .pre_trans = uf, | ||
| 96 | |||
| 97 | .tables = {&pd_nxopt31_HTM, &pd_corners_HTM}, | ||
| 98 | .ntables = 2, | ||
| 99 | }; | ||
| 100 | |||
| 101 | Step | ||
| 80 | optimal_light_HTM = { | 102 | optimal_light_HTM = { |
| 81 | .shortname = "light", | 103 | .shortname = "light", |
| 82 | .name = "Optimal solve (in HTM), small table (500Mb RAM total)", | 104 | .name = "Optimal solve (in HTM), small table (500Mb RAM total)", |
| @@ -87,7 +109,7 @@ optimal_light_HTM = { | |||
| 87 | .ready = check_centers, | 109 | .ready = check_centers, |
| 88 | .ready_msg = check_centers_msg, | 110 | .ready_msg = check_centers_msg, |
| 89 | .is_valid = always_valid, | 111 | .is_valid = always_valid, |
| 90 | .moveset = moveset_HTM, | 112 | .moveset = &moveset_HTM, |
| 91 | 113 | ||
| 92 | .pre_trans = uf, | 114 | .pre_trans = uf, |
| 93 | 115 | ||
| @@ -107,7 +129,7 @@ eoany_HTM = { | |||
| 107 | .ready = check_centers, | 129 | .ready = check_centers, |
| 108 | .ready_msg = check_centers_msg, | 130 | .ready_msg = check_centers_msg, |
| 109 | .is_valid = validate_singlecw_ending, | 131 | .is_valid = validate_singlecw_ending, |
| 110 | .moveset = moveset_HTM, | 132 | .moveset = &moveset_HTM, |
| 111 | 133 | ||
| 112 | .pre_trans = uf, | 134 | .pre_trans = uf, |
| 113 | 135 | ||
| @@ -126,7 +148,7 @@ eofb_HTM = { | |||
| 126 | .ready = check_centers, | 148 | .ready = check_centers, |
| 127 | .ready_msg = check_centers_msg, | 149 | .ready_msg = check_centers_msg, |
| 128 | .is_valid = validate_singlecw_ending, | 150 | .is_valid = validate_singlecw_ending, |
| 129 | .moveset = moveset_HTM, | 151 | .moveset = &moveset_HTM, |
| 130 | 152 | ||
| 131 | .pre_trans = uf, | 153 | .pre_trans = uf, |
| 132 | 154 | ||
| @@ -145,7 +167,7 @@ eorl_HTM = { | |||
| 145 | .ready = check_centers, | 167 | .ready = check_centers, |
| 146 | .ready_msg = check_centers_msg, | 168 | .ready_msg = check_centers_msg, |
| 147 | .is_valid = validate_singlecw_ending, | 169 | .is_valid = validate_singlecw_ending, |
| 148 | .moveset = moveset_HTM, | 170 | .moveset = &moveset_HTM, |
| 149 | 171 | ||
| 150 | .pre_trans = ur, | 172 | .pre_trans = ur, |
| 151 | 173 | ||
| @@ -164,7 +186,7 @@ eoud_HTM = { | |||
| 164 | .ready = check_centers, | 186 | .ready = check_centers, |
| 165 | .ready_msg = check_centers_msg, | 187 | .ready_msg = check_centers_msg, |
| 166 | .is_valid = validate_singlecw_ending, | 188 | .is_valid = validate_singlecw_ending, |
| 167 | .moveset = moveset_HTM, | 189 | .moveset = &moveset_HTM, |
| 168 | 190 | ||
| 169 | .pre_trans = fd, | 191 | .pre_trans = fd, |
| 170 | 192 | ||
| @@ -183,7 +205,7 @@ coany_HTM = { | |||
| 183 | .estimate = estimate_coany_HTM, | 205 | .estimate = estimate_coany_HTM, |
| 184 | .ready = NULL, | 206 | .ready = NULL, |
| 185 | .is_valid = validate_singlecw_ending, | 207 | .is_valid = validate_singlecw_ending, |
| 186 | .moveset = moveset_HTM, | 208 | .moveset = &moveset_HTM, |
| 187 | 209 | ||
| 188 | .pre_trans = uf, | 210 | .pre_trans = uf, |
| 189 | 211 | ||
| @@ -201,7 +223,7 @@ coud_HTM = { | |||
| 201 | .estimate = estimate_coud_HTM, | 223 | .estimate = estimate_coud_HTM, |
| 202 | .ready = NULL, | 224 | .ready = NULL, |
| 203 | .is_valid = validate_singlecw_ending, | 225 | .is_valid = validate_singlecw_ending, |
| 204 | .moveset = moveset_HTM, | 226 | .moveset = &moveset_HTM, |
| 205 | 227 | ||
| 206 | .pre_trans = uf, | 228 | .pre_trans = uf, |
| 207 | 229 | ||
| @@ -219,7 +241,7 @@ corl_HTM = { | |||
| 219 | .estimate = estimate_coud_HTM, | 241 | .estimate = estimate_coud_HTM, |
| 220 | .ready = NULL, | 242 | .ready = NULL, |
| 221 | .is_valid = validate_singlecw_ending, | 243 | .is_valid = validate_singlecw_ending, |
| 222 | .moveset = moveset_HTM, | 244 | .moveset = &moveset_HTM, |
| 223 | 245 | ||
| 224 | .pre_trans = rf, | 246 | .pre_trans = rf, |
| 225 | 247 | ||
| @@ -237,7 +259,7 @@ cofb_HTM = { | |||
| 237 | .estimate = estimate_coud_HTM, | 259 | .estimate = estimate_coud_HTM, |
| 238 | .ready = NULL, | 260 | .ready = NULL, |
| 239 | .is_valid = validate_singlecw_ending, | 261 | .is_valid = validate_singlecw_ending, |
| 240 | .moveset = moveset_HTM, | 262 | .moveset = &moveset_HTM, |
| 241 | 263 | ||
| 242 | .pre_trans = fd, | 264 | .pre_trans = fd, |
| 243 | 265 | ||
| @@ -255,7 +277,7 @@ coany_URF = { | |||
| 255 | .estimate = estimate_coany_URF, | 277 | .estimate = estimate_coany_URF, |
| 256 | .ready = NULL, | 278 | .ready = NULL, |
| 257 | .is_valid = validate_singlecw_ending, | 279 | .is_valid = validate_singlecw_ending, |
| 258 | .moveset = moveset_URF, | 280 | .moveset = &moveset_URF, |
| 259 | 281 | ||
| 260 | .pre_trans = uf, | 282 | .pre_trans = uf, |
| 261 | 283 | ||
| @@ -273,7 +295,7 @@ coud_URF = { | |||
| 273 | .estimate = estimate_coud_URF, | 295 | .estimate = estimate_coud_URF, |
| 274 | .ready = NULL, | 296 | .ready = NULL, |
| 275 | .is_valid = validate_singlecw_ending, | 297 | .is_valid = validate_singlecw_ending, |
| 276 | .moveset = moveset_URF, | 298 | .moveset = &moveset_URF, |
| 277 | 299 | ||
| 278 | .pre_trans = uf, | 300 | .pre_trans = uf, |
| 279 | 301 | ||
| @@ -291,7 +313,7 @@ corl_URF = { | |||
| 291 | .estimate = estimate_coud_URF, | 313 | .estimate = estimate_coud_URF, |
| 292 | .ready = NULL, | 314 | .ready = NULL, |
| 293 | .is_valid = validate_singlecw_ending, | 315 | .is_valid = validate_singlecw_ending, |
| 294 | .moveset = moveset_URF, | 316 | .moveset = &moveset_URF, |
| 295 | 317 | ||
| 296 | .pre_trans = rf, | 318 | .pre_trans = rf, |
| 297 | 319 | ||
| @@ -309,7 +331,7 @@ cofb_URF = { | |||
| 309 | .estimate = estimate_coud_URF, | 331 | .estimate = estimate_coud_URF, |
| 310 | .ready = NULL, | 332 | .ready = NULL, |
| 311 | .is_valid = validate_singlecw_ending, | 333 | .is_valid = validate_singlecw_ending, |
| 312 | .moveset = moveset_URF, | 334 | .moveset = &moveset_URF, |
| 313 | 335 | ||
| 314 | .pre_trans = fd, | 336 | .pre_trans = fd, |
| 315 | 337 | ||
| @@ -328,7 +350,7 @@ cornershtr_HTM = { | |||
| 328 | .estimate = estimate_cornershtr_HTM, | 350 | .estimate = estimate_cornershtr_HTM, |
| 329 | .ready = NULL, | 351 | .ready = NULL, |
| 330 | .is_valid = validate_singlecw_ending, | 352 | .is_valid = validate_singlecw_ending, |
| 331 | .moveset = moveset_HTM, | 353 | .moveset = &moveset_HTM, |
| 332 | 354 | ||
| 333 | .pre_trans = uf, | 355 | .pre_trans = uf, |
| 334 | 356 | ||
| @@ -346,7 +368,7 @@ cornershtr_URF = { | |||
| 346 | .estimate = estimate_cornershtr_URF, | 368 | .estimate = estimate_cornershtr_URF, |
| 347 | .ready = NULL, | 369 | .ready = NULL, |
| 348 | .is_valid = validate_singlecw_ending, | 370 | .is_valid = validate_singlecw_ending, |
| 349 | .moveset = moveset_URF, | 371 | .moveset = &moveset_URF, |
| 350 | 372 | ||
| 351 | .pre_trans = uf, | 373 | .pre_trans = uf, |
| 352 | 374 | ||
| @@ -364,7 +386,7 @@ corners_HTM = { | |||
| 364 | .estimate = estimate_corners_HTM, | 386 | .estimate = estimate_corners_HTM, |
| 365 | .ready = NULL, | 387 | .ready = NULL, |
| 366 | .is_valid = always_valid, | 388 | .is_valid = always_valid, |
| 367 | .moveset = moveset_HTM, | 389 | .moveset = &moveset_HTM, |
| 368 | 390 | ||
| 369 | .pre_trans = uf, | 391 | .pre_trans = uf, |
| 370 | 392 | ||
| @@ -382,7 +404,7 @@ corners_URF = { | |||
| 382 | .estimate = estimate_corners_URF, | 404 | .estimate = estimate_corners_URF, |
| 383 | .ready = NULL, | 405 | .ready = NULL, |
| 384 | .is_valid = always_valid, | 406 | .is_valid = always_valid, |
| 385 | .moveset = moveset_URF, | 407 | .moveset = &moveset_URF, |
| 386 | 408 | ||
| 387 | .pre_trans = uf, | 409 | .pre_trans = uf, |
| 388 | 410 | ||
| @@ -402,7 +424,7 @@ drany_HTM = { | |||
| 402 | .ready = check_centers, | 424 | .ready = check_centers, |
| 403 | .ready_msg = check_centers_msg, | 425 | .ready_msg = check_centers_msg, |
| 404 | .is_valid = validate_singlecw_ending, | 426 | .is_valid = validate_singlecw_ending, |
| 405 | .moveset = moveset_HTM, | 427 | .moveset = &moveset_HTM, |
| 406 | 428 | ||
| 407 | .pre_trans = uf, | 429 | .pre_trans = uf, |
| 408 | 430 | ||
| @@ -421,7 +443,7 @@ drud_HTM = { | |||
| 421 | .ready = check_centers, | 443 | .ready = check_centers, |
| 422 | .ready_msg = check_centers_msg, | 444 | .ready_msg = check_centers_msg, |
| 423 | .is_valid = validate_singlecw_ending, | 445 | .is_valid = validate_singlecw_ending, |
| 424 | .moveset = moveset_HTM, | 446 | .moveset = &moveset_HTM, |
| 425 | 447 | ||
| 426 | .pre_trans = uf, | 448 | .pre_trans = uf, |
| 427 | 449 | ||
| @@ -440,7 +462,7 @@ drrl_HTM = { | |||
| 440 | .ready = check_centers, | 462 | .ready = check_centers, |
| 441 | .ready_msg = check_centers_msg, | 463 | .ready_msg = check_centers_msg, |
| 442 | .is_valid = validate_singlecw_ending, | 464 | .is_valid = validate_singlecw_ending, |
| 443 | .moveset = moveset_HTM, | 465 | .moveset = &moveset_HTM, |
| 444 | 466 | ||
| 445 | .pre_trans = rf, | 467 | .pre_trans = rf, |
| 446 | 468 | ||
| @@ -459,7 +481,7 @@ drfb_HTM = { | |||
| 459 | .ready = check_centers, | 481 | .ready = check_centers, |
| 460 | .ready_msg = check_centers_msg, | 482 | .ready_msg = check_centers_msg, |
| 461 | .is_valid = validate_singlecw_ending, | 483 | .is_valid = validate_singlecw_ending, |
| 462 | .moveset = moveset_HTM, | 484 | .moveset = &moveset_HTM, |
| 463 | 485 | ||
| 464 | .pre_trans = fd, | 486 | .pre_trans = fd, |
| 465 | 487 | ||
| @@ -479,7 +501,7 @@ dr_eo = { | |||
| 479 | .ready = check_eofb, | 501 | .ready = check_eofb, |
| 480 | .ready_msg = check_eo_msg, | 502 | .ready_msg = check_eo_msg, |
| 481 | .is_valid = validate_singlecw_ending, | 503 | .is_valid = validate_singlecw_ending, |
| 482 | .moveset = moveset_eofb, | 504 | .moveset = &moveset_eofb, |
| 483 | 505 | ||
| 484 | .detect = detect_pretrans_eofb, | 506 | .detect = detect_pretrans_eofb, |
| 485 | 507 | ||
| @@ -498,7 +520,7 @@ dr_eofb = { | |||
| 498 | .ready = check_eofb, | 520 | .ready = check_eofb, |
| 499 | .ready_msg = check_eo_msg, | 521 | .ready_msg = check_eo_msg, |
| 500 | .is_valid = validate_singlecw_ending, | 522 | .is_valid = validate_singlecw_ending, |
| 501 | .moveset = moveset_eofb, | 523 | .moveset = &moveset_eofb, |
| 502 | 524 | ||
| 503 | .pre_trans = uf, | 525 | .pre_trans = uf, |
| 504 | 526 | ||
| @@ -517,7 +539,7 @@ dr_eorl = { | |||
| 517 | .ready = check_eofb, | 539 | .ready = check_eofb, |
| 518 | .ready_msg = check_eo_msg, | 540 | .ready_msg = check_eo_msg, |
| 519 | .is_valid = validate_singlecw_ending, | 541 | .is_valid = validate_singlecw_ending, |
| 520 | .moveset = moveset_eofb, | 542 | .moveset = &moveset_eofb, |
| 521 | 543 | ||
| 522 | .pre_trans = ur, | 544 | .pre_trans = ur, |
| 523 | 545 | ||
| @@ -536,7 +558,7 @@ dr_eoud = { | |||
| 536 | .ready = check_eofb, | 558 | .ready = check_eofb, |
| 537 | .ready_msg = check_eo_msg, | 559 | .ready_msg = check_eo_msg, |
| 538 | .is_valid = validate_singlecw_ending, | 560 | .is_valid = validate_singlecw_ending, |
| 539 | .moveset = moveset_eofb, | 561 | .moveset = &moveset_eofb, |
| 540 | 562 | ||
| 541 | .pre_trans = fd, | 563 | .pre_trans = fd, |
| 542 | 564 | ||
| @@ -555,7 +577,7 @@ drud_eofb = { | |||
| 555 | .ready = check_eofb, | 577 | .ready = check_eofb, |
| 556 | .ready_msg = check_eo_msg, | 578 | .ready_msg = check_eo_msg, |
| 557 | .is_valid = validate_singlecw_ending, | 579 | .is_valid = validate_singlecw_ending, |
| 558 | .moveset = moveset_eofb, | 580 | .moveset = &moveset_eofb, |
| 559 | 581 | ||
| 560 | .pre_trans = uf, | 582 | .pre_trans = uf, |
| 561 | 583 | ||
| @@ -574,7 +596,7 @@ drrl_eofb = { | |||
| 574 | .ready = check_eofb, | 596 | .ready = check_eofb, |
| 575 | .ready_msg = check_eo_msg, | 597 | .ready_msg = check_eo_msg, |
| 576 | .is_valid = validate_singlecw_ending, | 598 | .is_valid = validate_singlecw_ending, |
| 577 | .moveset = moveset_eofb, | 599 | .moveset = &moveset_eofb, |
| 578 | 600 | ||
| 579 | .pre_trans = rf, | 601 | .pre_trans = rf, |
| 580 | 602 | ||
| @@ -593,7 +615,7 @@ drud_eorl = { | |||
| 593 | .ready = check_eofb, | 615 | .ready = check_eofb, |
| 594 | .ready_msg = check_eo_msg, | 616 | .ready_msg = check_eo_msg, |
| 595 | .is_valid = validate_singlecw_ending, | 617 | .is_valid = validate_singlecw_ending, |
| 596 | .moveset = moveset_eofb, | 618 | .moveset = &moveset_eofb, |
| 597 | 619 | ||
| 598 | .pre_trans = ur, | 620 | .pre_trans = ur, |
| 599 | 621 | ||
| @@ -612,7 +634,7 @@ drfb_eorl = { | |||
| 612 | .ready = check_eofb, | 634 | .ready = check_eofb, |
| 613 | .ready_msg = check_eo_msg, | 635 | .ready_msg = check_eo_msg, |
| 614 | .is_valid = validate_singlecw_ending, | 636 | .is_valid = validate_singlecw_ending, |
| 615 | .moveset = moveset_eofb, | 637 | .moveset = &moveset_eofb, |
| 616 | 638 | ||
| 617 | .pre_trans = fr, | 639 | .pre_trans = fr, |
| 618 | 640 | ||
| @@ -631,7 +653,7 @@ drfb_eoud = { | |||
| 631 | .ready = check_eofb, | 653 | .ready = check_eofb, |
| 632 | .ready_msg = check_eo_msg, | 654 | .ready_msg = check_eo_msg, |
| 633 | .is_valid = validate_singlecw_ending, | 655 | .is_valid = validate_singlecw_ending, |
| 634 | .moveset = moveset_eofb, | 656 | .moveset = &moveset_eofb, |
| 635 | 657 | ||
| 636 | .pre_trans = fd, | 658 | .pre_trans = fd, |
| 637 | 659 | ||
| @@ -650,7 +672,7 @@ drrl_eoud = { | |||
| 650 | .ready = check_eofb, | 672 | .ready = check_eofb, |
| 651 | .ready_msg = check_eo_msg, | 673 | .ready_msg = check_eo_msg, |
| 652 | .is_valid = validate_singlecw_ending, | 674 | .is_valid = validate_singlecw_ending, |
| 653 | .moveset = moveset_eofb, | 675 | .moveset = &moveset_eofb, |
| 654 | 676 | ||
| 655 | .pre_trans = rd, | 677 | .pre_trans = rd, |
| 656 | 678 | ||
| @@ -670,7 +692,7 @@ dranyfin_DR = { | |||
| 670 | .ready = check_drud, | 692 | .ready = check_drud, |
| 671 | .ready_msg = check_drany_msg, | 693 | .ready_msg = check_drany_msg, |
| 672 | .is_valid = always_valid, | 694 | .is_valid = always_valid, |
| 673 | .moveset = moveset_drud, | 695 | .moveset = &moveset_drud, |
| 674 | 696 | ||
| 675 | .detect = detect_pretrans_drud, | 697 | .detect = detect_pretrans_drud, |
| 676 | 698 | ||
| @@ -689,7 +711,7 @@ drudfin_drud = { | |||
| 689 | .ready = check_drud, | 711 | .ready = check_drud, |
| 690 | .ready_msg = check_dr_msg, | 712 | .ready_msg = check_dr_msg, |
| 691 | .is_valid = always_valid, | 713 | .is_valid = always_valid, |
| 692 | .moveset = moveset_drud, | 714 | .moveset = &moveset_drud, |
| 693 | 715 | ||
| 694 | .pre_trans = uf, | 716 | .pre_trans = uf, |
| 695 | 717 | ||
| @@ -708,7 +730,7 @@ drrlfin_drrl = { | |||
| 708 | .ready = check_drud, | 730 | .ready = check_drud, |
| 709 | .ready_msg = check_dr_msg, | 731 | .ready_msg = check_dr_msg, |
| 710 | .is_valid = always_valid, | 732 | .is_valid = always_valid, |
| 711 | .moveset = moveset_drud, | 733 | .moveset = &moveset_drud, |
| 712 | 734 | ||
| 713 | .pre_trans = rf, | 735 | .pre_trans = rf, |
| 714 | 736 | ||
| @@ -727,7 +749,7 @@ drfbfin_drfb = { | |||
| 727 | .ready = check_drud, | 749 | .ready = check_drud, |
| 728 | .ready_msg = check_dr_msg, | 750 | .ready_msg = check_dr_msg, |
| 729 | .is_valid = always_valid, | 751 | .is_valid = always_valid, |
| 730 | .moveset = moveset_drud, | 752 | .moveset = &moveset_drud, |
| 731 | 753 | ||
| 732 | .pre_trans = fd, | 754 | .pre_trans = fd, |
| 733 | 755 | ||
| @@ -747,7 +769,7 @@ htr_any = { | |||
| 747 | .ready = check_drud, | 769 | .ready = check_drud, |
| 748 | .ready_msg = check_drany_msg, | 770 | .ready_msg = check_drany_msg, |
| 749 | .is_valid = validate_singlecw_ending, | 771 | .is_valid = validate_singlecw_ending, |
| 750 | .moveset = moveset_drud, | 772 | .moveset = &moveset_drud, |
| 751 | 773 | ||
| 752 | .detect = detect_pretrans_drud, | 774 | .detect = detect_pretrans_drud, |
| 753 | 775 | ||
| @@ -766,7 +788,7 @@ htr_drud = { | |||
| 766 | .ready = check_drud, | 788 | .ready = check_drud, |
| 767 | .ready_msg = check_dr_msg, | 789 | .ready_msg = check_dr_msg, |
| 768 | .is_valid = validate_singlecw_ending, | 790 | .is_valid = validate_singlecw_ending, |
| 769 | .moveset = moveset_drud, | 791 | .moveset = &moveset_drud, |
| 770 | 792 | ||
| 771 | .pre_trans = uf, | 793 | .pre_trans = uf, |
| 772 | 794 | ||
| @@ -785,7 +807,7 @@ htr_drrl = { | |||
| 785 | .ready = check_drud, | 807 | .ready = check_drud, |
| 786 | .ready_msg = check_dr_msg, | 808 | .ready_msg = check_dr_msg, |
| 787 | .is_valid = validate_singlecw_ending, | 809 | .is_valid = validate_singlecw_ending, |
| 788 | .moveset = moveset_drud, | 810 | .moveset = &moveset_drud, |
| 789 | 811 | ||
| 790 | .pre_trans = rf, | 812 | .pre_trans = rf, |
| 791 | 813 | ||
| @@ -804,7 +826,7 @@ htr_drfb = { | |||
| 804 | .ready = check_drud, | 826 | .ready = check_drud, |
| 805 | .ready_msg = check_dr_msg, | 827 | .ready_msg = check_dr_msg, |
| 806 | .is_valid = validate_singlecw_ending, | 828 | .is_valid = validate_singlecw_ending, |
| 807 | .moveset = moveset_drud, | 829 | .moveset = &moveset_drud, |
| 808 | 830 | ||
| 809 | .pre_trans = fd, | 831 | .pre_trans = fd, |
| 810 | 832 | ||
| @@ -824,7 +846,7 @@ htrfin_htr = { | |||
| 824 | .ready = check_htr, | 846 | .ready = check_htr, |
| 825 | .ready_msg = check_htr_msg, | 847 | .ready_msg = check_htr_msg, |
| 826 | .is_valid = always_valid, | 848 | .is_valid = always_valid, |
| 827 | .moveset = moveset_htr, | 849 | .moveset = &moveset_htr, |
| 828 | 850 | ||
| 829 | .pre_trans = uf, | 851 | .pre_trans = uf, |
| 830 | 852 | ||
| @@ -834,6 +856,7 @@ htrfin_htr = { | |||
| 834 | 856 | ||
| 835 | Step *steps[NSTEPS] = { | 857 | Step *steps[NSTEPS] = { |
| 836 | &optimal_HTM, /* first is default */ | 858 | &optimal_HTM, /* first is default */ |
| 859 | &optimal_nxopt31_HTM, | ||
| 837 | &optimal_light_HTM, | 860 | &optimal_light_HTM, |
| 838 | 861 | ||
| 839 | &eoany_HTM, | 862 | &eoany_HTM, |
| @@ -1183,6 +1206,19 @@ estimate_htrfin_htr(DfsArg *arg) | |||
| 1183 | static int | 1206 | static int |
| 1184 | estimate_optimal_HTM(DfsArg *arg) | 1207 | estimate_optimal_HTM(DfsArg *arg) |
| 1185 | { | 1208 | { |
| 1209 | return estimate_nxoptlike(arg, &pd_khuge_HTM); | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static int | ||
| 1213 | estimate_nxopt31_HTM(DfsArg *arg) | ||
| 1214 | { | ||
| 1215 | return estimate_nxoptlike(arg, &pd_nxopt31_HTM); | ||
| 1216 | } | ||
| 1217 | |||
| 1218 | /* TODO: also use generic procedure for this */ | ||
| 1219 | static int | ||
| 1220 | estimate_light_HTM(DfsArg *arg) | ||
| 1221 | { | ||
| 1186 | int target, ret; | 1222 | int target, ret; |
| 1187 | Cube aux; | 1223 | Cube aux; |
| 1188 | 1224 | ||
| @@ -1192,6 +1228,9 @@ estimate_optimal_HTM(DfsArg *arg) | |||
| 1192 | (1<<L) | (1<<L2) | (1<<L3); | 1228 | (1<<L) | (1<<L2) | (1<<L3); |
| 1193 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | | 1229 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | |
| 1194 | (1<<B) | (1<<B2) | (1<<B3); | 1230 | (1<<B) | (1<<B2) | (1<<B3); |
| 1231 | static const uint64_t htmask = (1<<U2) | (1<<D2) | | ||
| 1232 | (1<<R2) | (1<<L2) | | ||
| 1233 | (1<<F2) | (1<<B2); | ||
| 1195 | 1234 | ||
| 1196 | ret = -1; | 1235 | ret = -1; |
| 1197 | target = arg->d - arg->current_alg->len; | 1236 | target = arg->d - arg->current_alg->len; |
| @@ -1204,18 +1243,18 @@ estimate_optimal_HTM(DfsArg *arg) | |||
| 1204 | UPDATECHECKSTOP(ret, arg->ed->corners, target); | 1243 | UPDATECHECKSTOP(ret, arg->ed->corners, target); |
| 1205 | 1244 | ||
| 1206 | /* Normal probing */ | 1245 | /* Normal probing */ |
| 1207 | arg->ed->normal_ud = ptableval(&pd_khuge_HTM, arg->cube); | 1246 | arg->ed->normal_ud = ptableval(&pd_drud_sym16_HTM, arg->cube); |
| 1208 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); | 1247 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); |
| 1209 | aux = apply_trans(fd, arg->cube); | 1248 | aux = apply_trans(fd, arg->cube); |
| 1210 | arg->ed->normal_fb = ptableval(&pd_khuge_HTM, aux); | 1249 | arg->ed->normal_fb = ptableval(&pd_drud_sym16_HTM, aux); |
| 1211 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); | 1250 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); |
| 1212 | aux = apply_trans(rf, arg->cube); | 1251 | aux = apply_trans(rf, arg->cube); |
| 1213 | arg->ed->normal_rl = ptableval(&pd_khuge_HTM, aux); | 1252 | arg->ed->normal_rl = ptableval(&pd_drud_sym16_HTM, aux); |
| 1214 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); | 1253 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); |
| 1215 | 1254 | ||
| 1216 | /* If ret == 0, it's solved (corners + triple slice solved) */ | 1255 | /* If ret == 0, it's solved (corners + triple slice solved) */ |
| 1217 | if (ret == 0) | 1256 | if (ret == 0) |
| 1218 | return 0; | 1257 | return is_solved(arg->cube) ? 0 : 1; |
| 1219 | 1258 | ||
| 1220 | /* Michel de Bondt's trick*/ | 1259 | /* Michel de Bondt's trick*/ |
| 1221 | if (arg->ed->normal_ud == arg->ed->normal_fb && | 1260 | if (arg->ed->normal_ud == arg->ed->normal_fb && |
| @@ -1224,21 +1263,30 @@ estimate_optimal_HTM(DfsArg *arg) | |||
| 1224 | } | 1263 | } |
| 1225 | 1264 | ||
| 1226 | /* Inverse probing */ | 1265 | /* Inverse probing */ |
| 1227 | aux = arg->inverse = inverse_cube(arg->cube); | 1266 | if (!((1<<arg->last1) & htmask)) { |
| 1228 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud == -1)) { | 1267 | aux = arg->inverse = inverse_cube(arg->cube); |
| 1229 | arg->ed->inverse_ud = ptableval(&pd_khuge_HTM, aux); | 1268 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud==-1)) { |
| 1230 | } | 1269 | arg->ed->inverse_ud = |
| 1231 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | 1270 | ptableval(&pd_drud_sym16_HTM, aux); |
| 1232 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb == -1)) { | 1271 | } |
| 1233 | aux = apply_trans(fd, arg->inverse); | 1272 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); |
| 1234 | arg->ed->inverse_fb = ptableval(&pd_khuge_HTM, aux); | 1273 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb==-1)) { |
| 1235 | } | 1274 | aux = apply_trans(fd, arg->inverse); |
| 1236 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | 1275 | arg->ed->inverse_fb = |
| 1237 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl == -1)) { | 1276 | ptableval(&pd_drud_sym16_HTM, aux); |
| 1238 | aux = apply_trans(rf, arg->inverse); | 1277 | } |
| 1239 | arg->ed->inverse_rl = ptableval(&pd_khuge_HTM, aux); | 1278 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); |
| 1279 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl==-1)) { | ||
| 1280 | aux = apply_trans(rf, arg->inverse); | ||
| 1281 | arg->ed->inverse_rl = | ||
| 1282 | ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1283 | } | ||
| 1284 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1285 | } else { | ||
| 1286 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | ||
| 1287 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | ||
| 1288 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1240 | } | 1289 | } |
| 1241 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1242 | 1290 | ||
| 1243 | /* Michel de Bondt's trick*/ | 1291 | /* Michel de Bondt's trick*/ |
| 1244 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && | 1292 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && |
| @@ -1246,26 +1294,26 @@ estimate_optimal_HTM(DfsArg *arg) | |||
| 1246 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); | 1294 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); |
| 1247 | } | 1295 | } |
| 1248 | 1296 | ||
| 1249 | /* nxopt trick */ | 1297 | /* nxopt trick + half turn trick */ |
| 1250 | if (arg->ed->normal_ud == target) | 1298 | if (arg->ed->normal_ud == target) |
| 1251 | arg->badmovesinv |= udmask; | 1299 | arg->badmovesinv |= udmask | htmask; |
| 1252 | if (arg->ed->normal_fb == target) | 1300 | if (arg->ed->normal_fb == target) |
| 1253 | arg->badmovesinv |= fbmask; | 1301 | arg->badmovesinv |= fbmask | htmask; |
| 1254 | if (arg->ed->normal_rl == target) | 1302 | if (arg->ed->normal_rl == target) |
| 1255 | arg->badmovesinv |= rlmask; | 1303 | arg->badmovesinv |= rlmask | htmask; |
| 1256 | 1304 | ||
| 1257 | if (arg->ed->inverse_ud == target) | 1305 | if (arg->ed->inverse_ud == target) |
| 1258 | arg->badmoves |= udmask; | 1306 | arg->badmoves |= udmask | htmask; |
| 1259 | if (arg->ed->inverse_fb == target) | 1307 | if (arg->ed->inverse_fb == target) |
| 1260 | arg->badmoves |= fbmask; | 1308 | arg->badmoves |= fbmask | htmask; |
| 1261 | if (arg->ed->inverse_rl == target) | 1309 | if (arg->ed->inverse_rl == target) |
| 1262 | arg->badmoves |= rlmask; | 1310 | arg->badmoves |= rlmask | htmask; |
| 1263 | 1311 | ||
| 1264 | return arg->ed->oldret = ret; | 1312 | return arg->ed->oldret = ret; |
| 1265 | } | 1313 | } |
| 1266 | 1314 | ||
| 1267 | static int | 1315 | static int |
| 1268 | estimate_light_HTM(DfsArg *arg) | 1316 | estimate_nxoptlike(DfsArg *arg, PruneData *pd) |
| 1269 | { | 1317 | { |
| 1270 | int target, ret; | 1318 | int target, ret; |
| 1271 | Cube aux; | 1319 | Cube aux; |
| @@ -1276,9 +1324,6 @@ estimate_light_HTM(DfsArg *arg) | |||
| 1276 | (1<<L) | (1<<L2) | (1<<L3); | 1324 | (1<<L) | (1<<L2) | (1<<L3); |
| 1277 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | | 1325 | static const uint64_t fbmask = (1<<F) | (1<<F2) | (1<<F3) | |
| 1278 | (1<<B) | (1<<B2) | (1<<B3); | 1326 | (1<<B) | (1<<B2) | (1<<B3); |
| 1279 | static const uint64_t htmask = (1<<U2) | (1<<D2) | | ||
| 1280 | (1<<R2) | (1<<L2) | | ||
| 1281 | (1<<F2) | (1<<B2); | ||
| 1282 | 1327 | ||
| 1283 | ret = -1; | 1328 | ret = -1; |
| 1284 | target = arg->d - arg->current_alg->len; | 1329 | target = arg->d - arg->current_alg->len; |
| @@ -1291,18 +1336,17 @@ estimate_light_HTM(DfsArg *arg) | |||
| 1291 | UPDATECHECKSTOP(ret, arg->ed->corners, target); | 1336 | UPDATECHECKSTOP(ret, arg->ed->corners, target); |
| 1292 | 1337 | ||
| 1293 | /* Normal probing */ | 1338 | /* Normal probing */ |
| 1294 | arg->ed->normal_ud = ptableval(&pd_drud_sym16_HTM, arg->cube); | 1339 | arg->ed->normal_ud = ptableval(pd, arg->cube); |
| 1295 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); | 1340 | UPDATECHECKSTOP(ret, arg->ed->normal_ud, target); |
| 1296 | aux = apply_trans(fd, arg->cube); | 1341 | aux = apply_trans(fd, arg->cube); |
| 1297 | arg->ed->normal_fb = ptableval(&pd_drud_sym16_HTM, aux); | 1342 | arg->ed->normal_fb = ptableval(pd, aux); |
| 1298 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); | 1343 | UPDATECHECKSTOP(ret, arg->ed->normal_fb, target); |
| 1299 | aux = apply_trans(rf, arg->cube); | 1344 | aux = apply_trans(rf, arg->cube); |
| 1300 | arg->ed->normal_rl = ptableval(&pd_drud_sym16_HTM, aux); | 1345 | arg->ed->normal_rl = ptableval(pd, aux); |
| 1301 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); | 1346 | UPDATECHECKSTOP(ret, arg->ed->normal_rl, target); |
| 1302 | 1347 | ||
| 1303 | /* If ret == 0, it's solved (corners + triple slice solved) */ | ||
| 1304 | if (ret == 0) | 1348 | if (ret == 0) |
| 1305 | return 0; | 1349 | return arg->step->is_done(arg->cube) ? 0 : 1; |
| 1306 | 1350 | ||
| 1307 | /* Michel de Bondt's trick*/ | 1351 | /* Michel de Bondt's trick*/ |
| 1308 | if (arg->ed->normal_ud == arg->ed->normal_fb && | 1352 | if (arg->ed->normal_ud == arg->ed->normal_fb && |
| @@ -1311,30 +1355,21 @@ estimate_light_HTM(DfsArg *arg) | |||
| 1311 | } | 1355 | } |
| 1312 | 1356 | ||
| 1313 | /* Inverse probing */ | 1357 | /* Inverse probing */ |
| 1314 | if (!((1<<arg->last1) & htmask)) { | 1358 | aux = arg->inverse = inverse_cube(arg->cube); |
| 1315 | aux = arg->inverse = inverse_cube(arg->cube); | 1359 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud == -1)) { |
| 1316 | if (!((1<<arg->last1) & udmask) || (arg->ed->inverse_ud==-1)) { | 1360 | arg->ed->inverse_ud = ptableval(pd, aux); |
| 1317 | arg->ed->inverse_ud = | 1361 | } |
| 1318 | ptableval(&pd_drud_sym16_HTM, aux); | 1362 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); |
| 1319 | } | 1363 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb == -1)) { |
| 1320 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | 1364 | aux = apply_trans(fd, arg->inverse); |
| 1321 | if (!((1<<arg->last1) & fbmask) || (arg->ed->inverse_fb==-1)) { | 1365 | arg->ed->inverse_fb = ptableval(pd, aux); |
| 1322 | aux = apply_trans(fd, arg->inverse); | 1366 | } |
| 1323 | arg->ed->inverse_fb = | 1367 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); |
| 1324 | ptableval(&pd_drud_sym16_HTM, aux); | 1368 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl == -1)) { |
| 1325 | } | 1369 | aux = apply_trans(rf, arg->inverse); |
| 1326 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | 1370 | arg->ed->inverse_rl = ptableval(pd, aux); |
| 1327 | if (!((1<<arg->last1) & rlmask) || (arg->ed->inverse_rl==-1)) { | ||
| 1328 | aux = apply_trans(rf, arg->inverse); | ||
| 1329 | arg->ed->inverse_rl = | ||
| 1330 | ptableval(&pd_drud_sym16_HTM, aux); | ||
| 1331 | } | ||
| 1332 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1333 | } else { | ||
| 1334 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud, target); | ||
| 1335 | UPDATECHECKSTOP(ret, arg->ed->inverse_fb, target); | ||
| 1336 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1337 | } | 1371 | } |
| 1372 | UPDATECHECKSTOP(ret, arg->ed->inverse_rl, target); | ||
| 1338 | 1373 | ||
| 1339 | /* Michel de Bondt's trick*/ | 1374 | /* Michel de Bondt's trick*/ |
| 1340 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && | 1375 | if (arg->ed->inverse_ud == arg->ed->inverse_fb && |
| @@ -1342,24 +1377,25 @@ estimate_light_HTM(DfsArg *arg) | |||
| 1342 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); | 1377 | UPDATECHECKSTOP(ret, arg->ed->inverse_ud + 1, target); |
| 1343 | } | 1378 | } |
| 1344 | 1379 | ||
| 1345 | /* nxopt trick + half turn trick */ | 1380 | /* nxopt trick */ |
| 1346 | if (arg->ed->normal_ud == target) | 1381 | if (arg->ed->normal_ud == target) |
| 1347 | arg->badmovesinv |= udmask | htmask; | 1382 | arg->badmovesinv |= udmask; |
| 1348 | if (arg->ed->normal_fb == target) | 1383 | if (arg->ed->normal_fb == target) |
| 1349 | arg->badmovesinv |= fbmask | htmask; | 1384 | arg->badmovesinv |= fbmask; |
| 1350 | if (arg->ed->normal_rl == target) | 1385 | if (arg->ed->normal_rl == target) |
| 1351 | arg->badmovesinv |= rlmask | htmask; | 1386 | arg->badmovesinv |= rlmask; |
| 1352 | 1387 | ||
| 1353 | if (arg->ed->inverse_ud == target) | 1388 | if (arg->ed->inverse_ud == target) |
| 1354 | arg->badmoves |= udmask | htmask; | 1389 | arg->badmoves |= udmask; |
| 1355 | if (arg->ed->inverse_fb == target) | 1390 | if (arg->ed->inverse_fb == target) |
| 1356 | arg->badmoves |= fbmask | htmask; | 1391 | arg->badmoves |= fbmask; |
| 1357 | if (arg->ed->inverse_rl == target) | 1392 | if (arg->ed->inverse_rl == target) |
| 1358 | arg->badmoves |= rlmask | htmask; | 1393 | arg->badmoves |= rlmask; |
| 1359 | 1394 | ||
| 1360 | return arg->ed->oldret = ret; | 1395 | return arg->ed->oldret = ret; |
| 1361 | } | 1396 | } |
| 1362 | 1397 | ||
| 1398 | |||
| 1363 | static bool | 1399 | static bool |
| 1364 | always_valid(Alg *alg) | 1400 | always_valid(Alg *alg) |
| 1365 | { | 1401 | { |
diff --git a/src/symcoord.c b/src/symcoord.c index 038449a..707a84e 100644 --- a/src/symcoord.c +++ b/src/symcoord.c | |||
| @@ -4,23 +4,24 @@ | |||
| 4 | #define CLASSES_CP_16 2768 | 4 | #define CLASSES_CP_16 2768 |
| 5 | #define CLASSES_EOFBEPOS_16 64430 | 5 | #define CLASSES_EOFBEPOS_16 64430 |
| 6 | 6 | ||
| 7 | static Cube antindex_coud_sym16(uint64_t ind); | ||
| 8 | static Cube antindex_cp_sym16(uint64_t ind); | 7 | static Cube antindex_cp_sym16(uint64_t ind); |
| 9 | static Cube antindex_eofbepos_sym16(uint64_t ind); | 8 | static Cube antindex_eofbepos_sym16(uint64_t ind); |
| 10 | static Cube antindex_drud_sym16(uint64_t ind); | 9 | static Cube antindex_drud_sym16(uint64_t ind); |
| 11 | static Cube antindex_drudfin_noE_sym16(uint64_t ind); | 10 | static Cube antindex_drudfin_noE_sym16(uint64_t ind); |
| 12 | static Cube antindex_khuge(uint64_t ind); | 11 | static Cube antindex_khuge(uint64_t ind); |
| 12 | static Cube antindex_nxopt31(uint64_t ind); | ||
| 13 | 13 | ||
| 14 | static uint64_t index_coud_sym16(Cube cube); | ||
| 15 | static uint64_t index_cp_sym16(Cube cube); | 14 | static uint64_t index_cp_sym16(Cube cube); |
| 16 | static uint64_t index_eofbepos_sym16(Cube cube); | 15 | static uint64_t index_eofbepos_sym16(Cube cube); |
| 17 | static uint64_t index_drud_sym16(Cube cube); | 16 | static uint64_t index_drud_sym16(Cube cube); |
| 18 | static uint64_t index_drudfin_noE_sym16(Cube cube); | 17 | static uint64_t index_drudfin_noE_sym16(Cube cube); |
| 19 | static uint64_t index_khuge(Cube cube); | 18 | static uint64_t index_khuge(Cube cube); |
| 19 | static uint64_t index_nxopt31(Cube cube); | ||
| 20 | 20 | ||
| 21 | static int transfinder_drud_sym16(uint64_t ind, Trans *ret); | 21 | static int transfinder_drud_sym16(uint64_t ind, Trans *ret); |
| 22 | static int transfinder_drudfin_noE_sym16(uint64_t ind, Trans *ret); | 22 | static int transfinder_drudfin_noE_sym16(uint64_t ind, Trans *ret); |
| 23 | static int transfinder_khuge(uint64_t ind, Trans *ret); | 23 | static int transfinder_khuge(uint64_t ind, Trans *ret); |
| 24 | static int transfinder_nxopt31(uint64_t ind, Trans *ret); | ||
| 24 | 25 | ||
| 25 | static void gensym(SymData *sd); | 26 | static void gensym(SymData *sd); |
| 26 | static bool read_symdata_file(SymData *sd); | 27 | static bool read_symdata_file(SymData *sd); |
| @@ -38,15 +39,6 @@ trans_group_udfix[16] = { | |||
| 38 | }; | 39 | }; |
| 39 | 40 | ||
| 40 | static SymData | 41 | static SymData |
| 41 | sd_coud_16 = { | ||
| 42 | .filename = "sd_coud_16", | ||
| 43 | .coord = &coord_coud, | ||
| 44 | .sym_coord = &coord_coud_sym16, | ||
| 45 | .ntrans = 16, | ||
| 46 | .trans = trans_group_udfix | ||
| 47 | }; | ||
| 48 | |||
| 49 | static SymData | ||
| 50 | sd_cp_16 = { | 42 | sd_cp_16 = { |
| 51 | .filename = "sd_cp_16", | 43 | .filename = "sd_cp_16", |
| 52 | .coord = &coord_cp, | 44 | .coord = &coord_cp, |
| @@ -64,9 +56,8 @@ sd_eofbepos_16 = { | |||
| 64 | .trans = trans_group_udfix | 56 | .trans = trans_group_udfix |
| 65 | }; | 57 | }; |
| 66 | 58 | ||
| 67 | static int nsymdata = 3; | 59 | static int nsymdata = 2; |
| 68 | static SymData * all_sd[] = { | 60 | static SymData * all_sd[] = { |
| 69 | &sd_coud_16, | ||
| 70 | &sd_cp_16, | 61 | &sd_cp_16, |
| 71 | &sd_eofbepos_16, | 62 | &sd_eofbepos_16, |
| 72 | }; | 63 | }; |
| @@ -81,12 +72,6 @@ coord_eofbepos_sym16 = { | |||
| 81 | }; | 72 | }; |
| 82 | 73 | ||
| 83 | Coordinate | 74 | Coordinate |
| 84 | coord_coud_sym16 = { | ||
| 85 | .index = index_coud_sym16, | ||
| 86 | .cube = antindex_coud_sym16, | ||
| 87 | }; | ||
| 88 | |||
| 89 | Coordinate | ||
| 90 | coord_cp_sym16 = { | 75 | coord_cp_sym16 = { |
| 91 | .index = index_cp_sym16, | 76 | .index = index_cp_sym16, |
| 92 | .cube = antindex_cp_sym16, | 77 | .cube = antindex_cp_sym16, |
| @@ -116,13 +101,15 @@ coord_khuge = { | |||
| 116 | .trans = transfinder_khuge, | 101 | .trans = transfinder_khuge, |
| 117 | }; | 102 | }; |
| 118 | 103 | ||
| 119 | /* Functions *****************************************************************/ | 104 | Coordinate |
| 105 | coord_nxopt31 = { | ||
| 106 | .index = index_nxopt31, | ||
| 107 | .cube = antindex_nxopt31, | ||
| 108 | .max = POW3TO7 * BINOM8ON4 * CLASSES_EOFBEPOS_16 , | ||
| 109 | .trans = transfinder_nxopt31, | ||
| 110 | }; | ||
| 120 | 111 | ||
| 121 | static Cube | 112 | /* Functions *****************************************************************/ |
| 122 | antindex_coud_sym16(uint64_t ind) | ||
| 123 | { | ||
| 124 | return sd_coud_16.rep[ind]; | ||
| 125 | } | ||
| 126 | 113 | ||
| 127 | static Cube | 114 | static Cube |
| 128 | antindex_cp_sym16(uint64_t ind) | 115 | antindex_cp_sym16(uint64_t ind) |
| @@ -173,10 +160,16 @@ antindex_khuge(uint64_t ind) | |||
| 173 | return c; | 160 | return c; |
| 174 | } | 161 | } |
| 175 | 162 | ||
| 176 | static uint64_t | 163 | static Cube |
| 177 | index_coud_sym16(Cube cube) | 164 | antindex_nxopt31(uint64_t ind) |
| 178 | { | 165 | { |
| 179 | return sd_coud_16.class[coord_coud.index(cube)]; | 166 | Cube c; |
| 167 | |||
| 168 | c = antindex_eofbepos_sym16(ind/(BINOM8ON4*POW3TO7)); | ||
| 169 | c.cp = coord_cpud_separate.cube((ind/POW3TO7)%BINOM8ON4).cp; | ||
| 170 | c.coud = ind % POW3TO7; | ||
| 171 | |||
| 172 | return c; | ||
| 180 | } | 173 | } |
| 181 | 174 | ||
| 182 | static uint64_t | 175 | static uint64_t |
| @@ -229,6 +222,20 @@ index_khuge(Cube cube) | |||
| 229 | return a * POW3TO7 + c.coud; | 222 | return a * POW3TO7 + c.coud; |
| 230 | } | 223 | } |
| 231 | 224 | ||
| 225 | static uint64_t | ||
| 226 | index_nxopt31(Cube cube) | ||
| 227 | { | ||
| 228 | Trans t; | ||
| 229 | Cube c; | ||
| 230 | uint64_t a; | ||
| 231 | |||
| 232 | t = sd_eofbepos_16.transtorep[coord_eofbepos.index(cube)]; | ||
| 233 | c = apply_trans(t, cube); | ||
| 234 | a = (index_eofbepos_sym16(c)*BINOM8ON4) + coord_cpud_separate.index(c); | ||
| 235 | |||
| 236 | return a * POW3TO7 + c.coud; | ||
| 237 | } | ||
| 238 | |||
| 232 | static int | 239 | static int |
| 233 | transfinder_drud_sym16(uint64_t ind, Trans *ret) | 240 | transfinder_drud_sym16(uint64_t ind, Trans *ret) |
| 234 | { | 241 | { |
| @@ -295,6 +302,28 @@ transfinder_khuge(uint64_t ind, Trans *ret) | |||
| 295 | return naux[trueind]; | 302 | return naux[trueind]; |
| 296 | } | 303 | } |
| 297 | 304 | ||
| 305 | static int | ||
| 306 | transfinder_nxopt31(uint64_t ind, Trans *ret) | ||
| 307 | { | ||
| 308 | uint64_t i, trueind; | ||
| 309 | int j; | ||
| 310 | static bool initialized = false; | ||
| 311 | static int naux[CLASSES_EOFBEPOS_16]; | ||
| 312 | static Trans retaux[CLASSES_EOFBEPOS_16][NTRANS]; | ||
| 313 | |||
| 314 | if (!initialized) { | ||
| 315 | for (i = 0; i < CLASSES_EOFBEPOS_16; i++) | ||
| 316 | naux[i] = selfsims(&sd_eofbepos_16, i, retaux[i]); | ||
| 317 | |||
| 318 | initialized = true; | ||
| 319 | } | ||
| 320 | |||
| 321 | trueind = ind/(BINOM8ON4*POW3TO7); | ||
| 322 | for (j = 0; j < naux[trueind]; j++) | ||
| 323 | ret[j] = retaux[trueind][j]; | ||
| 324 | return naux[trueind]; | ||
| 325 | } | ||
| 326 | |||
| 298 | /* Other functions ***********************************************************/ | 327 | /* Other functions ***********************************************************/ |
| 299 | 328 | ||
| 300 | static void | 329 | static void |
diff --git a/src/symcoord.h b/src/symcoord.h index f231c92..4ba3815 100644 --- a/src/symcoord.h +++ b/src/symcoord.h | |||
| @@ -3,12 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #include "coord.h" | 4 | #include "coord.h" |
| 5 | 5 | ||
| 6 | extern Coordinate coord_coud_sym16; | ||
| 7 | extern Coordinate coord_cp_sym16; | 6 | extern Coordinate coord_cp_sym16; |
| 8 | extern Coordinate coord_eofbepos_sym16; | 7 | extern Coordinate coord_eofbepos_sym16; |
| 9 | extern Coordinate coord_drud_sym16; | 8 | extern Coordinate coord_drud_sym16; |
| 10 | extern Coordinate coord_drudfin_noE_sym16; | 9 | extern Coordinate coord_drudfin_noE_sym16; |
| 11 | extern Coordinate coord_khuge; | 10 | extern Coordinate coord_khuge; |
| 11 | extern Coordinate coord_nxopt31; | ||
| 12 | 12 | ||
| 13 | void init_symcoord(); | 13 | void init_symcoord(); |
| 14 | 14 | ||
