nissy-nx

A Rubik's cube optimal solver
git clone https://git.tronto.net/nissy-nx
Download | Log | Files | Refs | README | LICENSE

commit f021ee7fa4975eab02c158451093a28e83a725d9
parent e18f8e4eefadd733d985e99e2710111afa5a710a
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Tue, 31 May 2022 17:29:08 +0200

Big changes to coordinate system: remove "anti-index" in favor of a more kociemba-like move function for each coordinate. This should speedup the table generation step. WARNING: nissy might not be 100% functional at this stage, TESTING needed!

Diffstat:
A.gitignore | 1+
MTODO.md | 47+++++++++++++++++++++++++++++++++++------------
Mnissy | 0
Msrc/commands.c | 28+++++++++++++++++++++-------
Msrc/coord.c | 560++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/coord.h | 5++++-
Msrc/cube.c | 30++++++++++++++++++++++++++----
Msrc/cube.h | 3+++
Msrc/cubetypes.h | 7++++---
Msrc/pruning.c | 32+++++++++++++++-----------------
Msrc/symcoord.c | 344+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Mwww/download/index.html | 4++--
12 files changed, 610 insertions(+), 451 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +nissy diff --git a/TODO.md b/TODO.md @@ -5,24 +5,46 @@ It's more of a personal reminder than anything else. ## For version 2.1 ### Moving coordinates -* Implement coord->move to apply moves directly on coordinates -* add transformer to transform coordinate (optional, only for sym coordinates) -* For each coordinate, manually disallow "bad" moves, or just ignore the error - (probably better to check: low performance cost, detect problems that I might - be overlooking) -* remove selsims, do this directly inside transfinder -* change genptable where needed -* Remove coord->cube (and edit README.md accordingly) -* Remove sym_data->rep (but keep transtorep)? -* Use this to improve solver: add 2 or 3 helper coordinates to optimal solver, - to avoid transforming every time. We still need to transform when checking - inverse scramble, though. +* general cleanup +### Changes to Step and Solve +* add a list of "helper" coordinates to every step +* Probably nicer: instead of passing a cube pass a structure "cube description" + which can contain coordinates and one or more cubes. + This can also be used to avoid using index_epud too much in drfin + (it is slow because it goes through cubearray). +* add a step->move(Cube) function, which may apply moves to the cube or just to + the coordinates +* optimal solver: move the coordinates for the 3 orientations, but also the + cube so we can check the inverse +### Tables management +* Check files in tables directory, add command to remove old / extraneous files +* Add checksum to check that tables are generated / downloaded correctly ### Documentation +* Fix README.md with new coordinate system * Write an examples.md file * More screenshots! ### More * Anything quick and easy from the sections below +## Refactor +### Coordinates +* Text (README.md) description of coordinate system with 3 (or 4) types of + coordinates: basic (+ fundamental), sym, composite (consisting of at most + one sym + one or more basic) +* Use this to restructure the coordinate part; maybe fundamental coordinates + do not need to exist??? +* Add also "transform" for every coordinate. For example, for EO and similar + only allow transformations that fix the EO axis. +* Also: "basic" symcoord do not allow trans, composite coordinates assume + the transformation fixes the basic sumcoord +* For each coordinate, manually disallow "bad" moves, or just ignore the error + (probably better to check: low performance cost, detect problems that I might + be overlooking) +### Loading at startup vs dynamically +* Consider moving more things to the initial loading phase (i.e. remove + many of the "initialized" parts) + + ## Commands ### Commands that are available in nissy 1.0, but not in this version (yet): @@ -34,6 +56,7 @@ including e.g. solutions that were not shown because -c) ### More steps for `solve` * QTM optimal solving +* 5-side solve (for robots) * Block-building steps (cross, roux blocks, ...) * Other common steps (LSE, ...) diff --git a/nissy b/nissy Binary files differ. diff --git a/src/commands.c b/src/commands.c @@ -410,9 +410,11 @@ static void scramble_exec(CommandArgs *args) { Cube cube; + CubeArray *arr; Alg *scr, *ruf, *aux; int i, j, eo, ep, co, cp, a[12]; - uint64_t ui, uj; + int eparr[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 }; + uint64_t ui, uj, uk; init_all_movesets(); init_symcoord(); @@ -429,17 +431,29 @@ scramble_exec(CommandArgs *args) * Moreover we again need to fix parity after * * generating epose manually */ do { - ui = rand() % coord_drudfin_noE_sym16.max; - uj = rand() % FACTORIAL4; - cube = coord_drudfin_noE_sym16.cube(ui); - cube.epose += uj; + ui = rand() % FACTORIAL8; + uj = rand() % FACTORIAL8; + uk = rand() % FACTORIAL4; + + index_to_perm(ui, 12, a); + arr = malloc(sizeof(CubeArray)); + arr->ep = eparr; + cube = arrays_to_cube(arr, pf_ep); + free(arr); + + cube.cp = uj; + cube.epose += uk; } while (!is_admissible(cube)); } else if (!strcmp(args->scrtype, "htr")) { /* antindex_htrfin() returns a consistent * * cube, except possibly for parity */ do { - ui = rand() % coord_htrfin.max; - cube = coord_htrfin.cube(ui); + ui = rand() % (24*24/6); + cube = (Cube){0}; + cube.cp = cornershtrfin_ant[ui]; + cube.epose = rand() % 24; + cube.eposs = rand() % 24; + cube.eposm = rand() % 24; } while (!is_admissible(cube)); } else { eo = rand() % POW2TO11; diff --git a/src/coord.c b/src/coord.c @@ -1,20 +1,5 @@ #include "coord.h" -static Cube antindex_eofb(uint64_t ind); -static Cube antindex_eofbepos(uint64_t ind); -static Cube antindex_epud(uint64_t ind); -static Cube antindex_coud(uint64_t ind); -static Cube antindex_corners(uint64_t ind); -static Cube antindex_cp(uint64_t ind); -static Cube antindex_cphtr(uint64_t); -static Cube antindex_cornershtr(uint64_t ind); -static Cube antindex_cornershtrfin(uint64_t ind); -static Cube antindex_drud(uint64_t ind); -static Cube antindex_drud_eofb(uint64_t ind); -static Cube antindex_htr_drud(uint64_t ind); -static Cube antindex_htrfin(uint64_t ind); -static Cube antindex_cpud_separate(uint64_t ind); - static uint64_t index_eofb(Cube cube); static uint64_t index_eofbepos(Cube cube); static uint64_t index_epud(Cube cube); @@ -30,10 +15,27 @@ static uint64_t index_htr_drud(Cube cube); static uint64_t index_htrfin(Cube cube); static uint64_t index_cpud_separate(Cube cube); +static uint64_t move_eofb(Move m, uint64_t ind); +static uint64_t move_eofbepos(Move m, uint64_t ind); +static uint64_t move_epud(Move m, uint64_t ind); +static uint64_t move_coud(Move m, uint64_t ind); +static uint64_t move_corners(Move m, uint64_t ind); +static uint64_t move_cp(Move m, uint64_t ind); +static uint64_t move_cphtr(Move m, uint64_t ind); +static uint64_t move_cornershtr(Move m, uint64_t ind); +static uint64_t move_cornershtrfin(Move m, uint64_t ind); +static uint64_t move_drud(Move m, uint64_t ind); +static uint64_t move_drud_eofb(Move m, uint64_t ind); +static uint64_t move_htr_drud(Move m, uint64_t ind); +static uint64_t move_htrfin(Move m, uint64_t ind); +static uint64_t move_cpud_separate(Move m, uint64_t ind); + static void init_cphtr_cosets(); static void init_cphtr_left_cosets_bfs(int i, int c); static void init_cphtr_right_cosets_color(int i, int c); +static void init_cpud_separate(); static void init_cornershtrfin(); +static void init_htr_eposs(); /* All sorts of useful costants and tables **********************************/ @@ -41,497 +43,408 @@ static void init_cornershtrfin(); static int cphtr_left_cosets[FACTORIAL8]; static int cphtr_right_cosets[FACTORIAL8]; static int cphtr_right_rep[BINOM8ON4*6]; +int cpud_separate_ind[FACTORIAL8]; +int cpud_separate_ant[BINOM8ON4]; static int cornershtrfin_ind[FACTORIAL8]; -static int cornershtrfin_ant[24*24/6]; +int cornershtrfin_ant[24*24/6]; +static int htr_eposs_ind[BINOM12ON4]; +static int htr_eposs_ant[BINOM8ON4]; /* Coordinates and their implementation **************************************/ Coordinate coord_eofb = { .index = index_eofb, - .cube = antindex_eofb, .max = POW2TO11, + .move = move_eofb, }; Coordinate coord_eofbepos = { .index = index_eofbepos, - .cube = antindex_eofbepos, .max = POW2TO11 * BINOM12ON4, + .move = move_eofbepos, }; Coordinate coord_coud = { .index = index_coud, - .cube = antindex_coud, .max = POW3TO7, + .move = move_coud, }; Coordinate coord_corners = { .index = index_corners, - .cube = antindex_corners, .max = POW3TO7 * FACTORIAL8, + .move = move_corners, }; Coordinate coord_cp = { .index = index_cp, - .cube = antindex_cp, .max = FACTORIAL8, + .move = move_cp, }; Coordinate coord_cphtr = { .index = index_cphtr, - .cube = antindex_cphtr, .max = BINOM8ON4 * 6, + .move = move_cphtr, }; Coordinate coord_cornershtr = { .index = index_cornershtr, - .cube = antindex_cornershtr, .max = POW3TO7 * BINOM8ON4 * 6, + .move = move_cornershtr, }; Coordinate coord_cornershtrfin = { .index = index_cornershtrfin, - .cube = antindex_cornershtrfin, .max = 24*24/6, + .move = move_cornershtrfin, }; Coordinate coord_epud = { .index = index_epud, - .cube = antindex_epud, .max = FACTORIAL8, + .move = move_epud, }; Coordinate coord_drud = { .index = index_drud, - .cube = antindex_drud, .max = POW2TO11 * POW3TO7 * BINOM12ON4, + .move = move_drud, }; Coordinate coord_htr_drud = { .index = index_htr_drud, - .cube = antindex_htr_drud, .max = BINOM8ON4 * 6 * BINOM8ON4, + .move = move_htr_drud, }; Coordinate coord_htrfin = { .index = index_htrfin, - .cube = antindex_htrfin, .max = 24 * 24 * 24 *24 * 24 / 6, /* should be /12 but it's ok */ + .move = move_htrfin, }; Coordinate coord_drud_eofb = { .index = index_drud_eofb, - .cube = antindex_drud_eofb, .max = POW3TO7 * BINOM12ON4, + .move = move_drud_eofb, }; Coordinate coord_cpud_separate = { .index = index_cpud_separate, - .cube = antindex_cpud_separate, .max = BINOM8ON4, + .move = move_cpud_separate, }; -/* Antindexers ***************************************************************/ +/* Indexers ******************************************************************/ -static Cube -antindex_eofb(uint64_t ind) +static uint64_t +index_eofb(Cube cube) { - /* The returned cube is consistent */ - Cube ret = {0}; - - ret.eofb = ind; - ret.eorl = ind; - ret.eoud = ind; - - return ret; + return cube.eofb; } -static Cube -antindex_eofbepos(uint64_t ind) +static uint64_t +index_eofbepos(Cube cube) { - /* The returned cube is NOT consistent: eoud can be wrong */ - Cube ret = {0}; - - /* We need eorl for sym16 coordinate */ - static int initialized = false; - static uint64_t eorl_a[POW2TO11][BINOM12ON4]; - static int eo_aux[12], ep_aux[12]; - unsigned int i, j, k; - - if (!initialized) { - for (i = 0; i < POW2TO11; i++) { - for (j = 0; j < BINOM12ON4; j++) { - int_to_sum_zero_array(i, 2, 12, eo_aux); - index_to_subset(j, 12, 4, ep_aux); - for (k = 0; k < 12; k++) - if ((ep_aux[k] && k < FR) || - (!ep_aux[k] && k >= FR)) - eo_aux[k] = 1 - eo_aux[k]; - eorl_a[i][j] = digit_array_to_int(eo_aux,11,2); - } - } + return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb; +} - initialized = true; - } +static uint64_t +index_epud(Cube cube) +{ + uint64_t ret; + CubeArray *arr = new_cubearray(cube, pf_ep); - ret.eofb = ind % POW2TO11; - ret.epose = (ind / POW2TO11) * 24; - ret.eorl = eorl_a[ret.eofb][ret.epose/24]; + ret = perm_to_index(arr->ep, 8); + free_cubearray(arr, pf_ep); return ret; } -static Cube -antindex_epud(uint64_t ind) +static uint64_t +index_coud(Cube cube) { - /* The returned cube is consistent */ - static bool initialized = false; - static Cube epud_aux[FACTORIAL8]; - int a[12]; - uint64_t ui; - CubeArray arr; - - if (!initialized) { - a[FR] = FR; - a[FL] = FL; - a[BL] = BL; - a[BR] = BR; - for (ui = 0; ui < FACTORIAL8; ui++) { - index_to_perm(ui, 8, a); - arr.ep = a; - epud_aux[ui] = arrays_to_cube(&arr, pf_ep); - } - - initialized = true; - } - - return epud_aux[ind]; + return cube.coud; } -static Cube -antindex_coud(uint64_t ind) +static uint64_t +index_corners(Cube cube) { - /* The returned cube is consistent */ - Cube ret = {0}; - - ret.coud = ind; - ret.corl = ind; - ret.cofb = ind; - - return ret; + return cube.coud * FACTORIAL8 + cube.cp; } -static Cube -antindex_corners(uint64_t ind) +static uint64_t +index_cp(Cube cube) { - /* The returned cube is NOT consistent: corl and cofb can be wrong */ - /* TODO: remember to make this consistent if I use this for symcoord */ - Cube ret = {0}; - - ret.coud = ind / FACTORIAL8; - ret.cp = ind % FACTORIAL8; - - return ret; + return cube.cp; } -static Cube -antindex_cp(uint64_t ind) +static uint64_t +index_cphtr(Cube cube) { - /* The returned cube is NOT consistent: co can be wrong in all axes */ - Cube ret = {0}; + return cphtr_right_cosets[cube.cp]; +} - ret.cp = ind; +static uint64_t +index_cornershtr(Cube cube) +{ + return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube); +} - return ret; +static uint64_t +index_cornershtrfin(Cube cube) +{ + return cornershtrfin_ind[cube.cp]; } -static Cube -antindex_cphtr(uint64_t ind) +static uint64_t +index_drud(Cube cube) { - /* The returned cube is NOT consistent: co can be wrong in all axes */ - Cube ret = {0}; + uint64_t a, b, c; - ret.cp = cphtr_right_rep[ind]; + a = cube.eofb; + b = cube.coud; + c = cube.epose / FACTORIAL4; - return ret; + b *= POW2TO11; + c *= POW2TO11 * POW3TO7; + + return a + b + c; } -static Cube -antindex_cornershtr(uint64_t ind) +static uint64_t +index_drud_eofb(Cube cube) { - /* The returned cube is NOT consistent: corl and cofb can be wrong */ - Cube ret = antindex_cphtr(ind % (BINOM8ON4 * 6)); - - ret.coud = ind / (BINOM8ON4 * 6); - - return ret; + return index_drud(cube) / POW2TO11; } -static Cube -antindex_cornershtrfin(uint64_t ind) +static uint64_t +index_htr_drud(Cube cube) { - /* The returned cube is consistent */ - Cube ret = {0}; + uint64_t a, b; - ret.cp = cornershtrfin_ant[ind]; + a = index_cphtr(cube); + b = htr_eposs_ind[cube.eposs/24]; - return ret; + return a * BINOM8ON4 + b; } -static Cube -antindex_drud(uint64_t ind) +static uint64_t +index_htrfin(Cube cube) { - /* The returned cube is NOT consistent in the same way as eofbepos */ - /* (see above). It works with sym16 coordinates */ - uint64_t epos, eofb; - Cube ret = {0}; - - eofb = ind % POW2TO11; - epos = ind / (POW2TO11 * POW3TO7); - ret = antindex_eofbepos(eofb + POW2TO11 * epos); + uint64_t epe, eps, epm, cp, ep; - ret.coud = (ind / POW2TO11) % POW3TO7; - ret.corl = ret.coud; - ret.cofb = ret.coud; + epe = cube.epose % 24; + eps = cube.eposs % 24; + epm = cube.eposm % 24; + ep = (epe * 24 + eps) *24 + epm; + cp = index_cornershtrfin(cube); - return ret; + return cp * 24 * 24 * 24 + ep; } -static Cube -antindex_drud_eofb(uint64_t ind) +static uint64_t +index_cpud_separate(Cube cube) { - /* The returned cube is NOT consistent (see antindex_drud) */ - return antindex_drud(ind * POW2TO11); + return cpud_separate_ind[cube.cp]; } -static Cube -antindex_htr_drud(uint64_t ind) -{ - /* The returned cube is NOT consistent: corl and cofb can be wrong */ - /* (see cphtr) and eposm can be wrong too (not epose because dr). */ - Cube ret = {0}; - static bool initialized = false; - static int aux[BINOM8ON4], ep[12], ep2[12]; - static int eps_solved[4] = {UL, UR, DL, DR}; - unsigned int i, j, k; +/* Coordinate movers *********************************************************/ - if (!initialized) { - for (i = 0; i < BINOM8ON4; i++) { - for (j = 0; j < 12; j++) - ep[j] = ep2[j] = 0; - index_to_subset(i, 8, 4, ep); - for (j = 0, k = 0; j < 8; j++) - ep2[j] = ep[j/2+4*(j%2)] ? eps_solved[k++] : 0; - aux[i] = array_ep_to_epos(ep2, eps_solved); - } - - initialized = true; - } - - ret = antindex_cphtr(ind / BINOM8ON4); - ret.epose = 0; - ret.eposs = aux[ind % BINOM8ON4]; - - return ret; +static uint64_t +move_eofb(Move m, uint64_t ind) +{ + return eofb_mtable[m][ind]; } -static Cube -antindex_htrfin(uint64_t ind) +static uint64_t +move_eofbepos(Move m, uint64_t ind) { - /* The returned cube is consistent */ - Cube ret = {0}; - - ret = antindex_cornershtrfin(ind/(24*24*24)); + uint64_t a, b; - ret.eposm = ind % 24; - ind /= 24; - ret.eposs = ind % 24; - ind /= 24; - ret.epose = ind % 24; + a = epose_mtable[m][(ind / POW2TO11)*24]; + b = eofb_mtable[m][ind % POW2TO11]; - return ret; + return a/24 + b; } -static Cube -antindex_cpud_separate(uint64_t ind) +static uint64_t +move_epud(Move m, uint64_t ind) { - /* Not consistent because of side corner orientations and cp */ - unsigned int ui; - int i, co[8], cp[8]; - Corner u, d; - - static Cube aux[BINOM8ON4]; + /* TODO: save to file? */ static bool initialized = false; + static int a[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 }; + static int shortlist[NMOVES] = { + [U] = 0, [U2] = 1, [U3] = 2, [D] = 3, [D2] = 4, [D3] = 5, + [R2] = 6, [L2] = 7, [F2] = 8, [B2] = 9 + }; + static uint64_t aux[10][FACTORIAL8]; + uint64_t ui; + int j; + Move mj; + Cube c; + CubeArray *arr, *auxarr; + + if (!moveset_drud.allowed(m)) { + fprintf(stderr, "Move not allowed for epud\n" + "This is a bug, please report\n"); + return coord_epud.max; + } if (!initialized) { - for (ui = 0; ui < BINOM8ON4; ui++) { - index_to_subset(ui, 8, 4, co); - for (i = 0, u = UFR, d = DFR; i < 8; i++) - cp[i] = co[i] ? d++ : u++; - aux[ui] = (Cube){.cp = perm_to_index(cp, 8)}; + auxarr = malloc(sizeof(CubeArray)); + auxarr->ep = a; + for (ui = 0; ui < coord_epud.max; ui++) { + index_to_perm(ui, 8, a); + c = arrays_to_cube(auxarr, pf_ep); + for (j = 0; moveset_drud.sorted_moves[j] != NULLMOVE; + j++) { + mj = moveset_drud.sorted_moves[j]; + arr = new_cubearray(apply_move(mj, c), pf_ep); + aux[shortlist[mj]][ui] = + perm_to_index(arr->ep, 8); + free_cubearray(arr, pf_ep); + } } + free(auxarr); initialized = true; } - return aux[ind]; + return aux[shortlist[m]][ind]; } -/* Indexers ******************************************************************/ - static uint64_t -index_eofb(Cube cube) +move_coud(Move m, uint64_t ind) { - return cube.eofb; + return coud_mtable[m][ind]; } static uint64_t -index_eofbepos(Cube cube) +move_corners(Move m, uint64_t ind) { - return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb; -} + uint64_t a, b; -static uint64_t -index_epud(Cube cube) -{ - uint64_t ret; - CubeArray *arr = new_cubearray(cube, pf_ep); - - ret = perm_to_index(arr->ep, 8); - free_cubearray(arr, pf_ep); + a = coud_mtable[m][ind / FACTORIAL8]; + b = cp_mtable[m][ind % FACTORIAL8]; - return ret; + return a * FACTORIAL8 + b; } static uint64_t -index_coud(Cube cube) +move_cp(Move m, uint64_t ind) { - return cube.coud; + return cp_mtable[m][ind]; } static uint64_t -index_corners(Cube cube) +move_cphtr(Move m, uint64_t ind) { - return cube.coud * FACTORIAL8 + cube.cp; -} + static bool initialized = false; + static uint64_t aux[NMOVES][BINOM8ON4*6]; + uint64_t ui; + Move j; -static uint64_t -index_cp(Cube cube) -{ - return cube.cp; -} + if (!initialized) { + for (ui = 0; ui < BINOM8ON4*6; ui++) + for (j = U; j < NMOVES; j++) + aux[j][ui] = + cp_mtable[j][cphtr_right_rep[ind]]; -static uint64_t -index_cphtr(Cube cube) -{ - return cphtr_right_cosets[cube.cp]; + initialized = true; + } + + return aux[m][ind]; } static uint64_t -index_cornershtr(Cube cube) +move_cornershtr(Move m, uint64_t ind) { - return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube); + uint64_t a, b; + + a = coud_mtable[m][ind/(BINOM8ON4 * 6)]; + b = move_cphtr(m, ind % (BINOM8ON4 * 6)); + + return a * BINOM8ON4 * 6 + b; } static uint64_t -index_cornershtrfin(Cube cube) +move_cornershtrfin(Move m, uint64_t ind) { - return cornershtrfin_ind[cube.cp]; + int a; + + a = cp_mtable[m][cornershtrfin_ant[ind]]; + + return cornershtrfin_ind[a]; } static uint64_t -index_drud(Cube cube) +move_drud(Move m, uint64_t ind) { uint64_t a, b, c; - a = cube.eofb; - b = cube.coud; - c = cube.epose / FACTORIAL4; - - b *= POW2TO11; - c *= POW2TO11 * POW3TO7; + a = eofb_mtable[m][ind % POW2TO11]; + b = coud_mtable[m][(ind / POW2TO11) % POW3TO7]; + c = epose_mtable[m][ind / (POW2TO11 * POW3TO7)]; - return a + b + c; + return a + (b + c * POW3TO7) * POW2TO11; } static uint64_t -index_drud_eofb(Cube cube) +move_drud_eofb(Move m, uint64_t ind) { - return index_drud(cube) / POW2TO11; + uint64_t a, b; + + a = coud_mtable[m][ind % POW3TO7]; + b = epose_mtable[m][ind / POW3TO7]; + + return a + b * POW3TO7; } static uint64_t -index_htr_drud(Cube cube) +move_htr_drud(Move m, uint64_t ind) { - static bool initialized = false; - static int aux[BINOM12ON4], ep[12], ep2[12]; - static int eps_solved[4] = {UL, UR, DL, DR}; - unsigned int i, j; + uint64_t a, b; - if (!initialized) { - for (i = 0; i < BINOM12ON4; i++) { - for (j = 0; j < 12; j++) - ep[j] = ep2[j] = 0; - epos_to_partial_ep(i*24, ep, eps_solved); - for (j = 0; j < 8; j++) - ep2[j/2 + 4*(j%2)] = ep[j] ? 1 : 0; - aux[i] = subset_to_index(ep2, 8, 4); - } + a = move_cphtr(m, ind/BINOM8ON4); + b = eposs_mtable[m][htr_eposs_ant[ind%BINOM8ON4]]; - initialized = true; - } - - return index_cphtr(cube) * BINOM8ON4 + aux[cube.eposs/24]; + return a*BINOM8ON4 + htr_eposs_ind[b/24]; } static uint64_t -index_htrfin(Cube cube) +move_htrfin(Move m, uint64_t ind) { - uint64_t epe, eps, epm, cp, ep; + uint64_t a, b, bm, bs, be; - epe = cube.epose % 24; - eps = cube.eposs % 24; - epm = cube.eposm % 24; - ep = (epe * 24 + eps) *24 + epm; - cp = index_cornershtrfin(cube); + a = move_cornershtrfin(m, ind % (24*24*24)); + bm = eposm_mtable[m][ind%24] % 24; + bs = eposs_mtable[m][(ind/24)%24] % 24; + be = epose_mtable[m][ind/(24*24)] % 24; + b = (be * 24 + bs) * 24 + bm; - return cp * 24 * 24 * 24 + ep; + return a * (24*24*24) + b; } static uint64_t -index_cpud_separate(Cube cube) +move_cpud_separate(Move m, uint64_t ind) { - unsigned int ui; - int i, co[8]; - - static int aux[FACTORIAL8]; - static bool initialized = false; - - if (!initialized) { - for (ui = 0; ui < FACTORIAL8; ui++) { - for (i = 0; i < 8; i++) - co[i] = what_corner_at((Cube){.cp=ui},i)>UBR ? - 1 : 0; - aux[ui] = subset_to_index(co, 8, 4); - } - - initialized = true; - } - - return aux[cube.cp]; + return cpud_separate_ind[cp_mtable[m][cpud_separate_ant[ind]]]; } /* Init functions implementation *********************************************/ @@ -618,6 +531,20 @@ init_cphtr_right_cosets_color(int i, int d) } static void +init_cpud_separate() +{ + unsigned int ui; + int i, co[8]; + + for (ui = 0; ui < FACTORIAL8; ui++) { + for (i = 0; i < 8; i++) + co[i] = what_corner_at((Cube){.cp=ui},i)>UBR ? 1 : 0; + cpud_separate_ind[ui] = subset_to_index(co, 8, 4); + cpud_separate_ant[cpud_separate_ind[ui]] = ui; + } +} + +static void init_cornershtrfin() { unsigned int i, j; @@ -649,28 +576,21 @@ init_cornershtrfin() } void -test_coord(Coordinate *coord) +init_htr_eposs() { - bool passed; - uint64_t ui, failcount; - - if (!(passed = (coord->index((Cube){0}) == 0))) { - printf("Failed: coordinate of solved cube is " - "%" PRIu64 "\n", coord->index((Cube){0})); - } + int ep[12], ep2[12]; + int eps_solved[4] = {UL, UR, DL, DR}; + unsigned int i, j; - printf("Testing %" PRIu64 " coordinates\n", coord->max); - for (failcount = 0, ui = 0; ui < coord->max; ui++) { - if (!(passed = (coord->index(coord->cube(ui)) == ui))) { - printf("Failed at %" PRIu64 "\n", ui); - failcount++; - } + for (i = 0; i < BINOM12ON4; i++) { + for (j = 0; j < 12; j++) + ep[j] = ep2[j] = 0; + epos_to_partial_ep(i*24, ep, eps_solved); + for (j = 0; j < 8; j++) + ep2[j/2 + 4*(j%2)] = ep[j] ? 1 : 0; + htr_eposs_ind[i] = subset_to_index(ep2, 8, 4); + htr_eposs_ant[htr_eposs_ind[i]] = i*24; } - - if (passed) - printf("Ok\n"); - else - printf("Test failed in %" PRIu64 " cases\n", failcount); } void @@ -685,5 +605,7 @@ init_coord() init_cphtr_cosets(); init_cornershtrfin(); + init_htr_eposs(); + init_cpud_separate(); } diff --git a/src/coord.h b/src/coord.h @@ -18,7 +18,10 @@ extern Coordinate coord_htr_drud; extern Coordinate coord_htrfin; extern Coordinate coord_cpud_separate; -void test_coord(Coordinate *coord); +extern int cpud_separate_ant[BINOM8ON4]; +extern int cpud_separate_ind[FACTORIAL8]; +extern int cornershtrfin_ant[24*24/6]; + void init_coord(); #endif diff --git a/src/cube.c b/src/cube.c @@ -2,8 +2,6 @@ /* Local functions ***********************************************************/ -static void fix_eorleoud(CubeArray *arr); -static void fix_cofbcorl(CubeArray *arr); static void init_inverse(); static bool read_invtables_file(); static bool write_invtables_file(); @@ -126,6 +124,30 @@ cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) } void +epos_to_compatible_ep(int epos, int *ep, int *ss) +{ + int i, j, k, other[8]; + bool flag; + + for (i = 0; i < 12; i++) + ep[i] = -1; + + epos_to_partial_ep(epos, ep, ss); + + for (i = 0, j = 0; i < 12; i++) { + flag = false; + for (k = 0; k < 4; k++) + flag = flag || (i == ss[k]); + if (!flag) + other[j++] = i; + } + + for (i = 0, j = 0; i < 12; i++) + if (ep[i] == -1) + ep[i] = other[j++]; +} + +void epos_to_partial_ep(int epos, int *ep, int *ss) { int i, is, eposs[12], eps[4]; @@ -141,7 +163,7 @@ epos_to_partial_ep(int epos, int *ep, int *ss) ep[i] = ss[eps[is++]]; } -static void +void fix_eorleoud(CubeArray *arr) { int i; @@ -163,7 +185,7 @@ fix_eorleoud(CubeArray *arr) } } -static void +void fix_cofbcorl(CubeArray *arr) { int i; diff --git a/src/cube.h b/src/cube.h @@ -23,6 +23,9 @@ bool is_solved_center(Cube cube, Center c); bool is_solved_corner(Cube cube, Corner c); bool is_solved_edge(Cube cube, Edge e); void epos_to_partial_ep(int epos, int *ep, int *ss); +void epos_to_compatible_ep(int epos, int *ep, int *ss); +void fix_eorleoud(CubeArray *arr); +void fix_cofbcorl(CubeArray *arr); Cube fourval_to_cube(int eofb, int ep, int coud, int cp); void free_cubearray(CubeArray *arr, PieceFilter f); Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf); diff --git a/src/cubetypes.h b/src/cubetypes.h @@ -168,11 +168,10 @@ struct coordinate { Indexer index; - AntiIndexer cube; uint64_t max; - TransFinder transfind; CoordMover move; CoordTransformer transform; + SymData * sd; }; struct @@ -324,8 +323,10 @@ symdata int ntrans; Trans * trans; uint64_t * class; - Cube * rep; + uint64_t * unsym; Trans * transtorep; + uint64_t * selfsim; + CoordTransformer transform; /* TODO: remove, use that of base coord */ }; struct diff --git a/src/pruning.c b/src/pruning.c @@ -258,25 +258,25 @@ genptable_compress(PruneData *pd) static void genptable_fixnasty(PruneData *pd, int d) { - uint64_t i; - int j, n; - Cube c, cc; - Trans t[NTRANS]; + uint64_t i, ii, mask; + Trans t; - if (pd->coord->transfind == NULL) + if (pd->coord->sd == NULL) return; for (i = 0; i < pd->coord->max; i++) { if (ptableval_index(pd, i) == d) { - n = pd->coord->transfind(i, t); - if (n == 1) + mask = pd->coord->sd->selfsim[i]; + if (mask == (1 << uf)) continue; - c = pd->coord->cube(i); - for (j = 0; j < n; j++) { - cc = apply_trans(t[j], c); - if (ptableval(pd, cc) > d) { - ptable_update(pd, cc, d); + for (t = 0; t < NTRANS; t++) { + if (!((1 << t) & mask)) + continue; + + ii = pd->coord->transform(t, i); + if (ptableval_index(pd, ii) > d) { + ptable_update_index(pd, ii, d); pd->n++; } } @@ -306,7 +306,6 @@ instance_bfs(void *arg) ThreadDataGenpt *td; uint64_t i, ii, blocksize, rmin, rmax, updated; int j, pval, ichunk; - Cube c, cc; Move *ms; td = (ThreadDataGenpt *)arg; @@ -324,15 +323,14 @@ instance_bfs(void *arg) pval = ptableval_index(td->pd, i); pthread_mutex_unlock(td->mutex[ichunk]); if (pval == td->d) { - c = td->pd->coord->cube(i); for (j = 0; ms[j] != NULLMOVE; j++) { - cc = apply_move(ms[j], c); - ii = td->pd->coord->index(cc); + ii = td->pd->coord->move(ms[j], i); ichunk = findchunk(td->pd, td->nchunks, ii); pthread_mutex_lock(td->mutex[ichunk]); pval = ptableval_index(td->pd, ii); if (pval > td->d+1) { - ptable_update(td->pd, cc, td->d+1); + ptable_update_index(td->pd, + ii, td->d+1); updated++; } pthread_mutex_unlock(td->mutex[ichunk]); diff --git a/src/symcoord.c b/src/symcoord.c @@ -4,27 +4,43 @@ #define CLASSES_CP_16 2768 #define CLASSES_EOFBEPOS_16 64430 -static Cube antindex_cp_sym16(uint64_t ind); -static Cube antindex_eofbepos_sym16(uint64_t ind); -static Cube antindex_drud_sym16(uint64_t ind); -static Cube antindex_drudfin_noE_sym16(uint64_t ind); -static Cube antindex_nxopt31(uint64_t ind); - static uint64_t index_cp_sym16(Cube cube); static uint64_t index_eofbepos_sym16(Cube cube); static uint64_t index_drud_sym16(Cube cube); static uint64_t index_drudfin_noE_sym16(Cube cube); static uint64_t index_nxopt31(Cube cube); -static int transfinder_drud_sym16(uint64_t ind, Trans *ret); -static int transfinder_drudfin_noE_sym16(uint64_t ind, Trans *ret); -static int transfinder_nxopt31(uint64_t ind, Trans *ret); +static uint64_t move_cp_sym16(Move m, uint64_t ind); +static uint64_t move_eofbepos_sym16(Move m, uint64_t ind); +static uint64_t move_drud_sym16(Move m, uint64_t ind); +static uint64_t move_drudfin_noE_sym16(Move m, uint64_t ind); +static uint64_t move_nxopt31(Move m, uint64_t ind); + +static uint64_t transform_cp(Trans t, uint64_t ind); +static uint64_t transform_eofbepos(Trans t, uint64_t ind); +static uint64_t transform_drud_sym16(Trans t, uint64_t ind); +static uint64_t transform_drudfin_noE_sym16(Trans t, uint64_t ind); +static uint64_t transform_nxopt31(Trans t, uint64_t ind); static void gensym(SymData *sd); +static void init_symc_moves(); +static void init_symc_trans(); static bool read_symdata_file(SymData *sd); -static int selfsims(SymData *sd, uint64_t ind, Trans *ret); static bool write_symdata_file(SymData *sd); +/* Some tables ***************************************************************/ + +static uint64_t move_cp_16[NMOVES][CLASSES_CP_16]; +static uint64_t move_eofbepos_16[NMOVES][CLASSES_EOFBEPOS_16]; + +static int trans_eofbepos[NTRANS][POW2TO11*BINOM12ON4]; +static int trans_epud[NTRANS][FACTORIAL8]; +static int trans_cpud_separate[NTRANS][BINOM8ON4]; + +static Trans ttrep_move_cp_16[NMOVES][CLASSES_CP_16]; +static Trans ttrep_move_eofbepos_16[NMOVES][CLASSES_EOFBEPOS_16]; + + /* Transformation groups and symmetry data ***********************************/ static Trans @@ -37,20 +53,22 @@ trans_group_udfix[16] = { static SymData sd_cp_16 = { - .filename = "sd_cp_16", + .filename = "sd_cp_16_new", .coord = &coord_cp, .sym_coord = &coord_cp_sym16, .ntrans = 16, - .trans = trans_group_udfix + .trans = trans_group_udfix, + .transform = transform_cp, }; static SymData sd_eofbepos_16 = { - .filename = "sd_eofbepos_16", + .filename = "sd_eofbepos_16_new", .coord = &coord_eofbepos, .sym_coord = &coord_eofbepos_sym16, .ntrans = 16, - .trans = trans_group_udfix + .trans = trans_group_udfix, + .transform = transform_eofbepos, }; SymData * all_sd[] = { @@ -65,90 +83,44 @@ SymData * all_sd[] = { Coordinate coord_eofbepos_sym16 = { .index = index_eofbepos_sym16, - .cube = antindex_eofbepos_sym16, + .move = move_eofbepos_sym16, }; Coordinate coord_cp_sym16 = { .index = index_cp_sym16, - .cube = antindex_cp_sym16, + .move = move_cp_sym16, }; Coordinate coord_drud_sym16 = { .index = index_drud_sym16, - .cube = antindex_drud_sym16, + .move = move_drud_sym16, .max = POW3TO7 * CLASSES_EOFBEPOS_16, - .transfind = transfinder_drud_sym16, + .transform = transform_drud_sym16, + .sd = &sd_cp_16, }; Coordinate coord_drudfin_noE_sym16 = { .index = index_drudfin_noE_sym16, - .cube = antindex_drudfin_noE_sym16, + .move = move_drudfin_noE_sym16, .max = FACTORIAL8 * CLASSES_CP_16, - .transfind = transfinder_drudfin_noE_sym16, + .transform = transform_drudfin_noE_sym16, + .sd = &sd_eofbepos_16, }; Coordinate coord_nxopt31 = { .index = index_nxopt31, - .cube = antindex_nxopt31, + .move = move_nxopt31, .max = POW3TO7 * BINOM8ON4 * CLASSES_EOFBEPOS_16, - .transfind = transfinder_nxopt31, + .transform = transform_nxopt31, + .sd = &sd_eofbepos_16, }; /* Functions *****************************************************************/ -static Cube -antindex_cp_sym16(uint64_t ind) -{ - return sd_cp_16.rep[ind]; -} - -static Cube -antindex_eofbepos_sym16(uint64_t ind) -{ - return sd_eofbepos_16.rep[ind]; -} - -static Cube -antindex_drud_sym16(uint64_t ind) -{ - Cube c; - - c = antindex_eofbepos_sym16(ind/POW3TO7); - c.coud = ind % POW3TO7; - c.cofb = c.coud; - c.corl = c.coud; - - return c; -} - -static Cube -antindex_drudfin_noE_sym16(uint64_t ind) -{ - Cube c1, c2; - - c1 = coord_epud.cube(ind % FACTORIAL8); - c2 = antindex_cp_sym16(ind/FACTORIAL8); - c1.cp = c2.cp; - - return c1; -} - -static Cube -antindex_nxopt31(uint64_t ind) -{ - Cube c; - - c = antindex_eofbepos_sym16(ind/(BINOM8ON4*POW3TO7)); - c.cp = coord_cpud_separate.cube(ind % BINOM8ON4).cp; - c.coud = (ind / BINOM8ON4) % POW3TO7; - - return c; -} - static uint64_t index_cp_sym16(Cube cube) { @@ -198,6 +170,116 @@ index_nxopt31(Cube cube) return a * BINOM8ON4 + coord_cpud_separate.index((Cube){.cp = cp}); } +static uint64_t +move_cp_sym16(Move m, uint64_t ind) +{ + return move_cp_16[m][ind]; +} + +static uint64_t +move_eofbepos_sym16(Move m, uint64_t ind) +{ + return move_eofbepos_16[m][ind]; +} + +static uint64_t +move_drud_sym16(Move m, uint64_t ind) +{ + uint64_t coud, eofbepos; + Trans ttr; + + eofbepos = move_eofbepos_16[m][ind / POW3TO7]; + ttr = ttrep_move_eofbepos_16[m][ind / POW3TO7]; + coud = coud_mtable[m][ind % POW3TO7]; + coud = co_ttable[ttr][coud]; /* Source is always coud */ + + return eofbepos * POW3TO7 + coud; +} + +static uint64_t +move_drudfin_noE_sym16(Move m, uint64_t ind) +{ + uint64_t cp, epud; + Trans ttr; + + cp = move_cp_16[m][ind / FACTORIAL8]; + ttr = ttrep_move_cp_16[m][ind / FACTORIAL8]; + epud = coord_epud.move(m, ind % FACTORIAL8); + epud = trans_epud[ttr][epud]; + + return cp * FACTORIAL8 + epud; +} + +static uint64_t +move_nxopt31(Move m, uint64_t ind) +{ + uint64_t eofbepos, cpsep, coud; + Trans ttr; + + eofbepos = ind / (POW3TO7 * BINOM8ON4); + coud = (ind / BINOM8ON4) % POW3TO7; + cpsep = ind % BINOM8ON4; + + eofbepos = move_eofbepos_16[m][eofbepos]; + ttr = ttrep_move_eofbepos_16[m][eofbepos]; + coud = coud_mtable[m][coud]; + coud = co_ttable[ttr][coud]; /* Source is always coud */ + cpsep = coord_cpud_separate.move(m, cpsep); + cpsep = trans_cpud_separate[ttr][cpsep]; + + return (eofbepos * POW3TO7 + coud) * BINOM8ON4 + cpsep; +} + +static uint64_t +transform_cp(Trans t, uint64_t ind) +{ + return cp_ttable[t][ind]; +} + +static uint64_t +transform_eofbepos(Trans t, uint64_t ind) +{ + return trans_eofbepos[t][ind]; +} + +static uint64_t +transform_drud_sym16(Trans t, uint64_t ind) +{ + uint64_t coud, eofbepos; + + eofbepos = ind / POW3TO7; /* Assum trans fixes eofbepos */ + coud = co_ttable[t][ind % POW3TO7]; /* Source is always coud */ + + return eofbepos * POW3TO7 + coud; +} + +static uint64_t +transform_drudfin_noE_sym16(Trans t, uint64_t ind) +{ + uint64_t cp, epud; + + cp = ind / FACTORIAL8; /* Assume trans fixes eofbepos */ + epud = trans_epud[t][ind % FACTORIAL8]; + + return cp * FACTORIAL8 + epud; +} + +static uint64_t +transform_nxopt31(Trans t, uint64_t ind) +{ + uint64_t eofbepos, cpsep, coud; + + eofbepos = ind / (POW3TO7 * BINOM8ON4); + coud = (ind / BINOM8ON4) % POW3TO7; + cpsep = ind % BINOM8ON4; + + coud = co_ttable[t][coud]; /* Source is always coud */ + cpsep = trans_cpud_separate[t][cpsep]; + + return (eofbepos * POW3TO7 + coud) * BINOM8ON4 + cpsep; +} + +/* static int transfinder_drud_sym16(uint64_t ind, Trans *ret) { @@ -264,6 +346,8 @@ transfinder_nxopt31(uint64_t ind, Trans *ret) return naux[trueind]; } +*/ + /* Other functions ***********************************************************/ void @@ -271,7 +355,7 @@ free_sd(SymData *sd) { if (sd->generated) { free(sd->class); - free(sd->rep); + free(sd->unsym); free(sd->transtorep); } @@ -282,15 +366,16 @@ static void gensym(SymData *sd) { uint64_t i, in, nreps = 0; + Trans t; int j; - Cube c, d; if (sd->generated) return; sd->class = malloc(sd->coord->max * sizeof(uint64_t)); - sd->rep = malloc(sd->coord->max * sizeof(Cube)); + sd->unsym = malloc(sd->coord->max * sizeof(uint64_t)); sd->transtorep = malloc(sd->coord->max * sizeof(Trans)); + sd->selfsim = malloc(sd->coord->max * sizeof(uint64_t)); if (read_symdata_file(sd)) { sd->generated = true; @@ -304,16 +389,17 @@ gensym(SymData *sd) for (i = 0; i < sd->coord->max; i++) { if (sd->class[i] == sd->coord->max + 1) { - c = sd->coord->cube(i); - sd->rep[nreps] = c; + sd->unsym[nreps] = i; + sd->selfsim[nreps] = 0; for (j = 0; j < sd->ntrans; j++) { - d = apply_trans(sd->trans[j], c); - in = sd->coord->index(d); - - if (sd->class[in] == sd->coord->max + 1) { - sd->class[in] = nreps; - sd->transtorep[in] = - inverse_trans(sd->trans[j]); + t = sd->trans[j]; + in = sd->transform(t, i); + sd->class[in] = nreps; + if (in == i) { + sd->selfsim[nreps] |= (1 << t); + sd->transtorep[in] = uf; + } else { + sd->transtorep[in] = inverse_trans(t); } } nreps++; @@ -321,7 +407,8 @@ gensym(SymData *sd) } sd->sym_coord->max = nreps; - sd->rep = realloc(sd->rep, nreps * sizeof(Cube)); + sd->unsym = realloc(sd->unsym, nreps * sizeof(uint64_t)); + sd->selfsim = realloc(sd->selfsim, nreps * sizeof(uint64_t)); sd->generated = true; fprintf(stderr, "Found %" PRIu64 " classes\n", nreps); @@ -350,7 +437,8 @@ read_symdata_file(SymData *sd) return false; r = r && fread(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; - r = r && fread(sd->rep, sizeof(Cube), *sn, f) == *sn; + r = r && fread(sd->unsym, sizeof(uint64_t), *sn, f) == *sn; + r = r && fread(sd->selfsim, sizeof(uint64_t), *sn, f) == *sn; r = r && fread(sd->class, sizeof(uint64_t), n, f) == n; r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n; @@ -358,6 +446,7 @@ read_symdata_file(SymData *sd) return r; } +/* static int selfsims(SymData *sd, uint64_t ind, Trans *ret) { @@ -376,6 +465,7 @@ selfsims(SymData *sd, uint64_t ind, Trans *ret) return n; } +*/ static bool write_symdata_file(SymData *sd) @@ -395,7 +485,8 @@ write_symdata_file(SymData *sd) return false; r = r && fwrite(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; - r = r && fwrite(sd->rep, sizeof(Cube), *sn, f) == *sn; + r = r && fwrite(sd->unsym, sizeof(uint64_t), *sn, f) == *sn; + r = r && fwrite(sd->selfsim, sizeof(uint64_t), *sn, f) == *sn; r = r && fwrite(sd->class, sizeof(uint64_t), n, f) == n; r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n; @@ -403,6 +494,83 @@ write_symdata_file(SymData *sd) return r; } +static void +init_symc_moves() +{ + uint64_t i, ii; + Move j; + + for (i = 0; i < CLASSES_CP_16; i++) { + ii = sd_cp_16.unsym[i]; + for (j = 0; j < NMOVES; j++) { + move_cp_16[j][i] = sd_cp_16.coord->move(j, ii); + ttrep_move_cp_16[j][i] = sd_cp_16.transtorep[ii]; + } + } + + for (i = 0; i < CLASSES_EOFBEPOS_16; i++) { + ii = sd_eofbepos_16.unsym[i]; + for (j = 0; j < NMOVES; j++) { + move_eofbepos_16[j][i] = + sd_eofbepos_16.coord->move(j, ii); + ttrep_move_eofbepos_16[j][i] = + sd_eofbepos_16.transtorep[ii]; + } + } +} + +void +init_symc_trans() +{ + uint64_t i; + int j, cp; + int epe[4] = {FR, FL, BL, BR}; + int a[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 }; + Cube c; + CubeArray *arr, *aux; + Trans t; + + for (i = 0; i < POW2TO11*BINOM12ON4; i++) { + for (j = 0; j < 16; j++) { + t = trans_group_udfix[j]; + + arr = new_cubearray((Cube){0}, pf_edges); + int_to_sum_zero_array(i/BINOM12ON4, 2, 12, arr->eofb); + epos_to_compatible_ep((i%BINOM12ON4)*24, arr->ep, epe); + fix_eorleoud(arr); + c = arrays_to_cube(arr, pf_edges); + free_cubearray(arr, pf_edges); + + c = apply_trans(t, c); + trans_eofbepos[t][i] = + c.eofb * BINOM12ON4 + (c.epose / 24); + } + } + + aux = malloc(sizeof(CubeArray)); + aux->ep = a; + for (i = 0; i < FACTORIAL8; i++) { + index_to_perm(i, 8, a); + c = arrays_to_cube(aux, pf_ep); + for (j = 0; j < 16; j++) { + t = trans_group_udfix[j]; + arr = new_cubearray(apply_trans(t, c), pf_ep); + trans_epud[t][i] = perm_to_index(arr->ep, 8); + free_cubearray(arr, pf_ep); + } + } + free(aux); + + for (i = 0; i < BINOM8ON4; i++) { + cp = cpud_separate_ant[i]; + for (j = 0; j < 16; j++) { + t = trans_group_udfix[j]; + trans_cpud_separate[j][i] = + cpud_separate_ind[cp_ttable[t][cp]]; + } + } +} + void init_symcoord() { @@ -415,7 +583,11 @@ init_symcoord() init_coord(); + init_symc_trans(); + for (i = 0; all_sd[i] != NULL; i++) gensym(all_sd[i]); + + init_symc_moves(); } diff --git a/www/download/index.html b/www/download/index.html @@ -98,7 +98,7 @@ followed by </p> <pre><code>make install</code></pre> <p> -Then ollow the instructions below to install the pruning tables. +Then follow the instructions below to install the pruning tables. </p> <h3>Tables</h3> @@ -114,7 +114,7 @@ Then ollow the instructions below to install the pruning tables. </table> <p> <strong>Note:</strong> the version 2.0 at the end of the file name is -only indicative. Later versionw will use the same tables, unless +only indicative. Later versions will use the same tables, unless otherwise specified. </p>