diff options
Diffstat (limited to 'src/solve_h48.h')
| -rw-r--r-- | src/solve_h48.h | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/src/solve_h48.h b/src/solve_h48.h index ad77156..ad865a7 100644 --- a/src/solve_h48.h +++ b/src/solve_h48.h | |||
| @@ -27,6 +27,24 @@ | |||
| 27 | 27 | ||
| 28 | #define MAX_SOLUTION_LENGTH 20 | 28 | #define MAX_SOLUTION_LENGTH 20 |
| 29 | 29 | ||
| 30 | /* | ||
| 31 | TODO: This loop other similar h48 coordinates can be improved by only | ||
| 32 | transforming edges, but we need to compose transformations (i.e. conjugate | ||
| 33 | _t by _ttrep). | ||
| 34 | */ | ||
| 35 | #define _foreach_h48sim(_cube, _cocsepdata, _selfsim, _h, _action) \ | ||
| 36 | int64_t _cocsep = coord_cocsep(_cube); \ | ||
| 37 | uint8_t _ttrep = TTREP(_cocsepdata[_cocsep]); \ | ||
| 38 | int64_t _coclass = COCLASS(_cocsepdata[_cocsep]); \ | ||
| 39 | cube_t _rep = transform(_cube, _ttrep); \ | ||
| 40 | uint64_t _sim = _selfsim[_coclass]; \ | ||
| 41 | for (uint8_t _t = 0; _t < 48 && _sim; _t++, _sim >>= 1) { \ | ||
| 42 | if (!(_sim & 1)) continue; \ | ||
| 43 | _cube = transform(_rep, _t); \ | ||
| 44 | _cube = transform(_cube, inverse_trans(_ttrep)); \ | ||
| 45 | _action \ | ||
| 46 | } | ||
| 47 | |||
| 30 | typedef struct { | 48 | typedef struct { |
| 31 | uint64_t n; | 49 | uint64_t n; |
| 32 | uint64_t capacity; | 50 | uint64_t capacity; |
| @@ -229,12 +247,12 @@ coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) | |||
| 229 | } | 247 | } |
| 230 | 248 | ||
| 231 | _static_inline int64_t | 249 | _static_inline int64_t |
| 232 | coord_h48_edges(cube_t c, int64_t coclass, uint8_t t, uint8_t h) | 250 | coord_h48_edges(cube_t c, int64_t coclass, uint8_t ttrep, uint8_t h) |
| 233 | { | 251 | { |
| 234 | cube_t d; | 252 | cube_t d; |
| 235 | int64_t esep, eo, edges; | 253 | int64_t esep, eo, edges; |
| 236 | 254 | ||
| 237 | d = transform_edges(c, t); | 255 | d = transform_edges(c, ttrep); |
| 238 | esep = coord_esep(d); | 256 | esep = coord_esep(d); |
| 239 | eo = coord_eo(d); | 257 | eo = coord_eo(d); |
| 240 | edges = (esep << 11) + eo; | 258 | edges = (esep << 11) + eo; |
| @@ -394,11 +412,11 @@ gen_h48short( | |||
| 394 | const uint64_t *selfsim, | 412 | const uint64_t *selfsim, |
| 395 | h48map_t *map | 413 | h48map_t *map |
| 396 | ) { | 414 | ) { |
| 397 | uint8_t i, m, t; | 415 | uint8_t i, m; |
| 398 | int64_t coord, cc; | 416 | int64_t coord; |
| 399 | uint64_t j, oldn, sim; | 417 | uint64_t j, oldn; |
| 400 | kvpair_t kv; | 418 | kvpair_t kv; |
| 401 | cube_t cube, d, e; | 419 | cube_t cube, d; |
| 402 | 420 | ||
| 403 | cube = solvedcube(); | 421 | cube = solvedcube(); |
| 404 | coord = coord_h48(cube, cocsepdata, 11); | 422 | coord = coord_h48(cube, cocsepdata, 11); |
| @@ -418,17 +436,10 @@ gen_h48short( | |||
| 418 | cube = invcoord_h48(kv.key, crep, 11); | 436 | cube = invcoord_h48(kv.key, crep, 11); |
| 419 | for (m = 0; m < 18; m++) { | 437 | for (m = 0; m < 18; m++) { |
| 420 | d = move(cube, m); | 438 | d = move(cube, m); |
| 421 | coord = coord_h48(d, cocsepdata, 11); | 439 | _foreach_h48sim(d, cocsepdata, selfsim, 11, |
| 422 | h48map_insertmin(map, coord, i+1); | 440 | coord = coord_h48(d, cocsepdata, 11); |
| 423 | cc = coord / H48_ESIZE(11); | ||
| 424 | sim = selfsim[cc] >> UINT64_C(1); | ||
| 425 | for (t = 1; t < 48 && sim; t++) { | ||
| 426 | /* TODO: optimize by using transform_edges, | ||
| 427 | corner coordinate is kept */ | ||
| 428 | e = transform(d, t); | ||
| 429 | coord = coord_h48(e, cocsepdata, 11); | ||
| 430 | h48map_insertmin(map, coord, i+1); | 441 | h48map_insertmin(map, coord, i+1); |
| 431 | } | 442 | ) |
| 432 | } | 443 | } |
| 433 | } | 444 | } |
| 434 | LOG("found %" PRIu8 "\n", map->n-oldn); | 445 | LOG("found %" PRIu8 "\n", map->n-oldn); |
| @@ -512,9 +523,8 @@ gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *arg) | |||
| 512 | { | 523 | { |
| 513 | uint8_t c, m, x; | 524 | uint8_t c, m, x; |
| 514 | uint32_t cc; | 525 | uint32_t cc; |
| 515 | int64_t i, j, k, t, cocsep_coord; | 526 | int64_t i, j, k; |
| 516 | uint64_t sim; | 527 | cube_t cube, moved; |
| 517 | cube_t cube, moved, transd; | ||
| 518 | 528 | ||
| 519 | for (i = 0, cc = 0; i < (int64_t)ESEP_MAX(0); i++) { | 529 | for (i = 0, cc = 0; i < (int64_t)ESEP_MAX(0); i++) { |
| 520 | c = get_esep_pval(arg->buf32, i); | 530 | c = get_esep_pval(arg->buf32, i); |
| @@ -522,30 +532,16 @@ gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *arg) | |||
| 522 | continue; | 532 | continue; |
| 523 | cube = invcoord_h48(i, arg->crep, 0); | 533 | cube = invcoord_h48(i, arg->crep, 0); |
| 524 | for (m = 0; m < 18; m++) { | 534 | for (m = 0; m < 18; m++) { |
| 525 | /* | ||
| 526 | * TODO: here we can optimize by computing at first | ||
| 527 | * only the corner part of the coordinate, and then | ||
| 528 | * the edge parts for each transformation. | ||
| 529 | */ | ||
| 530 | moved = move(cube, m); | 535 | moved = move(cube, m); |
| 531 | j = coord_h48(moved, arg->cocsepdata, 0); | 536 | j = coord_h48(moved, arg->cocsepdata, 0); |
| 532 | x = get_esep_pval(arg->buf32, j); | 537 | if (get_esep_pval(arg->buf32, j) <= arg->depth) |
| 533 | if (x <= arg->depth) | ||
| 534 | continue; | 538 | continue; |
| 535 | set_esep_pval(arg->buf32, j, arg->depth); | 539 | _foreach_h48sim(moved, arg->cocsepdata, arg->selfsim, 0, |
| 536 | cc += x != arg->depth; | 540 | k = coord_h48(moved, arg->cocsepdata, 0); |
| 537 | cocsep_coord = j / H48_ESIZE(0); | ||
| 538 | sim = arg->selfsim[cocsep_coord] >> UINT64_C(1); | ||
| 539 | for (t = 1; t < 48 && sim; t++) { | ||
| 540 | /* TODO: use only selfsim */ | ||
| 541 | transd = transform(moved, t); | ||
| 542 | k = coord_h48(transd, arg->cocsepdata, 0); | ||
| 543 | x = get_esep_pval(arg->buf32, k); | 541 | x = get_esep_pval(arg->buf32, k); |
| 544 | if (x <= arg->depth) | ||
| 545 | continue; | ||
| 546 | set_esep_pval(arg->buf32, k, arg->depth); | 542 | set_esep_pval(arg->buf32, k, arg->depth); |
| 547 | cc += x != arg->depth; | 543 | cc += x != arg->depth; |
| 548 | } | 544 | ) |
| 549 | } | 545 | } |
| 550 | } | 546 | } |
| 551 | 547 | ||
| @@ -557,8 +553,8 @@ gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *arg) | |||
| 557 | { | 553 | { |
| 558 | uint8_t c, m, x; | 554 | uint8_t c, m, x; |
| 559 | uint32_t cc; | 555 | uint32_t cc; |
| 560 | int64_t i, j, t, cocsep_coord, sim; | 556 | int64_t i, j; |
| 561 | cube_t cube, moved, transd; | 557 | cube_t cube, moved; |
| 562 | 558 | ||
| 563 | for (i = 0, cc = 0; i < (int64_t)ESEP_MAX(0); i++) { | 559 | for (i = 0, cc = 0; i < (int64_t)ESEP_MAX(0); i++) { |
| 564 | c = get_esep_pval(arg->buf32, i); | 560 | c = get_esep_pval(arg->buf32, i); |
| @@ -569,22 +565,33 @@ gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *arg) | |||
| 569 | moved = move(cube, m); | 565 | moved = move(cube, m); |
| 570 | j = coord_h48(moved, arg->cocsepdata, 0); | 566 | j = coord_h48(moved, arg->cocsepdata, 0); |
| 571 | x = get_esep_pval(arg->buf32, j); | 567 | x = get_esep_pval(arg->buf32, j); |
| 572 | if (x < arg->depth) | 568 | if (x >= arg->depth) |
| 573 | goto neighbor_found; | 569 | continue; |
| 574 | } | 570 | #if 0 |
| 575 | continue; | 571 | cube_t transd; |
| 576 | neighbor_found: | 572 | int64_t t, cocsep_coord, sim; |
| 577 | set_esep_pval(arg->buf32, i, arg->depth); | 573 | |
| 578 | cc++; | 574 | set_esep_pval(arg->buf32, i, arg->depth); |
| 579 | cocsep_coord = i / H48_ESIZE(0); | 575 | cc++; |
| 580 | sim = arg->selfsim[cocsep_coord] >> 1; | 576 | cocsep_coord = i / H48_ESIZE(0); |
| 581 | for (t = 1; t < 48 && sim; t++) { | 577 | sim = arg->selfsim[cocsep_coord] >> 1; |
| 582 | /* TODO: use only selfsim */ | 578 | for (t = 1; t < 48 && sim; t++) { |
| 583 | transd = transform(cube, t); | 579 | transd = transform(cube, t); |
| 584 | j = coord_h48(transd, arg->cocsepdata, 0); | 580 | j = coord_h48(transd, arg->cocsepdata, 0); |
| 585 | x = get_esep_pval(arg->buf32, j); | 581 | x = get_esep_pval(arg->buf32, j); |
| 586 | set_esep_pval(arg->buf32, j, arg->depth); | 582 | set_esep_pval(arg->buf32, j, arg->depth); |
| 587 | cc += x == 0xF; | 583 | cc += x == 0xF; |
| 584 | } | ||
| 585 | #else | ||
| 586 | _foreach_h48sim(cube, arg->cocsepdata, arg->selfsim, 0, | ||
| 587 | j = coord_h48(cube, arg->cocsepdata, 0); | ||
| 588 | x = get_esep_pval(arg->buf32, j); | ||
| 589 | set_esep_pval(arg->buf32, j, arg->depth); | ||
| 590 | cc += x == 0xF; | ||
| 591 | ) | ||
| 592 | #endif | ||
| 593 | |||
| 594 | break; | ||
| 588 | } | 595 | } |
| 589 | } | 596 | } |
| 590 | 597 | ||
