commit 4fb67201414169a2687f41c4056b2e284b4938cb
parent 3568412f8f230774d0d11d7ed1c897424f95d3ef
Author: Sebastiano Tronto <sebastiano.tronto@gmail.com>
Date: Thu, 11 Nov 2021 22:05:00 +0100
Removed old files
Diffstat:
145 files changed, 0 insertions(+), 53517 deletions(-)
diff --git a/old/2020-unknown-date/cube_backup.c b/old/2020-unknown-date/cube_backup.c
@@ -1,527 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include "cube.h"
-
-/* The next few functions are used to convert from the Cube structure
- * representation to actual arrays of pieces. */
-void cube_to_ep_array(Cube cube, int ep[12]);
-void cube_to_eofb_array(Cube cube, int eo[12]);
-void cube_to_eorl_array(Cube cube, int eo[12]);
-void cube_to_eoud_array(Cube cube, int eo[12]);
-void cube_to_cp_array(Cube cube, int cp[8]);
-void cube_to_coud_array(Cube cube, int co[8]);
-void cube_to_cofb_array(Cube cube, int co[8]);
-void cube_to_corl_array(Cube cube, int co[8]);
-void cube_to_centerpos_array(Cube cube, int centerpos[6]);
-Cube ep_array_to_cube(int ep[12]);
-Cube eofb_array_to_cube(int eo[12]);
-Cube eorl_array_to_cube(int eo[12]);
-Cube eoud_array_to_cube(int eo[12]);
-Cube cp_array_to_cube(int cp[8]);
-Cube coud_array_to_cube(int co[8]);
-Cube cofb_array_to_cube(int co[8]);
-Cube corl_array_to_cube(int co[8]);
-Cube centerpos_array_to_cube(int centerpos[6]);
-Cube move_array(Cube cube, void (cube_to_arr)(Cube, int *),
- Cube (*arr_to_cube)(int *),
- int *perm, int *orient, int n, int m);
-
-
-/* Transition tables */
-int epose_ttable[NMOVES][factorial12/factorial8];
-int eposs_ttable[NMOVES][factorial12/factorial8];
-int eposm_ttable[NMOVES][factorial12/factorial8];
-int eofb_ttable[NMOVES][pow2to11];
-int eorl_ttable[NMOVES][pow2to11];
-int eoud_ttable[NMOVES][pow2to11];
-int cp_ttable[NMOVES][factorial8];
-int coud_ttable[NMOVES][pow3to7];
-int cofb_ttable[NMOVES][pow3to7];
-int corl_ttable[NMOVES][pow3to7];
-int centerpos_ttable[NMOVES][factorial6];
-
-char edge_string[12][5] = {
- "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR"
-};
-char corner_string[8][5] = { "UFR", "UFL", "UBL", "UBR", "DFR", "DFL", "DBL", "DBR" };
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-char move_string[NMOVES][5] = {
- "-",
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'",
-};
-
-int epe_solved[] = {FR, FL, BL, BR};
-int eps_solved[] = {UL, UR, DL, DR};
-int epm_solved[] = {UF, UB, DF, DB};
-
-/**************************/
-/* Internal use functions */
-/**************************/
-
-int cube_to_ep_array(Cube cube, int ep[12]) {
- int epe[4], eps[4], epm[4];
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_perm(cube.eposm % factorial(4), 4, epm);
-
- int epose[12], eposs[12], eposm[12];
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) {
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- }
-
- for (int i = 0, ie = 0, is = 0, im = 0; i < 12; i++) {
- if (epose[i]) ep[i] = epe_solved[epe[ie++]];
- if (eposs[i]) ep[i] = eps_solved[eps[is++]];
- if (eposm[i]) ep[i] = epm_solved[epm[im++]];
- }
-}
-
-void cube_to_eofb_array(Cube cube, int eo[12]) {
- int_to_sum_zero_array(cube.eofb, 2, 12, eo);
-}
-
-void cube_to_eorl_array(Cube cube, int eo[12]) {
- int_to_sum_zero_array(cube.eorl, 2, 12, eo);
-}
-
-void cube_to_eoud_array(Cube cube, int eo[12]) {
- int_to_sum_zero_array(cube.eoud, 2, 12, eo);
-}
-
-void cube_to_cp_array(Cube cube, int cp[8]) {
- index_to_perm(cube.cp, 8, cp);
-}
-
-void cube_to_coud_array(Cube cube, int co[8]) {
- int_to_sum_zero_array(cube.coud, 3, 8, co);
-}
-
-void cube_to_cofb_array(Cube cube, int co[8]) {
- int_to_sum_zero_array(cube.cofb, 3, 8, co);
-}
-
-void cube_to_corl_array(Cube cube, int co[8]) {
- int_to_sum_zero_array(cube.corl, 3, 8, co);
-}
-
-void cube_to_centerpos_array(Cube cube, int centerpos[6]) {
- index_to_perm(cube.centerpos, 6, centerpos);
-}
-
-Cube ep_array_to_cube(int ep[12]) {
- int epe[4], eps[4], epm[4];
- int epose[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposs[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposm[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- for (int i = 0, ie = 0, is = 0, im = 0; i < 12; i++) {
- for (int j = 0; j < 4; j++) {
- if (ep[i] == epe_solved[j]) { epe[ie++] = j; epose[i] = 1; }
- if (ep[i] == eps_solved[j]) { eps[is++] = j; eposs[i] = 1; }
- if (ep[i] == epm_solved[j]) { epm[im++] = j; eposm[i] = 1; }
- }
- }
- for (int i = 0; i < 4; i++) {
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- }
- return { .epose = factorial(4) * subset_to_index(epose, 12, 4)
- + perm_to_index(epe, 4),
- .eposs = factorial(4) * subset_to_index(eposs, 12, 4)
- + perm_to_index(eps, 4),
- .eposm = factorial(4) * subset_to_index(eposm, 12, 4)
- + perm_to_index(epm, 4) };
-}
-
-Cube eofb_array_to_cube(int eo[12]) {
- return { .eofb = digit_array_to_int(eo, 11, 2) };
-}
-
-Cube eorl_array_to_cube(int eo[12]) {
- return { .eorl = digit_array_to_int(eo, 11, 2) };
-}
-
-Cube eoud_array_to_cube(int eo[12]) {
- return { .eoud = digit_array_to_int(eo, 11, 2) };
-}
-
-Cube cp_array_to_cube(int cp[8]) {
- return { .cp = perm_to_index(cp, 8) };
-}
-
-Cube coud_array_to_cube(int co[8]) {
- return { .coud = digit_array_to_int(co, 7, 3) };
-}
-
-Cube cofb_array_to_cube(int co[8]) {
- return { .cofb = digit_array_to_int(co, 7, 3) };
-}
-
-Cube corl_array_to_cube(int co[8]) {
- return { .corl = digit_array_to_int(co, 7, 3) };
-}
-
-Cube centerpos_array_to_cube(int centerpos[6]) {
- return { .centerpos = perm_to_index(centerpos, 6) };
-}
-
-Cube move_array(Cube cube, void (*cube_to_arr)(Cube, int *),
- void (*arr_to_cube)(int *),
- int *perm, int *orient, int n, int m) {
- int arr[n];
- cube_to_arr(cube, arr);
- apply_permutation(perm, arr, n);
- sum_arrays_mod(arr, orient, n, m);
- return arr_to_cube(arr);
-}
-
-/***********************/
-/* Interface functions */
-/***********************/
-
-Move inverse(Move m) {
- if (m == NULLMOVE)
- return m;
- int mod = (m-1)%3;
- Move base = m - mod;
- return base + 2 - mod;
-}
-
-void copy_alg(NissMove *src, NissMove *dest) {
- for (int i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
-}
-
-bool commute(Move m1, Move m2) {
- return equal(apply_move(m2, apply_move(m1, {0})),
- apply_move(m1, apply_move(m2, {0})));
-}
-
-bool equal(Cube c1, Cube c2) {
- return c1.eofb == c2.eofb && c1.epose == c2.epose &&
- c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
- c1.coud == c2.coud && c1.cp == c2.cp &&
- c1.centerpos == c2.centerpos;
-}
-
-bool solvable(Cube cube) {
- /* Since we memorize orientation truncating the last digit, we only need to
- * check that the permutations have the correct sign. */
- /* TODO: add check that every integer is in range */
- int ep[12], cp[12], c[6];
- /* TODO: change to use cube-specific functions */
- cube_to_ep_array(cube, ep);
- cube_to_cp_array(cube, 8, cp);
- cube_to_centerpos_array(cube, 6, c);
- return (perm_sign(ep, 12) ^ perm_sign(c, 6)) == perm_sign(cp, 8);
-}
-
-bool is_solved(Cube cube) {
- return (!cube.eofb && !cube.coud && !cube.cp &&
- !cube.epose && !cube.eposs && !cube.eposm && !cube.centerpos);
-}
-
-char *to_string(Cube cube) {
- int eo[12], co[8], ep[12], cp[8], cenpos[6];
- cube_to_eofb_array(cube, eo);
- cube_to_coud_array(cube, co);
- cube_to_ep_array(cube, ep);
- cube_to_cp_array(cube, cp);
- cube_to_centerpos_array(cube, cenpos);
-
- static char ret[1000];
-
- for (int i = 0; i < 12; i++) {
- strcat(ret, " ");
- strcat(ret, edge_string[ep[i]]);
- strcat(ret, " ");
- }
- strcat(ret, "\n");
- for (int i = 0; i < 12; i++) {
- strcat(ret, " ");
- char num[2] = { [0] = eo[i] + '0', [1] = 0 };
- strcat(ret, num);
- strcat(ret, " ");
- }
- strcat(ret, "\n");
- for (int i = 0; i < 8; i++) {
- strcat(ret, corner_string[cp[i]]);
- strcat(ret, " ");
- }
- strcat(ret, "\n");
- for (int i = 0; i < 8; i++) {
- strcat(ret, " ");
- char num[2] = { [0] = co[i] + '0', [1] = 0 };
- strcat(ret, num);
- strcat(ret, " ");
- }
- strcat(ret, "\n");
- for (int i = 0; i < 6; i++) {
- strcat(ret, " ");
- strcat(ret, center_string[cenpos[i]]);
- strcat(ret, " ");
- }
- strcat(ret, "\n");
-
- return ret;
-}
-
-void init_ttables() {
- FILE *ttf;
-
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- for (int m = 0; m < NMOVES; m++) {
- fread(epose_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fread(eposs_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fread(eposm_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fread(eofb_ttable[m], sizeof(int), pow2to11, ttf);
- fread(eorl_ttable[m], sizeof(int), pow2to11, ttf);
- fread(eoud_ttable[m], sizeof(int), pow2to11, ttf);
- fread(cp_ttable[m], sizeof(int), factorial8, ttf);
- fread(coud_ttable[m], sizeof(int), pow3to7, ttf);
- fread(corl_ttable[m], sizeof(int), pow3to7, ttf);
- fread(cofb_ttable[m], sizeof(int), pow3to7, ttf);
- fread(centerpos_ttable[m], sizeof(int), factorial6, ttf);
- }
- fclose(ttf);
- } else {
- ttf = fopen("ttables", "wb");
- int empty[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- /* For each type of pieces only the effects of U, x and y are described */
- int edge_cycle[NMOVES][12] = {
- [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [X] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [Y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL},
- };
- int eofb_flipped[NMOVES][12] = {
- [X] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [Y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 },
- };
- int eorl_flipped[NMOVES][12] = {
- [X] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [Y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 },
- };
- int eoud_flipped[NMOVES][12] = {
- [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [X] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [Y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- };
- int corner_cycle[NMOVES][8] = {
- [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [X] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [Y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL},
- };
- int coud_flipped[NMOVES][8] = {
- [X] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2},
- };
- int corl_flipped[NMOVES][8] = {
- [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [Y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1},
- };
- int cofb_flipped[NMOVES][8] = {
- [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [X] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=2,[UFL]=1,[DBL]=1,[DFL]=2},
- [Y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2},
- };
- int center_cycle[NMOVES][6] = {
- [X] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [Y] = {U_center, D_center, B_center, F_center, R_center, L_center},
- };
-
- /* Each move is reduced to a combination of U, x and y using this table */
- Move equiv_moves[NMOVES][13] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { X, X, U, X, X, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { X, X, U, U, X, X, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { X, X, U, U, U, X, X, 0, 0, 0, 0, 0, 0 },
- [R] = { Y, X, U, X, X, X, Y, Y, Y, 0, 0, 0, 0 },
- [R2] = { Y, X, U, U, X, X, X, Y, Y, Y, 0, 0, 0 },
- [R3] = { Y, X, U, U, U, X, X, X, Y, Y, Y, 0, 0 },
- [L] = { Y, Y, Y, X, U, X, X, X, Y, 0, 0, 0, 0 },
- [L2] = { Y, Y, Y, X, U, U, X, X, X, Y, 0, 0, 0 },
- [L3] = { Y, Y, Y, X, U, U, U, X, X, X, Y, 0, 0 },
- [F] = { X, U, X, X, X, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { X, U, U, X, X, X, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { X, U, U, U, X, X, X, 0, 0, 0, 0, 0, 0 },
- [B] = { X, X, X, U, X, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { X, X, X, U, U, X, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { X, X, X, U, U, U, X, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { X, X, U, X, X, Y, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { X, X, U, U, X, X, Y, Y, 0, 0, 0, 0, 0 },
- [Uw3] = { X, X, U, U, U, X, X, Y, Y, Y, 0, 0, 0 },
- [Dw] = { U, Y, Y, Y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, Y, Y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, Y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { Y, Y, Y, X, U, X, X, X, Y, X, 0, 0, 0 },
- [Rw2] = { Y, Y, Y, X, U, U, X, X, X, Y, X, X, 0 },
- [Rw3] = { Y, Y, Y, X, U, U, U, Y, X, X, X, Y, 0 },
- [Lw] = { Y, X, U, X, X, X, Y, Y, Y, X, X, X, 0 },
- [Lw2] = { Y, X, U, U, X, X, X, Y, Y, Y, X, X, 0 },
- [Lw3] = { Y, X, U, U, U, X, X, X, Y, Y, Y, X, 0 },
- [Fw] = { X, X, X, U, Y, Y, Y, X, 0, 0, 0, 0, 0 },
- [Fw2] = { X, X, X, U, U, Y, Y, X, 0, 0, 0, 0, 0 },
- [Fw3] = { X, X, X, U, U, U, Y, X, 0, 0, 0, 0, 0 },
- [Bw] = { X, U, Y, Y, Y, X, X, X, 0, 0, 0, 0, 0 },
- [Bw2] = { X, U, U, Y, Y, X, X, X, 0, 0, 0, 0, 0 },
- [Bw3] = { X, U, U, U, Y, X, X, X, 0, 0, 0, 0, 0 },
-
- [M] = { Y, X, U, X, X, U, U, U, Y, X, Y, Y, Y },
- [M2] = { Y, X, U, U, X, X, U, U, X, X, X, Y, 0 },
- [M3] = { Y, X, U, U, U, X, X, U, Y, X, X, X, Y },
- [S] = { X, U, U, U, X, X, U, Y, Y, Y, X, 0, 0 },
- [S2] = { X, U, U, X, X, U, U, Y, Y, X, 0, 0, 0 },
- [S3] = { X, U, X, X, U, U, U, Y, X, 0, 0, 0, 0 },
- [E] = { U, X, X, U, U, U, X, X, Y, Y, Y, 0, 0 },
- [E2] = { U, U, X, X, U, U, X, X, Y, Y, 0, 0, 0 },
- [E3] = { U, U, U, X, X, U, X, X, Y, 0, 0, 0, 0 },
-
- [X] = { X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [X2] = { X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [X3] = { X, X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Y] = { Y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Y2] = { Y, Y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Y3] = { Y, Y, Y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Z] = { Y, Y, Y, X, Y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Z2] = { Y, Y, X, X, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Z3] = { Y, X, Y, Y, Y, 0, 0, 0, 0, 0, 0, 0, 0 },
- };
-
- /* Generate all move cycles and flips */
- for (int i = 0; i < NMOVES; i++) {
- if (i == U || i == X || i == Y)
- continue;
-
- Cube cube = {0};
-
- cube_to_ep_array(&cube, edge_cycle[i]);
- cube_to_eofb_array(&cube, eofb_flipped[i]);
- cube_to_eorl_array(&cube, eorl_flipped[i]);
- cube_to_eoud_array(&cube, eoud_flipped[i]);
- cube_to_cp_array(&cube, corner_cycle[i]);
- cube_to_coud_array(&cube, coud_flipped[i]);
- cube_to_cofb_array(&cube, cofb_flipped[i]);
- cube_to_corl_array(&cube, corl_flipped[i]);
- cube_to_centerpos_array(&cube, center_cycle[i]);
-
- for (int j = 0; equiv_moves[i][j]; j++) {
- int m = equiv_moves[i][j];
-
- apply_permutation(edge_cycle[m], edge_cycle[i], 12);
- apply_permutation(edge_cycle[m], eofb_flipped[i], 12);
- apply_permutation(edge_cycle[m], eorl_flipped[i], 12);
- apply_permutation(edge_cycle[m], eoud_flipped[i], 12);
-
- sum_arrays_mod(eofb_flipped[i], eofb_flipped[m], 12, 2);
- sum_arrays_mod(eorl_flipped[i], eorl_flipped[m], 12, 2);
- sum_arrays_mod(eoud_flipped[i], eoud_flipped[m], 12, 2);
-
- apply_permutation(corner_cycle[m], corner_cycle[i], 8);
- apply_permutation(corner_cycle[m], coud_flipped[i], 8);
- apply_permutation(corner_cycle[m], cofb_flipped[i], 8);
- apply_permutation(corner_cycle[m], corl_flipped[i], 8);
-
- sum_arrays_mod(coud_flipped[i], coud_flipped[m], 8, 3);
- sum_arrays_mod(corl_flipped[i], corl_flipped[m], 8, 3);
- sum_arrays_mod(cofb_flipped[i], cofb_flipped[m], 8, 3);
-
- apply_permutation(center_cycle[m], center_cycle[i], 6);
- }
- }
-
- /* Initialize transition tables */
- for (int m = 0; m < NMOVES; m++) {
- for (int i = 0; i < factorial12/factorial8; i++) {
- Cube cube = { .epose = i };
- move_array(&cube, cube_to_ep_array, ep_array_to_cube,
- edge_cycle[m], empty, 12, 1);
- epose_ttable[m][i] = cube.epose;
- cube.eposs = i;
- move_array(&cube, cube_to_ep_array, ep_array_to_cube,
- edge_cycle[m], empty, 12, 1);
- eposs_ttable[m][i] = cube.eposs;
- cube.eposm = i;
- move_array(&cube, cube_to_ep_array, ep_array_to_cube,
- edge_cycle[m], empty, 12, 1);
- eposm_ttable[m][i] = cube.eposm;
- }
- for (int i = 0; i < pow2to11; i++ ) {
- Cube cube = { .eofb = i, .eorl = i, .eoud = i };
- move_array(&cube, cube_to_eofb_array, eofb_array_to_cube,
- edge_cycle[m], eofb_flipped[m], 12, 2);
- move_array(&cube, cube_to_eorl_array, eorl_array_to_cube,
- edge_cycle[m], eorl_flipped[m], 12, 2);
- move_array(&cube, cube_to_eoud_array, eoud_array_to_cube,
- edge_cycle[m], eoud_flipped[m], 12, 2);
- eofb_ttable[m][i] = cube.eofb;
- eorl_ttable[m][i] = cube.eorl;
- eoud_ttable[m][i] = cube.eoud;
- }
- for (int i = 0; i < factorial8; i++) {
- /* TODO: Maybe do this by hand to optimize? */
- Cube cube = { .cp = i };
- move_array(&cube, cube_to_cp_array, ep_array_to_cube,
- corner_cycle[m], empty, 8, 1);
- cp_ttable[m][i] = cube.cp;
- }
- for (int i = 0; i < pow3to7; i++) {
- Cube cube = { .coud = i, .corl = i, .cofb = i };
- move_array(&cube, cube_to_coud_array, coud_array_to_cube,
- corner_cycle[m], coud_flipped[m], 8, 3);
- move_array(&cube, cube_to_corl_array, corl_array_to_cube,
- corner_cycle[m], corl_flipped[m], 8, 3);
- move_array(&cube, cube_to_cofb_array, cofb_array_to_cube,
- corner_cycle[m], cofb_flipped[m], 8, 3);
- coud_ttable[m][i] = cube.coud;
- corl_ttable[m][i] = cube.corl;
- cofb_ttable[m][i] = cube.cofb;
- }
- for (int i = 0; i < factorial6; i++) {
- Cube cube = { .centerpos = i };
- move_array(&cube, cube_to_centerpos_array, centerpos_array_to_cube,
- center_cycle[m], empty, 6, 1);
- centerpos_ttable[m][i] = cube.centerpos;
- }
- fwrite(epose_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fwrite(eposs_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fwrite(eposm_ttable[m], sizeof(int), factorial12/factorial8, ttf);
- fwrite(eofb_ttable[m], sizeof(int), pow2to11, ttf);
- fwrite(eorl_ttable[m], sizeof(int), pow2to11, ttf);
- fwrite(eoud_ttable[m], sizeof(int), pow2to11, ttf);
- fwrite(cp_ttable[m], sizeof(int), factorial8, ttf);
- fwrite(coud_ttable[m], sizeof(int), pow3to7, ttf);
- fwrite(corl_ttable[m], sizeof(int), pow3to7, ttf);
- fwrite(cofb_ttable[m], sizeof(int), pow3to7, ttf);
- fwrite(centerpos_ttable[m], sizeof(int), factorial6, ttf);
- }
- fclose(ttf);
- }
-}
-
-Cube apply_move(Move m, Cube cube) {
- Cube moved = cube;
-
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.cp = cp_ttable[m][cube.cp];
- moved.centerpos = centerpos_ttable[m][cube.centerpos];
-
- return moved;
-}
diff --git a/old/2020-unknown-date/cubeutils.c b/old/2020-unknown-date/cubeutils.c
@@ -1,100 +0,0 @@
-#include <stdio.h>
-#include "utils.h"
-#include "pieces.h"
-#include "cubeutils.h"
-
-int epe_solved[] = {FR, FL, BL, BR};
-int eps_solved[] = {UL, UR, DL, DR};
-int epm_solved[] = {UF, UB, DF, DB};
-
-void cube_to_ep_array(Cube *cube, int ep[12]) {
- int epe[4], eps[4], epm[4];
- index_to_perm(cube->epose % factorial(4), 4, epe);
- index_to_perm(cube->eposs % factorial(4), 4, eps);
- index_to_perm(cube->eposm % factorial(4), 4, epm);
-
- int epose[12], eposs[12], eposm[12];
- index_to_subset(cube->epose / factorial(4), 12, 4, epose);
- index_to_subset(cube->eposs / factorial(4), 12, 4, eposs);
- index_to_subset(cube->eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) {
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- }
-
- for (int i = 0, ie = 0, is = 0, im = 0; i < 12; i++) {
- if (epose[i]) ep[i] = epe_solved[epe[ie++]];
- if (eposs[i]) ep[i] = eps_solved[eps[is++]];
- if (eposm[i]) ep[i] = epm_solved[epm[im++]];
- }
-}
-
-void ep_array_to_epos(int ep[12], Cube *cube) {
- int epe[4], eps[4], epm[4];
- int epose[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposs[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposm[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- for (int i = 0, ie = 0, is = 0, im = 0; i < 12; i++) {
- for (int j = 0; j < 4; j++) {
- if (ep[i] == epe_solved[j]) { epe[ie++] = j; epose[i] = 1; }
- if (ep[i] == eps_solved[j]) { eps[is++] = j; eposs[i] = 1; }
- if (ep[i] == epm_solved[j]) { epm[im++] = j; eposm[i] = 1; }
- }
- }
- for (int i = 0; i < 4; i++) {
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- }
- cube->epose = factorial(4) * subset_to_index(epose, 12, 4)
- + perm_to_index(epe, 4);
- cube->eposs = factorial(4) * subset_to_index(eposs, 12, 4)
- + perm_to_index(eps, 4);
- cube->eposm = factorial(4) * subset_to_index(eposm, 12, 4)
- + perm_to_index(epm, 4);
-}
-
-bool solvable(Cube *cube) {
- /* Since we memorize orientation truncating the last digit, we only need to
- * check that the permutations have the correct sign. */
- /* TODO: add check that every integer is in range */
- int ep[12], cp[12], c[6];
- cube_to_ep_array(cube, ep);
- index_to_perm(cube->cp, 8, cp);
- index_to_perm(cube->centerpos, 6, c);
- return (perm_sign(ep, 12) ^ perm_sign(c, 6)) == perm_sign(cp, 8);
-}
-
-Cube *solved_cube() {
- static Cube cube = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- return &cube;
-}
-
-bool solved(Cube *cube) {
- return (cube->eofb == 0 && cube->coud == 0 && cube->cp == 0 &&
- cube->epose == 0 && cube->eposs == 0 && cube->eposm == 0 &&
- cube->centerpos == 0);
-}
-
-char *to_string(Cube *cube) {
- int eo[12], co[8], ep[12], cp[8], cenpos[6];
- cube_to_eofb_array(cube->eofb, eo);
- cube_to_coud_array(cube->coud, co);
- cube_to_ep_array(cube, ep);
- cube_to_cp_array(cube->cp, cp);
- cube_to_centerpos_array(cube->centerpos, cenpos);
-
- char *ret[1000];
-
- for (int i = 0; i < 12; i++) sprintf(ret, " %s ", edge_string[ep[i]]);
- sprintf(ret, "\n");
- for (int i = 0; i < 12; i++) sprintf(ret, " %d ", eo[i]);
- sprintf(ret, "\n");
- for (int i = 0; i < 8; i++) sprintf(ret, "%s ", corner_string[cp[i]]);
- sprintf(ret, "\n");
- for (int i = 0; i < 8; i++) sprintf(ret, " %d ", co[i]);
- sprintf(ret, "\n");
- for (int i = 0; i < 6; i++) sprintf(ret, " %s ", center_string[cenpos[i]]);
- sprintf(ret, "\n");
-
- return ret;
-}
diff --git a/old/2020-unknown-date/cubeutils.h b/old/2020-unknown-date/cubeutils.h
@@ -1,18 +0,0 @@
-/* Cube-specific utility functions */
-
-#ifndef CUBEUTILS_H
-#define CUBEUTILS_H
-
-#include <stdbool.h>
-#include "pieces.h"
-
-void cube_to_ep_array(Cube *cube, int ep[12]);
-void ep_array_to_epos(int ep[12], Cube *cube);
-
-Cube *solved_cube();
-bool solvable(Cube *cube);
-bool solved(Cube *cube);
-
-void print(Cube *cube);
-
-#endif
diff --git a/old/2020-unknown-date/moves.c b/old/2020-unknown-date/moves.c
@@ -1,57 +0,0 @@
-#include <stdbool.h>
-#include "pieces.h"
-#include "moves.h"
-#include "utils.h"
-
-/* Transition tables */
-int eofb_ttable[pow2to11][NULLMOVE];
-int eorl_ttable[pow2to11][NULLMOVE];
-int eoud_ttable[pow2to11][NULLMOVE];
-int coud_ttable[pow3to7][NULLMOVE];
-int cofb_ttable[pow3to7][NULLMOVE];
-int corl_ttable[pow3to7][NULLMOVE];
-int epose_ttable[factorial12/factorial8][NULLMOVE];
-int eposs_ttable[factorial12/factorial8][NULLMOVE];
-int eposm_ttable[factorial12/factorial8][NULLMOVE];
-int cp_ttable[factorial8][NULLMOVE];
-int centerpos_ttable[factorial6][NULLMOVE];
-
-void apply_move_ep(Move m, int a[12]) {
- int aux[12];
- intarrcopy(a, aux, 12);
- for (int i = 0; i < 12; i++)
- a[i] = aux[edge_cycle[m][i]];
-}
-
-void apply_move_cp(Move m, int a[8]) {
- int aux[8];
- intarrcopy(a, aux, 8);
- for (int i = 0; i < 8; i++)
- a[i] = aux[corner_cycle[m][i]];
-}
-
-void apply_move_centerpos(Move m, int a[6]) {
- int aux[6];
- intarrcopy(a, aux, 6);
- for (int i = 0; i < 6; i++)
- a[i] = aux[center_cycle[m][i]];
-}
-
-void init_ttables() {
- /* TODO */
-}
-
-void apply_move(Move m, Cube *cube) {
- cube->eofb = eofb_ttable[cube->eofb][m];
- cube->eorl = eorl_ttable[cube->eorl][m];
- cube->eoud = eoud_ttable[cube->eoud][m];
- cube->coud = coud_ttable[cube->coud][m];
- cube->cofb = cofb_ttable[cube->cofb][m];
- cube->corl = corl_ttable[cube->corl][m];
- cube->epose = epose_ttable[cube->epose][m];
- cube->eposs = eposs_ttable[cube->eposs][m];
- cube->eposm = eposm_ttable[cube->eposm][m];
- cube->cp = cp_ttable[cube->cp][m];
- cube->centerpos = centerpos_ttable[cube->centerpos][m];
-}
-
diff --git a/old/2020-unknown-date/moves.h b/old/2020-unknown-date/moves.h
@@ -1,9 +0,0 @@
-/* Moves and transition tables */
-
-#ifndef MOVES_H
-#define MOVES_H
-
-void apply_move(Move m, Cube *cube);
-void init_ttables();
-
-#endif
diff --git a/old/2020-unknown-date/pieces.c b/old/2020-unknown-date/pieces.c
@@ -1,208 +0,0 @@
-#include "pieces.h"
-
-char edge_string[12][5] = {
- "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR"
-};
-
-char corner_string[8][5] = {
- "UFR", "UFL", "UBL", "UBR", "DFR", "DFL", "DBL", "DBR"
-};
-
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-
-char move_string[NULLMOVE+1][5] = {
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'",
- "-"
-};
-
-int edge_cycle[NULLMOVE+1][12] = {
- [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [U2] = {UB, UR, UF, UL, DF, DL, DB, DR, FR, FL, BL, BR},
- [U3] = {UL, UB, UR, UF, DF, DL, DB, DR, FR, FL, BL, BR},
- [D] = {UF, UL, UB, UR, DL, DB, DR, DF, FR, FL, BL, BR},
- [D2] = {UF, UL, UB, UR, DB, DR, DF, DL, FR, FL, BL, BR},
- [D3] = {UF, UL, UB, UR, DR, DF, DL, DB, FR, FL, BL, BR},
- [R] = {UF, UL, UB, FR, DF, DL, DB, BR, DR, FL, BL, UR},
- [R2] = {UF, UL, UB, DR, DF, DL, DB, UR, BR, FL, BL, FR},
- [R3] = {UF, UL, UB, BR, DF, DL, DB, FR, UR, FL, BL, DR},
- [L] = {UF, BL, UB, UR, DF, FL, DB, DR, FR, UL, DL, BR},
- [L2] = {UF, DL, UB, UR, DF, UL, DB, DR, FR, BL, FL, BR},
- [L3] = {UF, FL, UB, UR, DF, BL, DB, DR, FR, DL, UL, BR},
- [F] = {FL, UL, UB, UR, FR, DL, DB, DR, UF, DF, BL, BR},
- [F2] = {DF, UL, UB, UR, UF, DL, DB, DR, FL, FR, BL, BR},
- [F3] = {FR, UL, UB, UR, FL, DL, DB, DR, DF, UF, BL, BR},
- [B] = {UF, UL, BR, UR, DF, DL, BL, DR, FR, FL, UB, DB},
- [B2] = {UF, UL, DB, UR, DF, DL, UB, DR, FR, FL, BR, BL},
- [B3] = {UF, UL, BL, UR, DF, DL, BR, DR, FR, FL, DB, UB},
-
- [Uw] = {UR, UF, UL, UB, DF, DL, DB, DR, BR, FR, FL, BL},
- [Uw2] = {UB, UR, UF, UL, DF, DL, DB, DR, BL, BR, FR, FL},
- [Uw3] = {UL, UB, UR, UF, DF, DL, DB, DR, FL, BL, BR, FR},
- [Dw] = {UF, UL, UB, UR, DL, DB, DR, DF, FL, BL, BR, FR},
- [Dw2] = {UF, UL, UB, UR, DB, DR, DF, DL, BL, BR, FR, FL},
- [Dw3] = {UF, UL, UB, UR, DR, DF, DL, DB, BR, FR, FL, BL},
- [Rw] = {DF, UL, UF, FR, DB, DL, UB, BR, DR, FL, BL, UR},
- [Rw2] = {DB, UL, DF, DR, UB, DL, UF, UR, BR, FL, BL, FR},
- [Rw3] = {UB, UL, DB, BR, UF, DL, DF, FR, UR, FL, BL, DR},
- [Lw] = {UB, BL, DB, UR, UF, FL, DF, DR, FR, UL, DL, BR},
- [Lw2] = {DB, DL, DF, UR, UB, UL, UF, DR, FR, BL, FL, BR},
- [Lw3] = {DF, FL, UF, UR, DB, BL, UB, DR, FR, DL, UL, BR},
- [Fw] = {FL, DL, UB, UL, FR, DR, DB, UR, UF, DF, BL, BR},
- [Fw2] = {DF, DR, UB, DL, UF, UR, DB, UL, FL, FR, BL, BR},
- [Fw3] = {FR, UR, UB, DR, FL, UL, DB, DL, DF, UF, BL, BR},
- [Bw] = {UF, UR, BR, DR, DF, UL, BL, DL, FR, FL, UB, DB},
- [Bw2] = {UF, DR, DB, DL, DF, UR, UB, UL, FR, FL, BR, BL},
- [Bw3] = {UF, DL, BL, UL, DF, DR, BR, UR, FR, FL, DB, UB},
-
- [M] = {UB, UL, DB, UR, UF, DL, DF, DR, FR, FL, BL, BR},
- [M2] = {DB, UL, DF, UR, UB, DL, UF, DR, FR, FL, BL, BR},
- [M3] = {DF, UL, UF, UR, DB, DL, UB, DR, FR, FL, BL, BR},
- [S] = {UF, DL, UB, UL, DF, DR, DB, UR, FR, FL, BL, BR},
- [S2] = {UF, DR, UB, DL, DF, UR, DB, UL, FR, FL, BL, BR},
- [S3] = {UF, UR, UB, DR, DF, UL, DB, DL, FR, FL, BL, BR},
- [E] = {UF, UL, UB, UR, DF, DL, DB, DR, FL, BL, BR, FR},
- [E2] = {UF, UL, UB, UR, DF, DL, DB, DR, BL, BR, FR, FL},
- [E3] = {UF, UL, UB, UR, DF, DL, DB, DR, BR, FR, FL, BL},
-
- [X] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [X2] = {DB, DL, DF, DR, UB, UL, UF, UR, BR, BL, FL, FR},
- [X3] = {UB, BL, DB, BR, UF, FL, DF, FR, UR, UL, DL, DR},
- [Y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL},
- [Y2] = {UB, UR, UF, UL, DB, DR, DF, DL, BL, BR, FR, FL},
- [Y3] = {UL, UB, UR, UF, DL, DB, DR, DF, FL, BL, BR, FR},
- [Z] = {FL, DL, BL, UL, FR, DR, BR, UR, UF, DF, DB, UB},
- [Z2] = {DF, DR, DB, DL, UF, UR, UB, UL, FL, FR, BR, BL},
- [Z3] = {FR, UR, BR, DR, FL, UL, BL, DL, DF, UF, UB, DB},
-
- [NULLMOVE] = {UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR},
-};
-
-int corner_cycle[NULLMOVE+1][8] = {
- [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [U2] = {UBL, UBR, UFR, UFL, DFR, DFL, DBL, DBR},
- [U3] = {UFL, UBL, UBR, UFR, DFR, DFL, DBL, DBR},
- [D] = {UFR, UFL, UBL, UBR, DFL, DBL, DBR, DFR},
- [D2] = {UFR, UFL, UBL, UBR, DBL, DBR, DFR, DFL},
- [D3] = {UFR, UFL, UBL, UBR, DBR, DFR, DFL, DBL},
- [R] = {DFR, UFL, UBL, UFR, DBR, DFL, DBL, UBR},
- [R2] = {DBR, UFL, UBL, DFR, UBR, DFL, DBL, UFR},
- [R3] = {UBR, UFL, UBL, DBR, UFR, DFL, DBL, DFR},
- [L] = {UFR, UBL, DBL, UBR, DFR, UFL, DFL, DBR},
- [L2] = {UFR, DBL, DFL, UBR, DFR, UBL, UFL, DBR},
- [L3] = {UFR, DFL, UFL, UBR, DFR, DBL, UBL, DBR},
- [F] = {UFL, DFL, UBL, UBR, UFR, DFR, DBL, DBR},
- [F2] = {DFL, DFR, UBL, UBR, UFL, UFR, DBL, DBR},
- [F3] = {DFR, UFR, UBL, UBR, DFL, UFL, DBL, DBR},
- [B] = {UFR, UFL, UBR, DBR, DFR, DFL, UBL, DBL},
- [B2] = {UFR, UFL, DBR, DBL, DFR, DFL, UBR, UBL},
- [B3] = {UFR, UFL, DBL, UBL, DFR, DFL, DBR, UBR},
-
- [Uw] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [Uw2] = {UBL, UBR, UFR, UFL, DFR, DFL, DBL, DBR},
- [Uw3] = {UFL, UBL, UBR, UFR, DFR, DFL, DBL, DBR},
- [Dw] = {UFR, UFL, UBL, UBR, DFL, DBL, DBR, DFR},
- [Dw2] = {UFR, UFL, UBL, UBR, DBL, DBR, DFR, DFL},
- [Dw3] = {UFR, UFL, UBL, UBR, DBR, DFR, DFL, DBL},
- [Rw] = {DFR, UFL, UBL, UFR, DBR, DFL, DBL, UBR},
- [Rw2] = {DBR, UFL, UBL, DFR, UBR, DFL, DBL, UFR},
- [Rw3] = {UBR, UFL, UBL, DBR, UFR, DFL, DBL, DFR},
- [Lw] = {UFR, UBL, DBL, UBR, DFR, UFL, DFL, DBR},
- [Lw2] = {UFR, DBL, DFL, UBR, DFR, UBL, UFL, DBR},
- [Lw3] = {UFR, DFL, UFL, UBR, DFR, DBL, UBL, DBR},
- [Fw] = {UFL, DFL, UBL, UBR, UFR, DFR, DBL, DBR},
- [Fw2] = {DFL, DFR, UBL, UBR, UFL, UFR, DBL, DBR},
- [Fw3] = {DFR, UFR, UBL, UBR, DFL, UFL, DBL, DBR},
- [Bw] = {UFR, UFL, UBR, DBR, DFR, DFL, UBL, DBL},
- [Bw2] = {UFR, UFL, DBR, DBL, DFR, DFL, UBR, UBL},
- [Bw3] = {UFR, UFL, DBL, UBL, DFR, DFL, DBR, UBR},
-
- [M] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [M2] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [M3] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [S] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [S2] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [S3] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [E] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [E2] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
- [E3] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
-
- [X] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [X2] = {DBR, DBL, DFL, DFR, UBR, UBL, UFL, UFR},
- [X3] = {UBR, UBL, DBL, DBR, UFR, UFL, DFL, DFR},
- [Y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL},
- [Y2] = {UBL, UBR, UFR, UFL, DBL, DBR, DFR, DFL},
- [Y3] = {UFL, UBL, UBR, UFR, DFL, DBL, DBR, DFR},
- [Z] = {UFL, DFL, DBL, UBL, UFR, DFR, DBR, UBR},
- [Z2] = {DFL, DFR, DBR, DBL, UFL, UFR, UBR, UBL},
- [Z3] = {DFR, UFR, UBR, DBR, DFL, UFL, UBL, DBL},
-
- [NULLMOVE] = {UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR},
-};
-
-int center_cycle[NULLMOVE+1][6] = {
- [U] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [U2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [U3] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [D] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [D2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [D3] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [R] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [R2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [R3] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [L] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [L2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [L3] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [F] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [F2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [F3] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [B] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [B2] = {U_center, D_center, R_center, L_center, F_center, B_center},
- [B3] = {U_center, D_center, R_center, L_center, F_center, B_center},
-
- [Uw] = {U_center, D_center, B_center, F_center, R_center, L_center},
- [Uw2] = {U_center, D_center, L_center, R_center, B_center, F_center},
- [Uw3] = {U_center, D_center, F_center, B_center, L_center, R_center},
- [Dw] = {U_center, D_center, F_center, B_center, L_center, R_center},
- [Dw2] = {U_center, D_center, L_center, R_center, B_center, F_center},
- [Dw3] = {U_center, D_center, B_center, F_center, R_center, L_center},
- [Rw] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [Rw2] = {D_center, U_center, R_center, L_center, B_center, F_center},
- [Rw3] = {B_center, F_center, R_center, L_center, U_center, D_center},
- [Lw] = {B_center, F_center, R_center, L_center, U_center, D_center},
- [Lw2] = {D_center, U_center, R_center, L_center, B_center, F_center},
- [Lw3] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [Fw] = {L_center, R_center, U_center, D_center, F_center, B_center},
- [Fw2] = {D_center, U_center, L_center, R_center, F_center, B_center},
- [Fw3] = {R_center, L_center, D_center, U_center, F_center, B_center},
- [Bw] = {R_center, L_center, D_center, U_center, F_center, B_center},
- [Bw2] = {D_center, U_center, L_center, R_center, F_center, B_center},
- [Bw3] = {L_center, R_center, U_center, D_center, F_center, B_center},
-
- [X] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [X2] = {D_center, U_center, R_center, L_center, B_center, F_center},
- [X3] = {B_center, F_center, R_center, L_center, U_center, D_center},
- [Y] = {U_center, D_center, B_center, F_center, R_center, L_center},
- [Y2] = {U_center, D_center, L_center, R_center, B_center, F_center},
- [Y3] = {U_center, D_center, F_center, B_center, L_center, R_center},
- [Z] = {L_center, R_center, U_center, D_center, F_center, B_center},
- [Z2] = {D_center, U_center, L_center, R_center, F_center, B_center},
- [Z3] = {R_center, L_center, D_center, U_center, F_center, B_center},
-
- [M] = {B_center, F_center, R_center, L_center, U_center, D_center},
- [M2] = {D_center, U_center, R_center, L_center, B_center, F_center},
- [M3] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [E] = {U_center, D_center, F_center, B_center, L_center, R_center},
- [E2] = {U_center, D_center, L_center, R_center, B_center, F_center},
- [E3] = {U_center, D_center, B_center, F_center, R_center, L_center},
- [S] = {L_center, R_center, U_center, D_center, F_center, B_center},
- [S2] = {D_center, U_center, L_center, R_center, F_center, B_center},
- [S3] = {R_center, L_center, D_center, U_center, F_center, B_center},
-
- [NULLMOVE] = {U_center, D_center, R_center, L_center, F_center, B_center},
-};
-
diff --git a/old/2020-unknown-date/pieces.h b/old/2020-unknown-date/pieces.h
@@ -1,59 +0,0 @@
-/* Moves and other things */
-
-#ifndef PIECES_H
-#define PIECES_H
-
-typedef enum {
- U, U2, U3, D, D2, D3, R, R2, R3, L, L2, L3, F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3, Rw, Rw2, Rw3,
- Lw, Lw2, Lw3, Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3, S, S2, S3, E, E2, E3,
- X, X2, X3, Y, Y2, Y3, Z, Z2, Z3,
- NULLMOVE
-} Move;
-typedef enum {
- U_center, D_center, R_center, L_center, F_center, B_center
-} Center;
-typedef enum { UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR } Edge;
-typedef enum { UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR } Corner;
-
-/* Arrays for strings of pieces and moves */
-extern char edge_string[12][5];
-extern char corner_string[8][5];
-extern char center_string[6][5];
-extern char move_string[NULLMOVE+1][5];
-
-/* Three big arrays that determine the movement of edges, corners and
- * centers for some of the basic moves. Yes, one can be much more elegant and
- * write much fewer lines. But then things get less elegant somewhere else. */
-extern int edge_cycle[NULLMOVE+1][12];
-extern int corner_cycle[NULLMOVE+1][8];
-extern int center_cycle[NULLMOVE+1][6];
-
-/* Representation of the cube */
-typedef struct {
- /* Edge orientation */
- int eofb;
- int eorl;
- int eoud;
-
- /* Corner orientation */
- int coud;
- int cofb;
- int corl;
-
- /* Position of M/E/S slice edges */
- /* TODO: keep in mind that the 4! positions with edges in correct slice
- * must be the first 4! indeces */
- int epose;
- int eposs;
- int eposm;
-
- /* Permutation of corners */
- int cp;
-
- /* Position of centers */
- int centerpos;
-} Cube;
-
-#endif
diff --git a/old/2021-02-06/cube.c b/old/2021-02-06/cube.c
@@ -1,664 +0,0 @@
-#include "cube.h"
-
-typedef struct {
- int ep[12], eofb[12], eorl[12], eoud[12],
- cp[8], coud[8], corl[8], cofb[8], cpos[6];
-} CubeArray;
-
-typedef struct {
- bool epose, eposs, eposm, eofb, eorl, eoud, cp, coud, cofb, corl, cpos;
-} PieceFilter;
-
-PieceFilter fAll = {true,true,true,true,true,true,true,true,true,true,true};
-PieceFilter cpos_only = { .cpos = true };
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-Cube arrays_to_cube(CubeArray arr, PieceFilter f);
-void move_cubearray(Move m, CubeArray *arr, PieceFilter f);
-Cube move_via_array(Move m, Cube cube, PieceFilter f);
-void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front);
-bool read_ttables_file();
-bool write_ttables_file();
-
-/* Transition tables */
-uint16_t epose_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposs_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposm_ttable[NMOVES][factorial12/factorial8];
-uint16_t eofb_ttable[NMOVES][pow2to11];
-uint16_t eorl_ttable[NMOVES][pow2to11];
-uint16_t eoud_ttable[NMOVES][pow2to11];
-uint16_t cp_ttable[NMOVES][factorial8];
-uint16_t coud_ttable[NMOVES][pow3to7];
-uint16_t cofb_ttable[NMOVES][pow3to7];
-uint16_t corl_ttable[NMOVES][pow3to7];
-uint16_t cpos_ttable[NMOVES][factorial6];
-
-bool commute[NMOVES][NMOVES];
-bool possible_next[NMOVES][NMOVES][NMOVES];
-Move inverse[NMOVES];
-
-char edge_string[12][5] =
- { "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR" };
-char corner_string[8][5] = { "UFR","UFL","UBL","UBR","DFR","DFL","DBL","DBR" };
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-char move_string[NMOVES][5] =
- { "-",
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'" };
-
-/* For each type of pieces only the effects of U, x and y are described */
-int edge_cycle[NMOVES][12] =
- { [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [x] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL} };
-int eofb_flipped[NMOVES][12] =
- { [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eorl_flipped[NMOVES][12] =
- { [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eoud_flipped[NMOVES][12] =
- { [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-int corner_cycle[NMOVES][8] =
- { [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL} };
-int coud_flipped[NMOVES][8] =
- { [x] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2} };
-int corl_flipped[NMOVES][8] =
- { [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1} };
-int cofb_flipped[NMOVES][8] =
- { [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=2,[UFL]=1,[DBL]=1,[DFL]=2},
- [y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2} };
-int center_cycle[NMOVES][6] =
- { [x] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [y] = {U_center, D_center, B_center, F_center, R_center, L_center} };
-
-/* Each move is reduced to a combination of U, x and y using this table */
-Move equiv_moves[NMOVES][14] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 },
- [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 },
- [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 },
- [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 },
- [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 },
- [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 },
- [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 },
- [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 },
- [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 },
- [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 },
- [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 },
- [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 },
- [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 },
- [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 },
- [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 },
- [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 },
-
- [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 },
- [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 },
- [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 },
- [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 },
- [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 },
- [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 },
- [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 },
- [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 },
- [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 },
-
- [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* Movesets */
-bool standard_moveset[NMOVES] = {
- [U] = true, [U2] = true, [U3] = true, [D] = true, [D2] = true, [D3] = true,
- [R] = true, [R2] = true, [R3] = true, [L] = true, [L2] = true, [L3] = true,
- [F] = true, [F2] = true, [F3] = true, [B] = true, [B2] = true, [B3] = true,
-};
-
-int epe_solved[] = {FR, FL, BL, BR};
-int eps_solved[] = {UL, UR, DL, DR};
-int epm_solved[] = {UF, UB, DF, DB};
-
-Cube blank_cube() {
- Cube c = {0};
- return c;
-}
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) {
- /* ep is the hardest */
- if (f.epose || f.eposs || f.eposm)
- for (int i = 0; i < 12; i++) arr->ep[i] = -1;
- if (f.epose) {
- int epe[4], epose[12];
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- for (int i = 0, ie = 0; i < 12; i++)
- if (epose[i]) arr->ep[i] = epe_solved[epe[ie++]];
- }
- if (f.eposs) {
- int eps[4], eposs[12];
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- for (int i = 0, is = 0; i < 12; i++)
- if (eposs[i]) arr->ep[i] = eps_solved[eps[is++]];
- }
- if (f.eposm) {
- int epm[4], eposm[12];
- index_to_perm(cube.eposm % factorial(4), 4, epm);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- for (int i = 0, im = 0; i < 12; i++)
- if (eposm[i]) arr->ep[i] = epm_solved[epm[im++]];
- }
-
- /* All the others */
- if (f.eofb) int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl) int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud) int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp) index_to_perm( cube.cp, 8, arr->cp);
- if (f.coud) int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl) int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb) int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos) index_to_perm( cube.cpos, 6, arr->cpos);
-}
-
-Cube arrays_to_cube(CubeArray arr, PieceFilter f) {
- Cube ret = {0};
-
- /* Again, ep is the hardest part */
- if (f.epose) {
- int epe[4], epose[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, ie = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epe_solved[j])
- { epe[ie++] = j; epose[i] = 1; }
- ret.epose = factorial(4)*subset_to_index(epose,12,4)+perm_to_index(epe,4);
- }
- if (f.eposs) {
- int eps[4], eposs[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, is = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == eps_solved[j])
- { eps[is++] = j; eposs[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- ret.eposs = factorial(4)*subset_to_index(eposs,12,4)+perm_to_index(eps,4);
- }
- if (f.eposm) {
- int epm[4], eposm[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, im = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epm_solved[j])
- { epm[im++] = j; eposm[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- ret.eposm = factorial(4)*subset_to_index(eposm,12,4)+perm_to_index(epm,4);
- }
- if (f.eofb) ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
- if (f.eorl) ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
- if (f.eoud) ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
- if (f.cp) ret.cp = perm_to_index( arr.cp, 8 );
- if (f.coud) ret.coud = digit_array_to_int(arr.coud, 7, 3);
- if (f.corl) ret.corl = digit_array_to_int(arr.corl, 7, 3);
- if (f.cofb) ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
- if (f.cpos) ret.cpos = perm_to_index( arr.cpos, 6 );
-
- return ret;
-}
-
-void move_cubearray(Move m, CubeArray *arr, PieceFilter f) {
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(edge_cycle[m], arr->ep, 12);
- if (f.eofb) {
- apply_permutation(edge_cycle[m], arr->eofb, 12);
- sum_arrays_mod(eofb_flipped[m], arr->eofb, 12, 2);
- }
- if (f.eofb) {
- apply_permutation(edge_cycle[m], arr->eorl, 12);
- sum_arrays_mod(eorl_flipped[m], arr->eorl, 12, 2);
- }
- if (f.eofb) {
- apply_permutation(edge_cycle[m], arr->eoud, 12);
- sum_arrays_mod(eoud_flipped[m], arr->eoud, 12, 2);
- }
- if (f.cp)
- apply_permutation(corner_cycle[m], arr->cp, 8);
- if (f.coud) {
- apply_permutation(corner_cycle[m], arr->coud, 8);
- sum_arrays_mod(coud_flipped[m], arr->coud, 8, 3);
- }
- if (f.corl) {
- apply_permutation(corner_cycle[m], arr->corl, 8);
- sum_arrays_mod(corl_flipped[m], arr->corl, 8, 3);
- }
- if (f.cofb) {
- apply_permutation(corner_cycle[m], arr->cofb, 8);
- sum_arrays_mod(cofb_flipped[m], arr->cofb, 8, 3);
- }
- if (f.cpos)
- apply_permutation(center_cycle[m], arr->cpos, 6);
-}
-
-Cube move_via_array(Move m, Cube cube, PieceFilter f) {
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, f);
- move_cubearray(m, &arr, f);
- return arrays_to_cube(arr, f);
-}
-
-int copy_alg(NissMove *src, NissMove *dest) {
- int i;
- for (i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
- dest[i].m = NULLMOVE;
- return i;
-}
-
-bool equal(Cube c1, Cube c2) {
- return c1.eofb == c2.eofb && c1.epose == c2.epose &&
- c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
- c1.coud == c2.coud && c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-bool solvable(Cube cube) {
- /* Since we memorize orientation truncating the last digit, we only need to
- * check that the permutations have the correct sign. */
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, fAll);
- return (perm_sign(arr.ep,12) ^ perm_sign(arr.cpos,6)) == perm_sign(arr.cp,8);
-}
-
-bool is_solved(Cube cube, bool reorient) {
- if (!reorient || !cube.cpos)
- return !cube.eofb && !cube.coud && !cube.cp &&
- !cube.epose && !cube.eposs && !cube.eposm;
-
- bool ret = false;
- for (int i = x; i <= z3; i++) {
- ret = ret || is_solved(move_cube(i, cube), false);
- for (int j = x; j <= z3; j++)
- ret = ret || is_solved(move_cube(i, move_cube(j, cube)), false);
- }
- return ret;
-}
-
-void print_cube(Cube cube) {
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, fAll);
-
- for (int i = 0; i < 12; i++) printf(" %s ", edge_string[arr.ep[i]]);
- printf("\n");
- for (int i = 0; i < 12; i++) printf(" %c ", arr.eofb[i] + '0');
- printf("\n");
- for (int i = 0; i < 8; i++) printf("%s ", corner_string[arr.cp[i]]);
- printf("\n");
- for (int i = 0; i < 8; i++) printf(" %c ", arr.coud[i] + '0');
- printf("\n");
- for (int i = 0; i < 6; i++) printf(" %s ", center_string[arr.cpos[i]]);
- printf("\n");
-}
-
-/* TODO: all strings start with space?? */
-void print_moves(NissMove *alg) {
- bool niss = false;
- for (int i = 0; alg[i].m != NULLMOVE; i++) {
- char *fill = !niss && alg[i].inverse ? " (" :
- (niss && !alg[i].inverse ? ") " : " ");
- printf("%s%s", fill, move_string[alg[i].m]);
- niss = alg[i].inverse;
- }
- printf("%s\n", niss ? ")" : "");
-}
-
-int read_moves(char *str, NissMove *alg, int n) {
- bool niss = false;
- int c = 0;
-
- for (int i = 0; str[i] && c < n; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' || str[i] == ')') {
- if ((niss && str[i] == '(') || (!niss && str[i] == ')'))
- return -1;
- niss = !niss;
- continue;
- }
-
- alg[c].inverse = niss; alg[c].m = NULLMOVE;
- for (Move j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- alg[c].m = j;
- if (alg[c].m <= B && str[i+1]=='w') { alg[c].m += Uw - U; i++; }
- if (str[i+1]=='2') { alg[c].m += 1; i++; }
- else if (str[i+1]=='\'' || str[i+1]=='3') { alg[c].m += 2; i++; }
- c++;
- break;
- }
- }
- }
-
- alg[c].m = NULLMOVE;
- return c;
-}
-
-/* Helper function for cleanup. alg must contain only basic moves, no 2 or '.
- top and front describe an admissible orientation of the cube. */
-void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front) {
- int c = 0, i = 0;
- NissMove aux[n+3];
- aux[0].m = NULLMOVE;
-
- while (i < n && alg[i].m != NULLMOVE) {
- int j = i;
- while (j < n && commute[alg[i].m][alg[j].m]) j++;
- Move base = 6*((alg[i].m-1)/6);
- int t1 = 0, t2 = 0;
- for (int k = i; k < j; k++)
- if (alg[k].m == base+1) t1 = (t1+1)%4;
- else t2 = (t2+1)%4;
- if (t1) { aux[c].inverse = inv; aux[c].m = base+t1; c++; }
- if (t2) { aux[c].inverse = inv; aux[c].m = base+t2+3; c++; }
- i = j;
- }
- aux[c].m = NULLMOVE;
-
- CubeArray q;
- cube_to_arrays(blank_cube(), &q, cpos_only);
- /* First we try to rotate in one move, then we try an x or y rotation
- followed by a z rotation */
- for (int r = x; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front && q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c].m = r;
-
- aux[++c].m = NULLMOVE;
- copy_alg(aux, alg);
- return;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = x; r <= y3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = z; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
-
- aux[c].m = NULLMOVE;
- copy_alg(aux, alg);
-}
-
-void cleanup(NissMove *alg, int n) {
- int count_n = 0, count_i = 0, *count;
- NissMove aux_n[n+1], aux_i[n+1], *aux;
- CubeArray cube_n, cube_i, *cube;
- cube_to_arrays(blank_cube(), &cube_n, cpos_only);
- cube_to_arrays(blank_cube(), &cube_i, cpos_only);
-
- for (int i = 0; count_n + count_i < n && alg[i].m != NULLMOVE; i++) {
- if (alg[i].inverse) { count = &count_i; aux = aux_i; cube = &cube_i; }
- else { count = &count_n; aux = aux_n; cube = &cube_n; }
-
- for (int j = 0; equiv_moves[alg[i].m][j]; j++) {
- Move m = equiv_moves[alg[i].m][j];
- aux[*count].inverse = alg[i].inverse;
- move_cubearray(m, cube, cpos_only);
- if (m == U) aux[(*count)++].m = 3 * cube->cpos[0] + 1;
- }
- }
-
- aux_n[count_n].m = NULLMOVE;
- aux_i[count_i].m = NULLMOVE;
- sort_cancel_rotate(aux_n, count_n, false, cube_n.cpos[0], cube_n.cpos[4]);
- sort_cancel_rotate(aux_i, count_i, true, cube_i.cpos[0], cube_n.cpos[4]);
- copy_alg(aux_n, alg);
- copy_alg(aux_i, alg+count_n);
-}
-
-Cube inverse_cube(Cube cube) {
- CubeArray arr = {0}, inv = {0};
- cube_to_arrays(cube, &arr, fAll);
-
- for (int i = 0; i < 12; i++) {
- inv.ep[arr.ep[i]] = i;
- inv.eofb[arr.ep[i]] = arr.eofb[i];
- inv.eorl[arr.ep[i]] = arr.eorl[i];
- inv.eoud[arr.ep[i]] = arr.eoud[i];
- }
- for (int i = 0; i < 8; i++) {
- inv.cp[arr.cp[i]] = i;
- inv.coud[arr.cp[i]] = arr.coud[i];
- inv.corl[arr.cp[i]] = arr.corl[i];
- inv.cofb[arr.cp[i]] = arr.cofb[i];
- }
- for (int i = 0; i < 6; i++)
- inv.cpos[arr.cpos[i]] = i;
-
- return arrays_to_cube(inv, fAll);
-}
-
-bool read_ttables_file() {
- FILE *ttf;
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- for (int m = 0; m < NMOVES; m++) {
- fread(epose_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eposs_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eposm_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eofb_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(eorl_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(eoud_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(cp_ttable[m], sizeof(uint16_t), factorial8, ttf);
- fread(coud_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(corl_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(cofb_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(cpos_ttable[m], sizeof(uint16_t), factorial6, ttf);
- }
- fclose(ttf);
- return true;
- } else return false;
-}
-
-bool write_ttables_file() {
- FILE *ttf;
- if ((ttf = fopen("ttables", "wb")) != NULL) {
- for (int m = 0; m < NMOVES; m++) {
- fwrite(epose_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eposs_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eposm_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eofb_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(eorl_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(eoud_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(cp_ttable[m], sizeof(uint16_t), factorial8, ttf);
- fwrite(coud_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(corl_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(cofb_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(cpos_ttable[m], sizeof(uint16_t), factorial6, ttf);
- }
- fclose(ttf);
- return true;
- } else return false;
-}
-
-void init_ttables(bool read, bool write) {
- /* Generate all move cycles and flips; I do this regardless */
- for (int i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- CubeArray arr = {0};
- cube_to_arrays(blank_cube(), &arr, fAll);
- for (int j = 0; equiv_moves[i][j]; j++)
- move_cubearray(equiv_moves[i][j], &arr, fAll);
-
- intarrcopy(arr.ep, edge_cycle[i], 12);
- intarrcopy(arr.eofb, eofb_flipped[i], 12);
- intarrcopy(arr.eorl, eorl_flipped[i], 12);
- intarrcopy(arr.eoud, eoud_flipped[i], 12);
- intarrcopy(arr.cp, corner_cycle[i], 8);
- intarrcopy(arr.coud, coud_flipped[i], 8);
- intarrcopy(arr.corl, corl_flipped[i], 8);
- intarrcopy(arr.cofb, cofb_flipped[i], 8);
- intarrcopy(arr.cpos, center_cycle[i], 6);
- }
-
- if (read)
- if (read_ttables_file())
- return;
-
- /* Initialize transition tables */
- Cube c = {0};
- PieceFilter fe = {.epose=true}, fs = {.eposs=true}, fm = {.eposm=true};
- PieceFilter feo = { .eofb = true, .eorl = true, .eoud = true };
- PieceFilter fcp = { .cp = true };
- PieceFilter fco = { .cofb = true, .corl = true, .coud = true };
- PieceFilter fcc = { .cpos = true };
- for (int m = 0; m < NMOVES; m++) {
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- c.epose = i; epose_ttable[m][i] = move_via_array(m, c, fe).epose;
- c.eposs = i; eposs_ttable[m][i] = move_via_array(m, c, fs).eposs;
- c.eposm = i; eposm_ttable[m][i] = move_via_array(m, c, fm).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- c.eofb = i; eofb_ttable[m][i] = move_via_array(m, c, feo).eofb;
- c.eorl = i; eorl_ttable[m][i] = move_via_array(m, c, feo).eorl;
- c.eoud = i; eoud_ttable[m][i] = move_via_array(m, c, feo).eoud;
- }
- for (uint16_t i = 0; i < factorial8; i++) {
- c.cp = i; cp_ttable[m][i] = move_via_array(m, c, fcp).cp;
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- c.coud = i; coud_ttable[m][i] = move_via_array(m, c, fco).coud;
- c.corl = i; corl_ttable[m][i] = move_via_array(m, c, fco).corl;
- c.cofb = i; cofb_ttable[m][i] = move_via_array(m, c, fco).cofb;
- }
- for (uint16_t i = 0; i < factorial6; i++) {
- c.cpos = i; cpos_ttable[m][i] = move_via_array(m, c, fcc).cpos;
- }
- }
-
- if (write) write_ttables_file();
-}
-
-Cube move_cube(Move m, Cube cube) {
- Cube moved = cube;
-
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.cp = cp_ttable[m][cube.cp];
- moved.cpos = cpos_ttable[m][cube.cpos];
-
- return moved;
-}
-
-Cube compose(Cube c2, Cube c1) {
- /* This is basically the same as the move_cubearray function above */
- CubeArray arr2 = {0}, arr1 = {0};
- cube_to_arrays(c2, &arr2, fAll);
- cube_to_arrays(c1, &arr1, fAll);
-
- apply_permutation(arr2.ep, arr1.ep, 12);
- apply_permutation(arr2.ep, arr1.eofb, 12);
- apply_permutation(arr2.ep, arr1.eorl, 12);
- apply_permutation(arr2.ep, arr1.eoud, 12);
- sum_arrays_mod(arr2.eofb, arr1.eofb, 12, 2);
- sum_arrays_mod(arr2.eorl, arr1.eorl, 12, 2);
- sum_arrays_mod(arr2.eoud, arr1.eoud, 12, 2);
- apply_permutation(arr2.cp, arr1.cp, 8);
- apply_permutation(arr2.cp, arr1.coud, 8);
- apply_permutation(arr2.cp, arr1.corl, 8);
- apply_permutation(arr2.cp, arr1.cofb, 8);
- sum_arrays_mod(arr2.coud, arr1.coud, 8, 3);
- sum_arrays_mod(arr2.corl, arr1.corl, 8, 3);
- sum_arrays_mod(arr2.cofb, arr1.cofb, 8, 3);
- apply_permutation(arr2.cpos, arr1.cpos, 6);
-
- return arrays_to_cube(arr1, fAll);
-}
-
-Cube apply_alg(NissMove *alg, Cube cube) {
- Cube ret = {0};
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- ret = compose(cube, inverse_cube(ret));
-
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (!alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- return ret;
-}
-
-void init_aux_tables() {
- /* Commute */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- commute[i][j] = equal(move_cube(i, move_cube(j, blank_cube())),
- move_cube(j, move_cube(i, blank_cube())));
-
- /* Possible next (if the sequence i j k is valid) */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- for (int k = 0; k < NMOVES; k++)
- possible_next[i][j][k] =
- (j == 0) ||
- (j != 0 && (j-(j-1)%3) != (k-(k-1)%3) &&
- !(i != 0 && commute[i][j] && (i-(i-1)%3) == (k-(k-1)%3)));
-
- /* Inverse */
- for (int i = 0; i < NMOVES; i++)
- inverse[i] = i == 0 ? 0 : i + 2 - 2*((i-1)%3);
-}
-
diff --git a/old/2021-02-06/cube.h b/old/2021-02-06/cube.h
@@ -1,60 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "utils.h"
-
-#define NMOVES (z3+1)
-
-/* Constants for moves and pieces */
-typedef enum {
- NULLMOVE,
- U, U2, U3, D, D2, D3, R, R2, R3, L, L2, L3, F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3, Rw, Rw2, Rw3,
- Lw, Lw2, Lw3, Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3, S, S2, S3, E, E2, E3,
- x, x2, x3, y, y2, y3, z, z2, z3,
-} Move;
-typedef enum {U_center,D_center,R_center,L_center,F_center,B_center} Center;
-typedef enum { UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR } Edge;
-typedef enum { UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR } Corner;
-
-/* An alg is an array of "NissMoves", which can be on normal or on inverse. */
-typedef struct { bool inverse; Move m; } NissMove;
-
-/* Representation of the cube */
-typedef struct {
- uint16_t eofb, eorl, eoud, coud, cofb, corl,
- epose, eposs, eposm, cp, cpos;
-} Cube;
-
-extern bool commute[NMOVES][NMOVES];
-extern bool possible_next[NMOVES][NMOVES][NMOVES];
-extern Move inverse[NMOVES];
-/* Movesets */
-extern bool standard_moveset[NMOVES];
-
-int copy_alg(NissMove *src, NissMove *dest); /*return number of moves copied */
-
-bool equal(Cube c1, Cube c2);
-bool is_solvable(Cube cube);
-/* reorient=true allows solved in wrong orientation */
-bool is_solved(Cube cube, bool reorient);
-void print_cube(Cube cube);
-void print_moves(NissMove *alg);
-int read_moves(char *str, NissMove *alg, int n); /* reads at most n moves */
-void cleanup(NissMove *src, int n); /* rewrites using basic moves, at most n */
-Cube blank_cube();
-Cube inverse_cube(Cube cube);
-Cube move_cube(Move m, Cube cube);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg */
-Cube apply_alg(NissMove *alg, Cube cube);
-
-void init_ttables(bool read, bool write);
-void init_aux_tables();
-
-void init_dbg();
-
-#endif
diff --git a/old/2021-02-06/main.c b/old/2021-02-06/main.c
@@ -1,46 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "solve.h"
-
-int main() {
- init_ttables(true, true);
- init_aux_tables();
-
-
- char moves[100] = "MR U' B2 Bw F z xE2 M' x Dw' y Fw2 y2";
- NissMove alg[100];
- read_moves(moves, alg, 100);
- Cube cube = apply_alg(alg, blank_cube());
-
- /*f_eofb(cube);*/
-
-
-/* NissMove sol[MAXS][MAXM];*/
- SolveData d = { .optimal_only = true, .available = standard_moveset,
- .max_moves = 10,
- .cleanup = true,
- .max_solutions = 10,
- .f = f_eofb };
- read_moves("y", d.pre_rotation, 2);
- int n = solve(cube, &d);
- printf("%d solutions found:\n", n);
- for (int i = 0; i < n; i++)
- print_moves(d.solutions[i]);
-
- NissMove a[5], b[5];
- read_moves("R", a, 5);
- read_moves("U", b, 5);
- Cube c1 = apply_alg(a,blank_cube()), c2 = apply_alg(b,blank_cube());
- print_cube(compose(c2,c1));
- print_cube(compose(c1,c2));
- /*print_cube(compose(c2,blank_cube()));*/
-
- NissMove nm[10];
- read_moves("y(y)RU", nm, 10);
-
- print_moves(nm);
- cleanup(nm, 10);
- print_moves(nm);
-
- return 0;
-}
diff --git a/old/2021-02-06/solve.c b/old/2021-02-06/solve.c
@@ -1,177 +0,0 @@
-#include "solve.h"
-
-/* Data for creating a pruning table:
- - compressed: if set to true, each entry occupies only 4 bits, but values
- larger than 15 cannot be stored.
- - available[] is the list of availabel moves, as above.
- - *ptable is the actual table to fill.
- - n is the number of states (size of ptable).
- - index must "linearize" the cube, i.e. return its index in ptable.
- - fname is the name of the file where to store the table */
-typedef struct {
- bool compressed, *available;
- int max_moves;
- uint8_t *ptable;
- uint64_t n;
- uint64_t (*index)(Cube);
- char *fname;
-} PruneData;
-
-/* TODO: comment this */
-typedef struct {
- bool niss;
- int m, d;
- uint64_t *n;
- Move last1, last2;
-} DfsData;
-
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd);
-void init_ptable(PruneData *pd, bool read, bool write);
-
-/* Search solutions of lenght exactly d */
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd) {
- if (*dd.n >= sd->max_solutions ||
- ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d))
- return;
-
- (sd->solutions[*dd.n][dd.m]).inverse = dd.niss;
- (sd->solutions[*dd.n][dd.m]).m = NULLMOVE;
-
- if (!sd->f(cube)) { /* Solved */
- if (dd.m == dd.d) {
- (*dd.n)++;
- if (*dd.n < sd->max_solutions)
- copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]);
- }
- return;
- }
-
- for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) {
- Move move = sd->sorted_moves[i];
- if (possible_next[dd.last2][dd.last1][move]) {
- sd->solutions[*dd.n][dd.m].inverse = dd.niss;
- sd->solutions[*dd.n][dd.m].m = move;
- DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = move, .last2 = dd.last1 };
- solve_dfs(move_cube(move, cube), sd, nn);
- }
- }
-
- if (sd->can_niss && !dd.niss &&
- (!dd.m || (dd.m && sd->f(move_cube(dd.last1, blank_cube()))))) {
- DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n };
- solve_dfs(inverse_cube(cube), sd, nn);
- }
-}
-
-/* Iterative deepening depth-first search: for i running from the minimum
- to the maximum number of moves allowed, looks for solutions of length i. */
-int solve(Cube cube, SolveData *sd) {
- if (sd->precondition != NULL && !sd->precondition(cube))
- return -1;
-
- /* If not given, generate sorted list of moves */
- if (sd->sorted_moves[0] == NULLMOVE) {
- int a[NMOVES], b[NMOVES], ia = 0, ib = 0;
- for (int i = 0; i < NMOVES; i++) {
- if (sd->available[i]) {
- if (sd->f(move_cube(i, blank_cube())))
- a[ia++] = i;
- else
- b[ib++] = i;
- }
- }
- intarrcopy(a, (int *)sd->sorted_moves, ia);
- intarrcopy(b, (int *)sd->sorted_moves+ia, ib);
- sd->sorted_moves[ia+ib] = NULLMOVE;
- }
-
- sd->max_solutions = min(sd->max_solutions, MAXS);
- Cube rotated = apply_alg(sd->pre_rotation, blank_cube());
- cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
-
- uint64_t ret = 0;
- for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
- DfsData dd = { .d = i, .n = &ret };
- solve_dfs(cube, sd, dd);
- }
-
- for (uint64_t i = 0; i < ret; i++) {
- /* TODO: transform solutions with inverse of pre_rotation */
- if (sd->cleanup)
- cleanup(sd->solutions[i], sd->max_moves*3);
- }
-
- return ret;
-}
-
-void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
- uint64_t ind = pd->index(cube);
- if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
- return;
- if (dd.m == dd.d) {
- if (ind && !pd->ptable[ind]) {
- pd->ptable[ind] = dd.m;
- (*dd.n)++;
- }
- return;
- }
-
- for (int i = 0; i < NMOVES; i++) {
- if (dd.m<20)
- if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
- DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = i, .last2 = dd.last1 };
- prune_dfs(move_cube(i, cube), pd, nn);
- }
- }
-}
-
-void init_ptable(PruneData *pd, bool read, bool write) {
- if (read) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "rb")) != NULL) {
- fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-
- /* TODO: for now it behaves always as if copressed = false */
- for (uint64_t i = 0; i < pd->n; i++)
- pd->ptable[i] = 0;
-
- uint64_t s = 1;
- for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
- DfsData dd = { .d = i, .n = &s };
- prune_dfs(blank_cube(), pd, dd);
- }
-
- if (write) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "wb")) != NULL) {
- fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-}
-
-/* Solving steps (and indexing functions) */
-
-uint64_t index_eofb(Cube cube) { return cube.eofb; }
-uint16_t f_eofb(Cube cube) {
- static bool initialized_ptable;
- static uint8_t pt_eofb[pow2to11];
- if (!initialized_ptable) {
- PruneData pd = {
- .compressed = false, .available = standard_moveset, .max_moves = 13,
- .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
- .fname = "ptable_eofb"
- };
- init_ptable(&pd, false, true);
- initialized_ptable = true;
- }
- return cube.eofb ? pt_eofb[cube.eofb] : 0;
-}
-
diff --git a/old/2021-02-06/solve.h b/old/2021-02-06/solve.h
@@ -1,55 +0,0 @@
-#ifndef SOLVE_H
-#define SOLVE_H
-
-#include <stdlib.h>
-#include "cube.h"
-
-/* Maximum number of moves per solution and of solutions */
-#define MAXM 30
-#define MAXS 999
-
-/* Data for solving a step:
- - can_niss is true niss can be used, false otherwise.
- - optimal_only if true, dynamically updates max_moves so non-optimal
- solutions are discarded.
- - cleanup determines whether the cleaunup() function should be used on
- the found solutions before returning.
- - available[m] is true if the move m can be used, false otherwise.
- - min_moves and max_moves are the minimum and maximum number of moves that
- can be used.
- - max_solution is the maximum number of solutions that can be returned.
- - precondition can be used to check wheter the step can actually be applied
- to the cube. If it returns false, solve() stops immediately returning -1.
- - f must return 0 if and only if the step is solve, otherwise it must return
- a lower bound for the number of moves required (without niss).
- - sorted_moves[] can be used to specify in which order moves are tried
- by the solving algorithm (for example if one wants to always try F' before
- F). If sorted_moves[0] == NULLMOVE, the list is generated automatically.
- It is advised to list first all the moves that actually influence the
- solved state of the step (this is the default choice). This is in order to
- avoid cases like B2 F for EO and to NISS only when it makes sense.
- - start_moves [Currently unused, REMOVE]
- are the moves that will be used as first moves of all
- solutions. For example giving R' U' F (F' U R) will generate FMC scrambles
- and y (y) will solve the step on another axis.
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wrt a different orientation
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wth respect to a different orientation.
- - solutions[][] is the array where to store the found solutions. */
-typedef struct {
- bool can_niss, optimal_only, cleanup, *available;
- int min_moves, max_moves;
- uint64_t max_solutions;
- bool (*precondition)(Cube);
- uint16_t (*f)(Cube);
- Move sorted_moves[NMOVES];
- NissMove pre_rotation[3], solutions[MAXS][MAXM];
-} SolveData;
-
-int solve(Cube cube, SolveData *data); /* Returns the number of solutions. */
-
-/* Steps */
-uint16_t f_eofb(Cube cube);
-
-#endif
diff --git a/old/2021-02-06/utils.c b/old/2021-02-06/utils.c
@@ -1,197 +0,0 @@
-#include "utils.h"
-
-void swap(int *a, int *b) {
- int aux = *a;
- *a = *b;
- *b = aux;
-}
-
-void intarrcopy(int *src, int *dst, int n) {
- for (int i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-int sum(int *a, int n) {
- int ret = 0;
- for (int i = 0; i < n; i++)
- ret += a[i];
- return ret;
-}
-
-bool is_perm(int *a, int n) {
- int aux[n]; for (int i = 0; i < n; i++) aux[i] = 0;
- for (int i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
- for (int i = 0; i < n; i++)
- if (!aux[i])
- return false;
- return true;
-}
-
-bool is_subset(int *a, int n, int k) {
- int sum = 0;
- for (int i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
- return sum == k;
-}
-
-int powint(int a, int b) {
- return 0;
- if (b == 0 || a == 1)
- return 1;
- if (a == 0)
- return 0;
- if (b < 0)
- return 0; /* Immediate truncate (integer part is 0) */
- if (b % 2) {
- return a * powint(a, b-1);
- } else {
- int x = powint(a, b/2);
- return x*x;
- }
-}
-
-int factorial(int n) {
- if (n < 0)
- return 0;
- int ret = 1;
- for (int i = 1; i <= n; i++)
- ret *= i;
- return ret;
-}
-
-int binomial(int n, int k) {
- if (n < 0 || k < 0 || k > n)
- return 0;
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-void int_to_digit_array(int a, int b, int n, int *r) {
- if (b <= 1)
- for (int i = 0; i < n; i++)
- r[i] = 0;
- else
- for (int i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-int digit_array_to_int(int *a, int n, int b) {
- int ret = 0, p = 1;
- for (int i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
- return ret;
-}
-
-int perm_to_index(int *a, int n) {
- if (!is_perm(a, n))
- return factorial(n); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- int c = 0;
- for (int j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
- return ret;
-}
-
-void index_to_perm(int p, int n, int *r) {
- if (p < 0 || p >= factorial(n)) /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- int a[n]; for (int j = 0; j < n; j++) a[j] = 0; /* picked elements */
- for (int i = 0; i < n; i++) {
- int c = 0, j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-}
-
-int perm_sign(int *a, int n) {
- if (!is_perm(a,n))
- return false;
- int ret = 0;
- for (int i = 0; i < n; i++)
- for (int j = i+1; j < n; j++)
- ret += (a[i]>a[j]) ? 1 : 0;
- return ret % 2;
-}
-
-int subset_to_index(int *a, int n, int k) {
- /* TODO: better checks */
- if (!is_subset(a, n, k))
- return binomial(n, k); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- /*ret += factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- ret += binomial(n-i-1, k);
- k--;
- }
- }
- return ret;
-}
-
-void index_to_subset(int s, int n, int k, int *r) {
- if (s < 0 || s >= binomial(n, k)) { /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
- for (int i = 0; i < n; i++) {
- if (k == n-i) {
- for (int j = i; j < n; j++)
- r[j] = 1;
- return;
- }
- if (k == 0) {
- for (int j = i; j < n; j++)
- r[j] = 0;
- return;
- }
- /*int v = factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- int v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-void int_to_sum_zero_array(int x, int b, int n, int *a) {
- if (b <= 1) {
- for (int i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- int s = 0;
- for (int i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-void apply_permutation(int *perm, int *set, int n) {
- if (!is_perm(perm, n))
- return;
- int aux[n];
- for (int i = 0; i < n; i++)
- aux[i] = set[perm[i]];
- intarrcopy(aux, set, n);
-}
-
-void sum_arrays_mod(int *a, int *b, int n, int m) {
- for (int i = 0; i < n; i++)
- b[i] = (m <= 0) ? 0 : (a[i] + b[i]) % m;
-}
diff --git a/old/2021-02-06/utils.h b/old/2021-02-06/utils.h
@@ -1,70 +0,0 @@
-/* General utility functions */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Some useful constants */
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-/* Generic utility functions */
-void swap(int *a, int *b);
-void intarrcopy(int *src, int *dst, int n);
-int sum(int *a, int n);
-bool is_perm(int *a, int n);
-bool is_perm(int *a, int n);
-
-
-/* Standard mathematical functions */
-int powint(int a, int b);
-int factorial(int n);
-int binomial(int n, int k);
-
-/* Converts the integer a to its representation in base b (first n digits
- * only) and saves the result in r. */
-void int_to_digit_array(int a, int b, int n, int *r);
-int digit_array_to_int(int *a, int n, int b);
-
-/* Converts the first n-1 digits of a number to an array a of digits in base b;
- * then adds one element to the array, so that the sum of the elements of a is
- * zero modulo b.
- * This is used for determing the edge orientation from an 11-bits integer or
- * the corner orientation from a 7-trits integer. */
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-
-/* Converts a permutation on [0..(n-1)] into the integer i which is the index
- * of the permutation in the sorted list of all n! such permutations. */
-int perm_to_index(int *a, int n);
-void index_to_perm(int p, int n, int *r);
-
-/* Determine the sign of a permutation */
-int perm_sign(int a[], int n);
-
-/* Converts a k-element subset of a set from an array of n elements, of which k
- * are 1 and n-k are 0, to its index in the sorted list of all such subsets. */
-int subset_to_index(int *a, int n, int k);
-void index_to_subset(int s, int n, int k, int *r);
-
-int ordered_subset_to_index(int *a, int n, int k);
-void index_to_ordered_subset(int s, int n, int k, int *r);
-
-void apply_permutation(int *perm, int *set, int n);
-
-/* b[i] = (a[i]+b[i])%m for i=1,...,n */
-void sum_arrays_mod(int *a, int *b, int n, int m);
-
-#endif
diff --git a/old/2021-02-18-piecefilter/compile.sh b/old/2021-02-18-piecefilter/compile.sh
@@ -1 +0,0 @@
-gcc -Wall -Wextra -O2 -std=c99 -o nissy ./src/*.c
diff --git a/old/2021-02-18-piecefilter/nissy b/old/2021-02-18-piecefilter/nissy
Binary files differ.
diff --git a/old/2021-02-18-piecefilter/src/cube.c b/old/2021-02-18-piecefilter/src/cube.c
@@ -1,198 +0,0 @@
-#include "cube.h"
-
-char edge_string[12][5] =
- { "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR" };
-char corner_string[8][5] = { "UFR","UFL","UBL","UBR","DFR","DFL","DBL","DBR" };
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-
-int epe_solved[] = {FR, FL, BL, BR};
-int eps_solved[] = {UL, UR, DL, DR};
-int epm_solved[] = {UF, UB, DF, DB};
-
-PieceFilter fAll = {true,true,true,true,true,true,true,true,true,true,true};
-
-Cube blank_cube() {
- Cube c = {0};
- return c;
-}
-
-/* Return axis (ud=0, rl=1, fb=0) of center c */
-int center_axis(int c) {
- if (c == U_center || c == D_center)
- return 0;
- if (c == R_center || c == L_center)
- return 1;
- return 2;
-}
-
-/* Return slice (e=0, s=1, m=2) to which e belongs */
-int edge_slice(int e) {
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
- return 2;
-}
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) {
- /* ep is the hardest */
- if (f.epose || f.eposs || f.eposm)
- for (int i = 0; i < 12; i++) arr->ep[i] = -1;
- if (f.epose) {
- int epe[4], epose[12];
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- for (int i = 0, ie = 0; i < 12; i++)
- if (epose[i]) arr->ep[i] = epe_solved[epe[ie++]];
- }
- if (f.eposs) {
- int eps[4], eposs[12];
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- for (int i = 0, is = 0; i < 12; i++)
- if (eposs[i]) arr->ep[i] = eps_solved[eps[is++]];
- }
- if (f.eposm) {
- int epm[4], eposm[12];
- index_to_perm(cube.eposm % factorial(4), 4, epm);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- for (int i = 0, im = 0; i < 12; i++)
- if (eposm[i]) arr->ep[i] = epm_solved[epm[im++]];
- }
-
- /* All the others */
- if (f.eofb) int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl) int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud) int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp) index_to_perm( cube.cp, 8, arr->cp);
- if (f.coud) int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl) int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb) int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos) index_to_perm( cube.cpos, 6, arr->cpos);
-}
-
-Cube arrays_to_cube(CubeArray arr, PieceFilter f) {
- Cube ret = {0};
-
- /* Again, ep is the hardest part */
- if (f.epose) {
- int epe[4], epose[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, ie = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epe_solved[j])
- { epe[ie++] = j; epose[i] = 1; }
- ret.epose = factorial(4)*subset_to_index(epose,12,4)+perm_to_index(epe,4);
- }
- if (f.eposs) {
- int eps[4], eposs[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, is = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == eps_solved[j])
- { eps[is++] = j; eposs[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- ret.eposs = factorial(4)*subset_to_index(eposs,12,4)+perm_to_index(eps,4);
- }
- if (f.eposm) {
- int epm[4], eposm[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, im = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epm_solved[j])
- { epm[im++] = j; eposm[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- ret.eposm = factorial(4)*subset_to_index(eposm,12,4)+perm_to_index(epm,4);
- }
- if (f.eofb) ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
- if (f.eorl) ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
- if (f.eoud) ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
- if (f.cp) ret.cp = perm_to_index( arr.cp, 8 );
- if (f.coud) ret.coud = digit_array_to_int(arr.coud, 7, 3);
- if (f.corl) ret.corl = digit_array_to_int(arr.corl, 7, 3);
- if (f.cofb) ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
- if (f.cpos) ret.cpos = perm_to_index( arr.cpos, 6 );
-
- return ret;
-}
-
-bool equal(Cube c1, Cube c2) {
- return c1.eofb == c2.eofb && c1.epose == c2.epose &&
- c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
- c1.coud == c2.coud && c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-bool solvable(Cube cube) {
- /* Since we memorize orientation truncating the last digit, we only need to
- * check that the permutations have the correct sign. */
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, fAll);
- return (perm_sign(arr.ep,12) ^ perm_sign(arr.cpos,6)) == perm_sign(arr.cp,8);
-}
-
-bool is_solved(Cube cube) {
- return !cube.eofb && !cube.coud && !cube.cp &&
- !cube.epose && !cube.eposs && !cube.eposm && cube.cpos;
-}
-
-void print_cube(Cube cube) {
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, fAll);
-
- for (int i = 0; i < 12; i++) printf(" %s ", edge_string[arr.ep[i]]);
- printf("\n");
- for (int i = 0; i < 12; i++) printf(" %c ", arr.eofb[i] + '0');
- printf("\n");
- for (int i = 0; i < 8; i++) printf("%s ", corner_string[arr.cp[i]]);
- printf("\n");
- for (int i = 0; i < 8; i++) printf(" %c ", arr.coud[i] + '0');
- printf("\n");
- for (int i = 0; i < 6; i++) printf(" %s ", center_string[arr.cpos[i]]);
- printf("\n");
-}
-
-Cube inverse_cube(Cube cube) {
- CubeArray arr = {0}, inv = {0};
- cube_to_arrays(cube, &arr, fAll);
-
- for (int i = 0; i < 12; i++) {
- inv.ep[arr.ep[i]] = i;
- inv.eofb[arr.ep[i]] = arr.eofb[i];
- inv.eorl[arr.ep[i]] = arr.eorl[i];
- inv.eoud[arr.ep[i]] = arr.eoud[i];
- }
- for (int i = 0; i < 8; i++) {
- inv.cp[arr.cp[i]] = i;
- inv.coud[arr.cp[i]] = arr.coud[i];
- inv.corl[arr.cp[i]] = arr.corl[i];
- inv.cofb[arr.cp[i]] = arr.cofb[i];
- }
- for (int i = 0; i < 6; i++)
- inv.cpos[arr.cpos[i]] = i;
-
- return arrays_to_cube(inv, fAll);
-}
-
-Cube compose_via_arrays(CubeArray arr2, Cube c1, PieceFilter f) {
- /* This is basically the same as the move_cubearray function above */
- CubeArray arr1 = {0};
- cube_to_arrays(c1, &arr1, fAll);
-
- apply_permutation(arr2.ep, arr1.ep, 12);
- apply_permutation(arr2.ep, arr1.eofb, 12);
- apply_permutation(arr2.ep, arr1.eorl, 12);
- apply_permutation(arr2.ep, arr1.eoud, 12);
- sum_arrays_mod(arr2.eofb, arr1.eofb, 12, 2);
- sum_arrays_mod(arr2.eorl, arr1.eorl, 12, 2);
- sum_arrays_mod(arr2.eoud, arr1.eoud, 12, 2);
- apply_permutation(arr2.cp, arr1.cp, 8);
- apply_permutation(arr2.cp, arr1.coud, 8);
- apply_permutation(arr2.cp, arr1.corl, 8);
- apply_permutation(arr2.cp, arr1.cofb, 8);
- sum_arrays_mod(arr2.coud, arr1.coud, 8, 3);
- sum_arrays_mod(arr2.corl, arr1.corl, 8, 3);
- sum_arrays_mod(arr2.cofb, arr1.cofb, 8, 3);
- apply_permutation(arr2.cpos, arr1.cpos, 6);
-
- return arrays_to_cube(arr1, fAll);
-}
diff --git a/old/2021-02-18-piecefilter/src/cube.h b/old/2021-02-18-piecefilter/src/cube.h
@@ -1,45 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "utils.h"
-
-typedef enum {U_center,D_center,R_center,L_center,F_center,B_center} Center;
-typedef enum { UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR } Edge;
-typedef enum { UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR } Corner;
-
-typedef struct {
- bool epose, eposs, eposm, eofb, eorl, eoud, cp, coud, cofb, corl, cpos;
-} PieceFilter;
-
-typedef struct {
- uint16_t eofb, eorl, eoud, coud, cofb, corl,
- epose, eposs, eposm, cp, cpos;
-} Cube;
-
-typedef struct {
- int ep[12], eofb[12], eorl[12], eoud[12],
- cp[8], coud[8], corl[8], cofb[8], cpos[6];
-} CubeArray;
-
-
-extern PieceFilter fAll;
-
-Cube blank_cube();
-/* Return axis (ud=0, rl=1, fb=0) of center c */
-int center_axis(int c);
-/* Return slice (e=0, s=1, m=2) to which e belongs */
-int edge_slice(int e);
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-Cube arrays_to_cube(CubeArray arr, PieceFilter f);
-bool equal(Cube c1, Cube c2);
-bool is_solvable(Cube cube);
-bool is_solved(Cube cube);
-void print_cube(Cube cube);
-Cube inverse_cube(Cube cube);
-/* Use c2 as an alg on c1 */
-Cube compose_via_arrays(CubeArray c2, Cube c1, PieceFilter f);
-
-#endif
diff --git a/old/2021-02-18-piecefilter/src/main.c b/old/2021-02-18-piecefilter/src/main.c
@@ -1,47 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "moves.h"
-#include "solve.h"
-
-int main() {
- init_ttables(true, true);
- init_aux_tables();
-
-
- char moves[100] = "MR U' B2 Bw F z xE2 M' x Dw' y Fw2 y2";
- NissMove alg[100];
- read_moves(moves, alg, 100);
- Cube cube = apply_alg(alg, blank_cube());
-
- /*f_eofb(cube);*/
-
-
-/* NissMove sol[MAXS][MAXM];*/
- SolveData d = { .optimal_only = true, .available = standard_moveset,
- .max_moves = 10,
- .cleanup = true,
- .max_solutions = 10,
- .f = f_eofb };
- read_moves("y", d.pre_rotation, 2);
- int n = solve(cube, &d);
- printf("%d solutions found:\n", n);
- for (int i = 0; i < n; i++)
- print_moves(d.solutions[i]);
-
- NissMove a[5], b[5];
- read_moves("R", a, 5);
- read_moves("U", b, 5);
- Cube c1 = apply_alg(a,blank_cube()), c2 = apply_alg(b,blank_cube());
- print_cube(compose(c2,c1));
- print_cube(compose(c1,c2));
- /*print_cube(compose(c2,blank_cube()));*/
-
- NissMove nm[10];
- read_moves("y(y)RU", nm, 10);
-
- print_moves(nm);
- cleanup(nm, 10);
- print_moves(nm);
-
- return 0;
-}
diff --git a/old/2021-02-18-piecefilter/src/moves.c b/old/2021-02-18-piecefilter/src/moves.c
@@ -1,482 +0,0 @@
-#include "moves.h"
-
-void move_cubearray(Move m, CubeArray *arr, PieceFilter f);
-Cube move_via_array(Move m, Cube cube, PieceFilter f);
-void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front);
-bool read_ttables_file();
-bool write_ttables_file();
-
-/* Transition tables */
-uint16_t epose_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposs_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposm_ttable[NMOVES][factorial12/factorial8];
-uint16_t eofb_ttable[NMOVES][pow2to11];
-uint16_t eorl_ttable[NMOVES][pow2to11];
-uint16_t eoud_ttable[NMOVES][pow2to11];
-uint16_t cp_ttable[NMOVES][factorial8];
-uint16_t coud_ttable[NMOVES][pow3to7];
-uint16_t cofb_ttable[NMOVES][pow3to7];
-uint16_t corl_ttable[NMOVES][pow3to7];
-uint16_t cpos_ttable[NMOVES][factorial6];
-
-bool commute[NMOVES][NMOVES];
-bool possible_next[NMOVES][NMOVES][NMOVES];
-Move inverse[NMOVES];
-
-char move_string[NMOVES][5] =
- { "-",
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'" };
-
-/* For each type of pieces only the effects of U, x and y are described */
-int edge_cycle[NMOVES][12] =
- { [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [x] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL} };
-int eofb_flipped[NMOVES][12] =
- { [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eorl_flipped[NMOVES][12] =
- { [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eoud_flipped[NMOVES][12] =
- { [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-int corner_cycle[NMOVES][8] =
- { [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL} };
-int coud_flipped[NMOVES][8] =
- { [x] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2} };
-int corl_flipped[NMOVES][8] =
- { [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1} };
-int cofb_flipped[NMOVES][8] =
- { [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=2,[UFL]=1,[DBL]=1,[DFL]=2},
- [y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2} };
-int center_cycle[NMOVES][6] =
- { [x] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [y] = {U_center, D_center, B_center, F_center, R_center, L_center} };
-
-/* Each move is reduced to a combination of U, x and y using this table */
-Move equiv_moves[NMOVES][14] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 },
- [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 },
- [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 },
- [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 },
- [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 },
- [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 },
- [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 },
- [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 },
- [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 },
- [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 },
- [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 },
- [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 },
- [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 },
- [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 },
- [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 },
- [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 },
-
- [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 },
- [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 },
- [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 },
- [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 },
- [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 },
- [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 },
- [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 },
- [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 },
- [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 },
-
- [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* Movesets */
-bool standard_moveset[NMOVES] = {
- [U] = true, [U2] = true, [U3] = true, [D] = true, [D2] = true, [D3] = true,
- [R] = true, [R2] = true, [R3] = true, [L] = true, [L2] = true, [L3] = true,
- [F] = true, [F2] = true, [F3] = true, [B] = true, [B2] = true, [B3] = true,
-};
-
-bool is_solved_up_to_reorient(Cube cube) {
- if (is_solved(cube))
- return true;
-
- /*TODO: improve this crap */
-
- bool ret = false;
- for (int i = x; i <= z3; i++) {
- ret = ret || is_solved(move_cube(i, cube));
- for (int j = x; j <= z3; j++)
- ret = ret || is_solved(move_cube(i, move_cube(j, cube)));
- }
- return ret;
-}
-
-void move_cubearray(Move m, CubeArray *arr, PieceFilter f) {
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(edge_cycle[m], arr->ep, 12);
- if (f.eofb) {
- apply_permutation(edge_cycle[m], arr->eofb, 12);
- sum_arrays_mod(eofb_flipped[m], arr->eofb, 12, 2);
- }
- if (f.eorl) {
- apply_permutation(edge_cycle[m], arr->eorl, 12);
- sum_arrays_mod(eorl_flipped[m], arr->eorl, 12, 2);
- }
- if (f.eoud) {
- apply_permutation(edge_cycle[m], arr->eoud, 12);
- sum_arrays_mod(eoud_flipped[m], arr->eoud, 12, 2);
- }
- if (f.cp)
- apply_permutation(corner_cycle[m], arr->cp, 8);
- if (f.coud) {
- apply_permutation(corner_cycle[m], arr->coud, 8);
- sum_arrays_mod(coud_flipped[m], arr->coud, 8, 3);
- }
- if (f.corl) {
- apply_permutation(corner_cycle[m], arr->corl, 8);
- sum_arrays_mod(corl_flipped[m], arr->corl, 8, 3);
- }
- if (f.cofb) {
- apply_permutation(corner_cycle[m], arr->cofb, 8);
- sum_arrays_mod(cofb_flipped[m], arr->cofb, 8, 3);
- }
- if (f.cpos)
- apply_permutation(center_cycle[m], arr->cpos, 6);
-}
-
-Cube move_via_array(Move m, Cube cube, PieceFilter f) {
- CubeArray arr = {0};
- cube_to_arrays(cube, &arr, f);
- move_cubearray(m, &arr, f);
- return arrays_to_cube(arr, f);
-}
-
-int copy_alg(NissMove *src, NissMove *dest) {
- int i;
- for (i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
- dest[i].m = NULLMOVE;
- return i;
-}
-
-/* TODO: all strings start with space?? */
-void print_moves(NissMove *alg) {
- bool niss = false;
- for (int i = 0; alg[i].m != NULLMOVE; i++) {
- char *fill = !niss && alg[i].inverse ? " (" :
- (niss && !alg[i].inverse ? ") " : " ");
- printf("%s%s", fill, move_string[alg[i].m]);
- niss = alg[i].inverse;
- }
- printf("%s\n", niss ? ")" : "");
-}
-
-int read_moves(char *str, NissMove *alg, int n) {
- bool niss = false;
- int c = 0;
-
- for (int i = 0; str[i] && c < n; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' || str[i] == ')') {
- if ((niss && str[i] == '(') || (!niss && str[i] == ')'))
- return -1;
- niss = !niss;
- continue;
- }
-
- alg[c].inverse = niss; alg[c].m = NULLMOVE;
- for (Move j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- alg[c].m = j;
- if (alg[c].m <= B && str[i+1]=='w') { alg[c].m += Uw - U; i++; }
- if (str[i+1]=='2') { alg[c].m += 1; i++; }
- else if (str[i+1]=='\'' || str[i+1]=='3') { alg[c].m += 2; i++; }
- c++;
- break;
- }
- }
- }
-
- alg[c].m = NULLMOVE;
- return c;
-}
-
-/* Helper function for cleanup. alg must contain only basic moves, no 2 or '.
- top and front describe an admissible orientation of the cube. */
-void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front) {
- int c = 0, i = 0;
- PieceFilter cpos_only = { .cpos = true };
- NissMove aux[n+3];
- aux[0].m = NULLMOVE;
-
- while (i < n && alg[i].m != NULLMOVE) {
- int j = i;
- while (j < n && commute[alg[i].m][alg[j].m]) j++;
- Move base = 6*((alg[i].m-1)/6);
- int t1 = 0, t2 = 0;
- for (int k = i; k < j; k++)
- if (alg[k].m == base+1) t1 = (t1+1)%4;
- else t2 = (t2+1)%4;
- if (t1) { aux[c].inverse = inv; aux[c].m = base+t1; c++; }
- if (t2) { aux[c].inverse = inv; aux[c].m = base+t2+3; c++; }
- i = j;
- }
- aux[c].m = NULLMOVE;
-
- CubeArray q;
- cube_to_arrays(blank_cube(), &q, cpos_only);
- /* First we try to rotate in one move, then we try an x or y rotation
- followed by a z rotation */
- for (int r = x; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front && q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c].m = r;
-
- aux[++c].m = NULLMOVE;
- copy_alg(aux, alg);
- return;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = x; r <= y3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = z; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
-
- aux[c].m = NULLMOVE;
- copy_alg(aux, alg);
-}
-
-/* TODO: does not work with niss + rotations */
-void cleanup(NissMove *alg, int n) {
- int count_n = 0, count_i = 0, *count;
- PieceFilter cpos_only = { .cpos = true };
- NissMove aux_n[n+1], aux_i[n+1], *aux;
- CubeArray cube_n, cube_i, *cube;
- cube_to_arrays(blank_cube(), &cube_n, cpos_only);
- cube_to_arrays(blank_cube(), &cube_i, cpos_only);
-
- for (int i = 0; count_n + count_i < n && alg[i].m != NULLMOVE; i++) {
- if (alg[i].inverse) { count = &count_i; aux = aux_i; cube = &cube_i; }
- else { count = &count_n; aux = aux_n; cube = &cube_n; }
-
- for (int j = 0; equiv_moves[alg[i].m][j]; j++) {
- Move m = equiv_moves[alg[i].m][j];
- aux[*count].inverse = alg[i].inverse;
- move_cubearray(m, cube, cpos_only);
- if (m == U) aux[(*count)++].m = 3 * cube->cpos[0] + 1;
- }
- }
-
- aux_n[count_n].m = NULLMOVE;
- aux_i[count_i].m = NULLMOVE;
- sort_cancel_rotate(aux_n, count_n, false, cube_n.cpos[0], cube_n.cpos[4]);
- sort_cancel_rotate(aux_i, count_i, true, cube_i.cpos[0], cube_n.cpos[4]);
- copy_alg(aux_n, alg);
- copy_alg(aux_i, alg+count_n);
-}
-
-bool read_ttables_file() {
- FILE *ttf;
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- for (int m = 0; m < NMOVES; m++) {
- fread(epose_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eposs_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eposm_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fread(eofb_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(eorl_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(eoud_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fread(cp_ttable[m], sizeof(uint16_t), factorial8, ttf);
- fread(coud_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(corl_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(cofb_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fread(cpos_ttable[m], sizeof(uint16_t), factorial6, ttf);
- }
- fclose(ttf);
- return true;
- } else return false;
-}
-
-bool write_ttables_file() {
- FILE *ttf;
- if ((ttf = fopen("ttables", "wb")) != NULL) {
- for (int m = 0; m < NMOVES; m++) {
- fwrite(epose_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eposs_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eposm_ttable[m], sizeof(uint16_t), factorial12/factorial8, ttf);
- fwrite(eofb_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(eorl_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(eoud_ttable[m], sizeof(uint16_t), pow2to11, ttf);
- fwrite(cp_ttable[m], sizeof(uint16_t), factorial8, ttf);
- fwrite(coud_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(corl_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(cofb_ttable[m], sizeof(uint16_t), pow3to7, ttf);
- fwrite(cpos_ttable[m], sizeof(uint16_t), factorial6, ttf);
- }
- fclose(ttf);
- return true;
- } else return false;
-}
-
-void init_ttables(bool read, bool write) {
- /* Generate all move cycles and flips; I do this regardless */
- for (int i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- CubeArray arr = {0};
- cube_to_arrays(blank_cube(), &arr, fAll);
- for (int j = 0; equiv_moves[i][j]; j++)
- move_cubearray(equiv_moves[i][j], &arr, fAll);
-
- intarrcopy(arr.ep, edge_cycle[i], 12);
- intarrcopy(arr.eofb, eofb_flipped[i], 12);
- intarrcopy(arr.eorl, eorl_flipped[i], 12);
- intarrcopy(arr.eoud, eoud_flipped[i], 12);
- intarrcopy(arr.cp, corner_cycle[i], 8);
- intarrcopy(arr.coud, coud_flipped[i], 8);
- intarrcopy(arr.corl, corl_flipped[i], 8);
- intarrcopy(arr.cofb, cofb_flipped[i], 8);
- intarrcopy(arr.cpos, center_cycle[i], 6);
- }
-
- if (read)
- if (read_ttables_file())
- return;
-
- /* Initialize transition tables */
- Cube c = {0};
- PieceFilter fe = {.epose=true}, fs = {.eposs=true}, fm = {.eposm=true};
- PieceFilter feo = { .eofb = true, .eorl = true, .eoud = true };
- PieceFilter fcp = { .cp = true };
- PieceFilter fco = { .cofb = true, .corl = true, .coud = true };
- PieceFilter fcc = { .cpos = true };
- for (int m = 0; m < NMOVES; m++) {
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- c.epose = i; epose_ttable[m][i] = move_via_array(m, c, fe).epose;
- c.eposs = i; eposs_ttable[m][i] = move_via_array(m, c, fs).eposs;
- c.eposm = i; eposm_ttable[m][i] = move_via_array(m, c, fm).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- c.eofb = i; eofb_ttable[m][i] = move_via_array(m, c, feo).eofb;
- c.eorl = i; eorl_ttable[m][i] = move_via_array(m, c, feo).eorl;
- c.eoud = i; eoud_ttable[m][i] = move_via_array(m, c, feo).eoud;
- }
- for (uint16_t i = 0; i < factorial8; i++) {
- c.cp = i; cp_ttable[m][i] = move_via_array(m, c, fcp).cp;
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- c.coud = i; coud_ttable[m][i] = move_via_array(m, c, fco).coud;
- c.corl = i; corl_ttable[m][i] = move_via_array(m, c, fco).corl;
- c.cofb = i; cofb_ttable[m][i] = move_via_array(m, c, fco).cofb;
- }
- for (uint16_t i = 0; i < factorial6; i++) {
- c.cpos = i; cpos_ttable[m][i] = move_via_array(m, c, fcc).cpos;
- }
- }
-
- if (write) write_ttables_file();
-}
-
-Cube move_cube(Move m, Cube cube) {
- Cube moved = cube;
-
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.cp = cp_ttable[m][cube.cp];
- moved.cpos = cpos_ttable[m][cube.cpos];
-
- return moved;
-}
-
-Cube apply_alg(NissMove *alg, Cube cube) {
- Cube ret = {0};
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- ret = compose(cube, inverse_cube(ret));
-
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (!alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- return ret;
-}
-
-void init_aux_tables() {
- /* Commute */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- commute[i][j] = equal(move_cube(i, move_cube(j, blank_cube())),
- move_cube(j, move_cube(i, blank_cube())));
-
- /* Possible next (if the sequence i j k is valid) */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- for (int k = 0; k < NMOVES; k++)
- possible_next[i][j][k] =
- (j == 0) ||
- (j != 0 && (j-(j-1)%3) != (k-(k-1)%3) &&
- !(i != 0 && commute[i][j] && (i-(i-1)%3) == (k-(k-1)%3)));
-
- /* Inverse */
- for (int i = 0; i < NMOVES; i++)
- inverse[i] = i == 0 ? 0 : i + 2 - 2*((i-1)%3);
-}
-
diff --git a/old/2021-02-18-piecefilter/src/moves.h b/old/2021-02-18-piecefilter/src/moves.h
@@ -1,46 +0,0 @@
-#ifndef MOVES_H
-#define MOVES_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "utils.h"
-
-#define NMOVES (z3+1)
-
-typedef enum {
- NULLMOVE,
- U, U2, U3, D, D2, D3, R, R2, R3, L, L2, L3, F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3, Rw, Rw2, Rw3,
- Lw, Lw2, Lw3, Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3, S, S2, S3, E, E2, E3,
- x, x2, x3, y, y2, y3, z, z2, z3,
-} Move;
-
-/* An alg is an array of "NissMoves", which can be on normal or on inverse. */
-typedef struct { bool inverse; Move m; } NissMove;
-
-/* Movesets */
-extern bool standard_moveset[NMOVES];
-
-extern bool commute[NMOVES][NMOVES];
-extern bool possible_next[NMOVES][NMOVES][NMOVES];
-extern Move inverse[NMOVES];
-
-bool is_solve_up_to_reorient(Cube cube);
-int copy_alg(NissMove *src, NissMove *dest); /*return number of moves copied */
-void print_moves(NissMove *alg);
-int read_moves(char *str, NissMove *alg, int n); /* reads at most n moves */
-void cleanup(NissMove *src, int n); /* rewrites using basic moves, at most n */
-Cube move_cube(Move m, Cube cube);
-/* I might want to replace this with two versions, one that uses PieceFilter */
-Cube apply_alg(NissMove *alg, Cube cube);
-
-/* Merge the following two?
- always in this order */
-void init_ttables(bool read, bool write);
-void init_aux_tables();
-
-
-#endif
diff --git a/old/2021-02-18-piecefilter/src/solve.c b/old/2021-02-18-piecefilter/src/solve.c
@@ -1,179 +0,0 @@
-#include "solve.h"
-
-/* Data for creating a pruning table:
- - compressed: if set to true, each entry occupies only 4 bits, but values
- larger than 15 cannot be stored.
- - available[] is the list of availabel moves, as above.
- - *ptable is the actual table to fill.
- - n is the number of states (size of ptable).
- - index must "linearize" the cube, i.e. return its index in ptable.
- - fname is the name of the file where to store the table */
-typedef struct {
- bool compressed, *available;
- int max_moves;
- uint8_t *ptable;
- uint64_t n;
- uint64_t (*index)(Cube);
- char *fname;
-} PruneData;
-
-/* TODO: comment this */
-typedef struct {
- bool niss;
- int m, d;
- uint64_t *n;
- Move last1, last2;
-} DfsData;
-
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd);
-void init_ptable(PruneData *pd, bool read, bool write);
-
-/* Search solutions of lenght exactly d */
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd) {
- if (*dd.n >= sd->max_solutions ||
- ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d))
- return;
-
- (sd->solutions[*dd.n][dd.m]).inverse = dd.niss;
- (sd->solutions[*dd.n][dd.m]).m = NULLMOVE;
-
- if (!sd->f(cube)) { /* Solved */
- if (dd.m == dd.d) {
- (*dd.n)++;
- if (*dd.n < sd->max_solutions)
- copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]);
- }
- return;
- }
-
- for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) {
- Move move = sd->sorted_moves[i];
- if (possible_next[dd.last2][dd.last1][move]) {
- sd->solutions[*dd.n][dd.m].inverse = dd.niss;
- sd->solutions[*dd.n][dd.m].m = move;
- DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = move, .last2 = dd.last1 };
- solve_dfs(move_cube(move, cube), sd, nn);
- }
- }
-
- if (sd->can_niss && !dd.niss &&
- (!dd.m || (dd.m && sd->f(move_cube(dd.last1, blank_cube()))))) {
- DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n };
- solve_dfs(inverse_cube(cube), sd, nn);
- }
-}
-
-/* Iterative deepening depth-first search: for i running from the minimum
- to the maximum number of moves allowed, looks for solutions of length i. */
-int solve(Cube cube, SolveData *sd) {
- if (sd->precondition != NULL && !sd->precondition(cube))
- return -1;
-
- /* If not given, generate sorted list of moves */
- if (sd->sorted_moves[0] == NULLMOVE) {
- int a[NMOVES], b[NMOVES], ia = 0, ib = 0;
- for (int i = 0; i < NMOVES; i++) {
- if (sd->available[i]) {
- if (sd->f(move_cube(i, blank_cube())))
- a[ia++] = i;
- else
- b[ib++] = i;
- }
- }
- intarrcopy(a, (int *)sd->sorted_moves, ia);
- intarrcopy(b, (int *)sd->sorted_moves+ia, ib);
- sd->sorted_moves[ia+ib] = NULLMOVE;
- }
-
- sd->max_solutions = min(sd->max_solutions, MAXS);
- /*TODO
- Cube rotated = apply_alg(sd->pre_rotation, blank_cube());
- cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
- */
-
- uint64_t ret = 0;
- for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
- DfsData dd = { .d = i, .n = &ret };
- solve_dfs(cube, sd, dd);
- }
-
- for (uint64_t i = 0; i < ret; i++) {
- /* TODO: transform solutions with inverse of pre_rotation */
- if (sd->cleanup)
- cleanup(sd->solutions[i], sd->max_moves*3);
- }
-
- return ret;
-}
-
-void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
- uint64_t ind = pd->index(cube);
- if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
- return;
- if (dd.m == dd.d) {
- if (ind && !pd->ptable[ind]) {
- pd->ptable[ind] = dd.m;
- (*dd.n)++;
- }
- return;
- }
-
- for (int i = 0; i < NMOVES; i++) {
- if (dd.m<20)
- if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
- DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = i, .last2 = dd.last1 };
- prune_dfs(move_cube(i, cube), pd, nn);
- }
- }
-}
-
-void init_ptable(PruneData *pd, bool read, bool write) {
- if (read) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "rb")) != NULL) {
- fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-
- /* TODO: for now it behaves always as if copressed = false */
- for (uint64_t i = 0; i < pd->n; i++)
- pd->ptable[i] = 0;
-
- uint64_t s = 1;
- for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
- DfsData dd = { .d = i, .n = &s };
- prune_dfs(blank_cube(), pd, dd);
- }
-
- if (write) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "wb")) != NULL) {
- fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-}
-
-/* Solving steps (and indexing functions) */
-
-uint64_t index_eofb(Cube cube) { return cube.eofb; }
-uint16_t f_eofb(Cube cube) {
- static bool initialized_ptable;
- static uint8_t pt_eofb[pow2to11];
- if (!initialized_ptable) {
- PruneData pd = {
- .compressed = false, .available = standard_moveset, .max_moves = 13,
- .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
- .fname = "ptable_eofb"
- };
- init_ptable(&pd, false, true);
- initialized_ptable = true;
- }
- return cube.eofb ? pt_eofb[cube.eofb] : 0;
-}
-
diff --git a/old/2021-02-18-piecefilter/src/solve.h b/old/2021-02-18-piecefilter/src/solve.h
@@ -1,56 +0,0 @@
-#ifndef SOLVE_H
-#define SOLVE_H
-
-#include <stdlib.h>
-#include "cube.h"
-#include "moves.h"
-
-/* Maximum number of moves per solution and of solutions */
-#define MAXM 30
-#define MAXS 999
-
-/* Data for solving a step:
- - can_niss is true niss can be used, false otherwise.
- - optimal_only if true, dynamically updates max_moves so non-optimal
- solutions are discarded.
- - cleanup determines whether the cleaunup() function should be used on
- the found solutions before returning.
- - available[m] is true if the move m can be used, false otherwise.
- - min_moves and max_moves are the minimum and maximum number of moves that
- can be used.
- - max_solution is the maximum number of solutions that can be returned.
- - precondition can be used to check wheter the step can actually be applied
- to the cube. If it returns false, solve() stops immediately returning -1.
- - f must return 0 if and only if the step is solve, otherwise it must return
- a lower bound for the number of moves required (without niss).
- - sorted_moves[] can be used to specify in which order moves are tried
- by the solving algorithm (for example if one wants to always try F' before
- F). If sorted_moves[0] == NULLMOVE, the list is generated automatically.
- It is advised to list first all the moves that actually influence the
- solved state of the step (this is the default choice). This is in order to
- avoid cases like B2 F for EO and to NISS only when it makes sense.
- - start_moves [Currently unused, REMOVE]
- are the moves that will be used as first moves of all
- solutions. For example giving R' U' F (F' U R) will generate FMC scrambles
- and y (y) will solve the step on another axis.
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wrt a different orientation
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wth respect to a different orientation.
- - solutions[][] is the array where to store the found solutions. */
-typedef struct {
- bool can_niss, optimal_only, cleanup, *available;
- int min_moves, max_moves;
- uint64_t max_solutions;
- bool (*precondition)(Cube);
- uint16_t (*f)(Cube);
- Move sorted_moves[NMOVES];
- NissMove pre_rotation[3], solutions[MAXS][MAXM];
-} SolveData;
-
-int solve(Cube cube, SolveData *data); /* Returns the number of solutions. */
-
-/* Steps */
-uint16_t f_eofb(Cube cube);
-
-#endif
diff --git a/old/2021-02-18-piecefilter/src/transformations.c b/old/2021-02-18-piecefilter/src/transformations.c
@@ -1,103 +0,0 @@
-#include "transformations.h"
-/*
-Cube apply_rotation_alg(Rotation r, Cube c);
-void apply_rotation_cube(NissMove *alg);
-Cube apply_mirror_cube(Cube c);
-void apply_mirror_alg(NissMove *alg);
-*/
-
-void compute_sources();
-Cube rotate_via_compose(Rotation r, Cube c);
-
-/* Values mod 3 to determine from which side to take the state to convert */
-int epose_source[NROTATIONS]; /* 0 = epose, 1 = eposs, 2 = eposm */
-int eposs_source[NROTATIONS];
-int eposm_source[NROTATIONS];
-int eofb_source[NROTATIONS]; /* 0 = eofb, 1 = eorl, 2 = eoud */
-int eorl_source[NROTATIONS];
-int eoud_source[NROTATIONS];
-int coud_source[NROTATIONS]; /* 0 = coud, 1 = cofb, 2 = corl */
-int cofb_source[NROTATIONS];
-int corl_source[NROTATIONS];
-
-/* Transition tables for rotations */
-uint16_t epose_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eposs_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eposm_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eofb_rtable[NROTATIONS][pow2to11];
-uint16_t eorl_rtable[NROTATIONS][pow2to11];
-uint16_t eoud_rtable[NROTATIONS][pow2to11];
-uint16_t cp_rtable[NROTATIONS][factorial8];
-uint16_t coud_rtable[NROTATIONS][pow3to7];
-uint16_t cofb_rtable[NROTATIONS][pow3to7];
-uint16_t corl_rtable[NROTATIONS][pow3to7];
-
-/* Transition tables for mirror */
-uint16_t epose_mtable[factorial12/factorial8];
-uint16_t eposs_mtable[factorial12/factorial8];
-uint16_t eposm_mtable[factorial12/factorial8];
-uint16_t eofb_mtable[pow2to11];
-uint16_t eorl_mtable[pow2to11];
-uint16_t eoud_mtable[pow2to11];
-uint16_t cp_mtable[factorial8];
-uint16_t coud_mtable[pow3to7];
-uint16_t cofb_mtable[pow3to7];
-uint16_t corl_mtable[pow3to7];
-
-/* Same for moves */
-uint16_t move_rtable[NROTATIONS][NMOVES];
-uint16_t move_mtable[NMOVES];
-
-/* Applying a rotation to the cube is equivalent to applying m (m) */
-Move equiv_moves[NROTATIONS][3] = {
- [uf] = {0,0,0}, [ur] = {y,0,0}, [ub] = {y2,0,0}, [ul] = {y3,0,0},
- [df] = {z2,0,0}, [dr] = {y,z2,0}, [db] = {y2,z2,0}, [dl] = {y3,z2,0},
- [rf] = {z3,0,0}, [rd] = {z3,y,0}, [rb] = {z3,y2,0}, [ru] = {z3,y3,0},
- [lf] = {z,0,0}, [ld] = {z,y3,0}, [lb] = {z,y2,0}, [lu] = {z,y,0},
- [fu] = {x,y2,0}, [fr] = {x,y,0}, [fd] = {x,0,0}, [fl] = {x,y3,0},
- [bu] = {x3,0,0}, [br] = {x3,y,0}, [bd] = {x3,y2,0}, [bl] = {x3,y3,0},
-};
-
-int mirror_ep[12] = {UF, UR, UB, UL, DF, DR, DB, DL, FL, FR, BR, BL};
-int mirror_cp[8] = {UFL, UFR, UBR, UBL, DFL, DFR, DBR, DBL};
-int mirror_cpos[6] = {U_center,D_center,L_center,R_center,F_center,B_center};
-
-void compute_sources() {
- /* epos{e,s,m} */
- CubeArray arr;
- for (int i = 0; i < NROTATIONS; i++) {
- cube_to_arrays(move_cube(equiv_moves[i][1],
- move_cube(equiv_moves[i][0], blank_cube())), &arr, fAll);
- epose_source[i] = edge_slice(arr.ep[FR]);
- eposs_source[i] = edge_slice(arr.ep[UR]);
- eposm_source[i] = edge_slice(arr.ep[UF]);
- eofb_source[i] = 2 - center_axis(arr.cpos[F_center]);
- eorl_source[i] = 2 - center_axis(arr.cpos[R_center]);
- eoud_source[i] = 2 - center_axis(arr.cpos[U_center]);
- coud_source[i] = (2 * center_axis(arr.cpos[U_center])) % 3;
- cofb_source[i] = (2 * center_axis(arr.cpos[F_center])) % 3;
- corl_source[i] = (2 * center_axis(arr.cpos[R_center])) % 3;
- }
-}
-
-/* Use Piecefilter? */
-Cube rotate_via_compose(Rotation r, Cube c) {
-/* TODO: if this is slow, change compose() in cube.{c,h} to use PieceFilter */
- int j = 0;
- NissMove nm[10] = {0};
- for (int i = 1; i >= 0; i--) {
- if (equiv_moves[r][i] != NULLMOVE) {
- nm[j].inverse = true;
- nm[j++].m = inverse[equiv_moves[r][i]];
- }
- }
- for (int i = 0; equiv_moves[r][i] != NULLMOVE; i++) {
- nm[j].inverse = false;
- nm[j++].m = equiv_moves[r][i];
- }
-
- return apply_alg(nm, c);
-}
-
-/* Use PieceFilter? Not really necessary, but could be nice */
-Cube mirror_via_cubearray(Cube c) {
diff --git a/old/2021-02-18-piecefilter/src/transformations.h b/old/2021-02-18-piecefilter/src/transformations.h
@@ -1,37 +0,0 @@
-#ifndef TRANSFORMATIONS_H
-#define TRANSFORMATIONS_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "moves.h"
-#include "utils.h"
-
-#define NROTATIONS (bl+1)
-
-/* Letters indicate top and front centers
- * Lowercase letter to distinguish from pieces */
-typedef enum {
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
-} Rotation;
-
-/* Mirror is always on fb axis and applied after rotation */
-typedef struct {
- Rotation rotation;
- bool mirror;
-} Transformation;
-
-void print_transformation(Transformation t);
-
-Cube transform_cube(Transformation t, Cube cube);
-void transform_alg(Transformation t, NissMove *alg); /* Applied in-place */
-
-void init_transformations(bool read, bool write);
-
-#endif
diff --git a/old/2021-02-18-piecefilter/src/utils.c b/old/2021-02-18-piecefilter/src/utils.c
@@ -1,197 +0,0 @@
-#include "utils.h"
-
-void swap(int *a, int *b) {
- int aux = *a;
- *a = *b;
- *b = aux;
-}
-
-void intarrcopy(int *src, int *dst, int n) {
- for (int i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-int sum(int *a, int n) {
- int ret = 0;
- for (int i = 0; i < n; i++)
- ret += a[i];
- return ret;
-}
-
-bool is_perm(int *a, int n) {
- int aux[n]; for (int i = 0; i < n; i++) aux[i] = 0;
- for (int i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
- for (int i = 0; i < n; i++)
- if (!aux[i])
- return false;
- return true;
-}
-
-bool is_subset(int *a, int n, int k) {
- int sum = 0;
- for (int i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
- return sum == k;
-}
-
-int powint(int a, int b) {
- return 0;
- if (b == 0 || a == 1)
- return 1;
- if (a == 0)
- return 0;
- if (b < 0)
- return 0; /* Immediate truncate (integer part is 0) */
- if (b % 2) {
- return a * powint(a, b-1);
- } else {
- int x = powint(a, b/2);
- return x*x;
- }
-}
-
-int factorial(int n) {
- if (n < 0)
- return 0;
- int ret = 1;
- for (int i = 1; i <= n; i++)
- ret *= i;
- return ret;
-}
-
-int binomial(int n, int k) {
- if (n < 0 || k < 0 || k > n)
- return 0;
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-void int_to_digit_array(int a, int b, int n, int *r) {
- if (b <= 1)
- for (int i = 0; i < n; i++)
- r[i] = 0;
- else
- for (int i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-int digit_array_to_int(int *a, int n, int b) {
- int ret = 0, p = 1;
- for (int i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
- return ret;
-}
-
-int perm_to_index(int *a, int n) {
- if (!is_perm(a, n))
- return factorial(n); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- int c = 0;
- for (int j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
- return ret;
-}
-
-void index_to_perm(int p, int n, int *r) {
- if (p < 0 || p >= factorial(n)) /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- int a[n]; for (int j = 0; j < n; j++) a[j] = 0; /* picked elements */
- for (int i = 0; i < n; i++) {
- int c = 0, j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-}
-
-int perm_sign(int *a, int n) {
- if (!is_perm(a,n))
- return false;
- int ret = 0;
- for (int i = 0; i < n; i++)
- for (int j = i+1; j < n; j++)
- ret += (a[i]>a[j]) ? 1 : 0;
- return ret % 2;
-}
-
-int subset_to_index(int *a, int n, int k) {
- /* TODO: better checks */
- if (!is_subset(a, n, k))
- return binomial(n, k); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- /*ret += factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- ret += binomial(n-i-1, k);
- k--;
- }
- }
- return ret;
-}
-
-void index_to_subset(int s, int n, int k, int *r) {
- if (s < 0 || s >= binomial(n, k)) { /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
- for (int i = 0; i < n; i++) {
- if (k == n-i) {
- for (int j = i; j < n; j++)
- r[j] = 1;
- return;
- }
- if (k == 0) {
- for (int j = i; j < n; j++)
- r[j] = 0;
- return;
- }
- /*int v = factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- int v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-void int_to_sum_zero_array(int x, int b, int n, int *a) {
- if (b <= 1) {
- for (int i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- int s = 0;
- for (int i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-void apply_permutation(int *perm, int *set, int n) {
- if (!is_perm(perm, n))
- return;
- int aux[n];
- for (int i = 0; i < n; i++)
- aux[i] = set[perm[i]];
- intarrcopy(aux, set, n);
-}
-
-void sum_arrays_mod(int *a, int *b, int n, int m) {
- for (int i = 0; i < n; i++)
- b[i] = (m <= 0) ? 0 : (a[i] + b[i]) % m;
-}
diff --git a/old/2021-02-18-piecefilter/src/utils.h b/old/2021-02-18-piecefilter/src/utils.h
@@ -1,70 +0,0 @@
-/* General utility functions */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Some useful constants */
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-/* Generic utility functions */
-void swap(int *a, int *b);
-void intarrcopy(int *src, int *dst, int n);
-int sum(int *a, int n);
-bool is_perm(int *a, int n);
-bool is_perm(int *a, int n);
-
-
-/* Standard mathematical functions */
-int powint(int a, int b);
-int factorial(int n);
-int binomial(int n, int k);
-
-/* Converts the integer a to its representation in base b (first n digits
- * only) and saves the result in r. */
-void int_to_digit_array(int a, int b, int n, int *r);
-int digit_array_to_int(int *a, int n, int b);
-
-/* Converts the first n-1 digits of a number to an array a of digits in base b;
- * then adds one element to the array, so that the sum of the elements of a is
- * zero modulo b.
- * This is used for determing the edge orientation from an 11-bits integer or
- * the corner orientation from a 7-trits integer. */
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-
-/* Converts a permutation on [0..(n-1)] into the integer i which is the index
- * of the permutation in the sorted list of all n! such permutations. */
-int perm_to_index(int *a, int n);
-void index_to_perm(int p, int n, int *r);
-
-/* Determine the sign of a permutation */
-int perm_sign(int a[], int n);
-
-/* Converts a k-element subset of a set from an array of n elements, of which k
- * are 1 and n-k are 0, to its index in the sorted list of all such subsets. */
-int subset_to_index(int *a, int n, int k);
-void index_to_subset(int s, int n, int k, int *r);
-
-int ordered_subset_to_index(int *a, int n, int k);
-void index_to_ordered_subset(int s, int n, int k, int *r);
-
-void apply_permutation(int *perm, int *set, int n);
-
-/* b[i] = (a[i]+b[i])%m for i=1,...,n */
-void sum_arrays_mod(int *a, int *b, int n, int m);
-
-#endif
diff --git a/old/2021-02-28-transformcube-works/src/cube.c b/old/2021-02-28-transformcube-works/src/cube.c
@@ -1,271 +0,0 @@
-#include "cube.h"
-
-typedef struct {
- int ep[12],eofb[12],eorl[12],eoud[12],cp[8],coud[8],corl[8],cofb[8],cpos[6];
-} CubeArrayAllocated;
-
-void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all);
-
-char edge_string[12][5] =
- { "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR" };
-char corner_string[8][5] = { "UFR","UFL","UBL","UBR","DFR","DFL","DBL","DBR" };
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-
-int epe_solved[4] = {FR, FL, BL, BR};
-int eps_solved[4] = {UL, UR, DL, DR};
-int epm_solved[4] = {UF, UB, DF, DB};
-
-PieceFilter pf_all = {true,true,true,true,true,true,true,true,true,true,true},
- pf_cpos = { .cpos = true }, pf_cp = { .cp = true },
- pf_ep = { .epose = true, .eposs = true, .eposm = true },
- pf_e = {.epose=true}, pf_s={.eposs=true}, pf_m={.eposm=true},
- pf_eo = { .eofb = true, .eorl = true, .eoud = true },
- pf_co = { .coud = true, .cofb = true, .corl = true };
-
-void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all) {
- arr->ep = all->ep;
- arr->eofb = all->eofb;
- arr->eorl = all->eorl;
- arr->eoud = all->eoud;
- arr->cp = all->cp;
- arr->coud = all->coud;
- arr->corl = all->corl;
- arr->cofb = all->cofb;
- arr->cpos = all->cpos;
-}
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) {
- /* ep is the hardest */
- if (f.epose || f.eposs || f.eposm)
- for (int i = 0; i < 12; i++) arr->ep[i] = -1;
- if (f.epose) {
- int epe[4], epose[12];
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- for (int i = 0, ie = 0; i < 12; i++)
- if (epose[i]) arr->ep[i] = epe_solved[epe[ie++]];
- }
- if (f.eposs) {
- int eps[4], eposs[12];
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- for (int i = 0, is = 0; i < 12; i++)
- if (eposs[i]) arr->ep[i] = eps_solved[eps[is++]];
- }
- if (f.eposm) {
- int epm[4], eposm[12];
- index_to_perm(cube.eposm % factorial(4), 4, epm);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- for (int i = 0, im = 0; i < 12; i++)
- if (eposm[i]) arr->ep[i] = epm_solved[epm[im++]];
- }
-
- /* All the others */
- if (f.eofb) int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl) int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud) int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp) index_to_perm( cube.cp, 8, arr->cp);
- if (f.coud) int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl) int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb) int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos) index_to_perm( cube.cpos, 6, arr->cpos);
-}
-
-Cube arrays_to_cube(CubeArray arr, PieceFilter f) {
- Cube ret = {0};
-
- /* Again, ep is the hardest part */
- if (f.epose) {
- int epe[4], epose[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, ie = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epe_solved[j])
- { epe[ie++] = j; epose[i] = 1; }
- ret.epose = factorial(4)*subset_to_index(epose,12,4)+perm_to_index(epe,4);
- }
- if (f.eposs) {
- int eps[4], eposs[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, is = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == eps_solved[j])
- { eps[is++] = j; eposs[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- ret.eposs = factorial(4)*subset_to_index(eposs,12,4)+perm_to_index(eps,4);
- }
- if (f.eposm) {
- int epm[4], eposm[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, im = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epm_solved[j])
- { epm[im++] = j; eposm[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- ret.eposm = factorial(4)*subset_to_index(eposm,12,4)+perm_to_index(epm,4);
- }
- if (f.eofb) ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
- if (f.eorl) ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
- if (f.eoud) ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
- if (f.cp) ret.cp = perm_to_index( arr.cp, 8 );
- if (f.coud) ret.coud = digit_array_to_int(arr.coud, 7, 3);
- if (f.corl) ret.corl = digit_array_to_int(arr.corl, 7, 3);
- if (f.cofb) ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
- if (f.cpos) ret.cpos = perm_to_index( arr.cpos, 6 );
-
- return ret;
-}
-
-Center center_at(Cube cube, Center c) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_cpos);
- return arr.cpos[c];
-}
-
-Edge edge_at(Cube cube, Edge e) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_ep);
- return arr.ep[e];
-}
-
-Corner corner_at(Cube cube, Corner c) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_cp);
- return arr.cp[c];
-}
-
-bool equal(Cube c1, Cube c2) {
- return c1.eofb == c2.eofb && c1.epose == c2.epose &&
- c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
- c1.coud == c2.coud && c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-bool is_solvable(Cube cube) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
- cube_to_arrays(cube, &arrx, pf_all);
-
- /* Since we memorize orientation truncating the last digit, we only need to
- * check that the permutations have the correct sign. */
- /* TODO: I should also check that the different eos and cos are compatible */
- return (perm_sign(arrx.ep,12)^perm_sign(arrx.cpos,6))==perm_sign(arrx.cp,8);
-}
-
-bool is_solved(Cube cube) {
- /* TODO: might return true if cube is not solvable but looks solved form one
- of the incompatible interpretations (e.g. eofb and ep solved, but
- eorl not solve) */
- return !cube.eofb && !cube.coud && !cube.cp &&
- !cube.epose && !cube.eposs && !cube.eposm && cube.cpos;
-}
-
-void print_cube(Cube cube) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
-
- cube_to_arrays(cube, &arrx, pf_all);
-
-/*
- for (int i = 0; i < 12; i++) printf("%d ", arrx.ep[i]);
- printf("\n");*/
-
- for (int i = 0; i < 12; i++) printf(" %s ", edge_string[arrx.ep[i]]);
- printf("\n");
- for (int i = 0; i < 12; i++) printf(" %c ", arrx.eofb[i] + '0');
- printf("\n");
- for (int i = 0; i < 8; i++) printf("%s ", corner_string[arrx.cp[i]]);
- printf("\n");
- for (int i = 0; i < 8; i++) printf(" %c ", arrx.coud[i] + '0');
- printf("\n");
- for (int i = 0; i < 6; i++) printf(" %s ", center_string[arrx.cpos[i]]);
- printf("\n");
-}
-
-Cube admissible_ep(Cube cube, PieceFilter f) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
- cube_to_arrays(cube, &arrx, f);
-
- bool used[12] = {0};
- for (int i = 0; i < 12; i++)
- if (arrx.ep[i] != -1)
- used[arrx.ep[i]] = true;
- for (int i = 0, j = 0; i < 12; i++) {
- while (j < 11 && used[j]) j++;
- if (arrx.ep[i] == -1)
- arrx.ep[i] = j++;
- }
-
- return arrays_to_cube(arrx, pf_ep);
-}
-
-Cube inverse_cube(Cube cube) {
- static CubeArrayAllocated all = {0}, invall = {0};
- CubeArray arrx = {0}, invx = {0};
- allocate_cubearray(&arrx, &all);
- allocate_cubearray(&invx, &invall);
-
- cube_to_arrays(cube, &arrx, pf_all);
-
- for (int i = 0; i < 12; i++) {
- invx.ep[arrx.ep[i]] = i;
- invx.eofb[arrx.ep[i]] = arrx.eofb[i];
- invx.eorl[arrx.ep[i]] = arrx.eorl[i];
- invx.eoud[arrx.ep[i]] = arrx.eoud[i];
- }
- for (int i = 0; i < 8; i++) {
- invx.cp[arrx.cp[i]] = i;
- invx.coud[arrx.cp[i]] = (3 - arrx.coud[i])%3;
- invx.corl[arrx.cp[i]] = (3 - arrx.corl[i])%3;
- invx.cofb[arrx.cp[i]] = (3 - arrx.cofb[i])%3;
- }
- for (int i = 0; i < 6; i++)
- invx.cpos[arrx.cpos[i]] = i;
-
- return arrays_to_cube(invx, pf_all);
-}
-
-Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter f) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
-
- cube_to_arrays(c, &arrx, f);
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation( arr.ep, arrx.ep, 12 );
- if (f.eofb) { apply_permutation( arr.ep, arrx.eofb, 12 );
- sum_arrays_mod( arr.eofb, arrx.eofb, 12, 2 ); }
- if (f.eorl) { apply_permutation( arr.ep, arrx.eorl, 12 );
- sum_arrays_mod( arr.eorl, arrx.eorl, 12, 2 ); }
- if (f.eoud) { apply_permutation( arr.ep, arrx.eoud, 12 );
- sum_arrays_mod( arr.eoud, arrx.eoud, 12, 2 ); }
- if (f.cp) apply_permutation( arr.cp, arrx.cp, 8 );
- if (f.coud) { apply_permutation( arr.cp, arrx.coud, 8 );
- sum_arrays_mod( arr.coud, arrx.coud, 8, 3 ); }
- if (f.corl) { apply_permutation( arr.cp, arrx.corl, 8 );
- sum_arrays_mod( arr.corl, arrx.corl, 8, 3 ); }
- if (f.cofb) { apply_permutation( arr.cp, arrx.cofb, 8 );
- sum_arrays_mod( arr.cofb, arrx.cofb, 8, 3 ); }
- if (f.cpos) apply_permutation( arr.cpos, arrx.cpos, 6 );
-
- return arrays_to_cube(arrx, f);
-}
-
-Cube compose(Cube c2, Cube c1) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
-
- cube_to_arrays(c2, &arrx, pf_all);
- return move_via_arrays(arrx, c1, pf_all);
-}
diff --git a/old/2021-02-28-transformcube-works/src/cube.h b/old/2021-02-28-transformcube-works/src/cube.h
@@ -1,55 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "utils.h"
-
-typedef enum {U_center,D_center,R_center,L_center,F_center,B_center} Center;
-typedef enum { UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR } Edge;
-typedef enum { UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR } Corner;
-
-typedef struct {
- uint16_t eofb, eorl, eoud, coud, cofb, corl,
- epose, eposs, eposm, cp, cpos;
-} Cube;
-
-typedef struct {
- bool epose, eposs, eposm, eofb, eorl, eoud, cp, coud, cofb, corl, cpos;
-} PieceFilter;
-
-typedef struct {
- int *ep, *eofb, *eorl, *eoud, *cp, *coud, *corl, *cofb, *cpos;
-} CubeArray;
-
-extern PieceFilter pf_all, pf_cpos, pf_ep, pf_cp,
- pf_e, pf_s, pf_m, pf_eo, pf_co;
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-Cube arrays_to_cube(CubeArray arr, PieceFilter f);
-
-Center center_at(Cube cube, Center c);
-Edge edge_at(Cube cube, Edge e);
-Corner corner_at(Cube cube, Corner c);
-/* Aggiungi funzioni per "queries" sul cubo: se pezzo è orientato rispetto ad
- un certo asse, se il pezzo è risolto... */
-/* Would be nice: a funciton block_solved(Cube c, Block b), where Block is
- something like struct {bool centers[6], edges[12], corners[8]}
- (The advantage over checking pieces one by one is that I can convert
- to cubearray only once and for all) */
-/* Altro TODO, ma forse non ne vale la pena: pre-calcolare tutti i possibili
- valori per questi, e salvare i risultati in array (facile per cp e cpos,
- mentre per ep bisogna anche cercare quale tra epose, eposs e eposm contiene
- il valore giusto) */
-
-bool equal(Cube c1, Cube c2);
-bool is_solvable(Cube cube);
-bool is_solved(Cube cube);
-void print_cube(Cube cube);
-Cube admissible_ep(Cube cube, PieceFilter f); /* Returns admissible ep */
-Cube inverse_cube(Cube cube);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter pf);
-
-#endif
diff --git a/old/2021-02-28-transformcube-works/src/main.c b/old/2021-02-28-transformcube-works/src/main.c
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "moves.h"
-#include "solve.h"
-#include "transformations.h"
-
-int main() {
- init_ttables(true, true);
- init_aux_tables();
- init_transformations(true, true);
-
-
- /*char moves[100] = "MR U' B2 Bw F z xE2 M' x Dw' y Fw2";*/
-
- /*char moves[100] = "M'U2MU2";*/
- char moves[100] = "R' D2 F2 U2 R F2 R D2 L' R2 D2 F D' L' U' B R' D' U R' B";
- NissMove alg[100];
- read_moves(moves, alg, 100);
- Cube cube = apply_alg(alg, (Cube){0});
- print_cube(cube);
- cube = transform_cube(rd, cube);
- print_cube(cube);
-
- /*f_eofb(cube);*/
-
-
- /*
- SolveData d = { .optimal_only = true, .available = standard_moveset,
- .max_moves = 10,
- .cleanup = true,
- .max_solutions = 10,
- .f = f_eofb };
- read_moves("y", d.pre_rotation, 2);
- int n = solve(cube, &d);
- printf("%d solutions found:\n", n);
- for (int i = 0; i < n; i++)
- print_moves(d.solutions[i]);
- */
-
-/*
- NissMove a[5], b[5];
- read_moves("R", a, 5);
- read_moves("U", b, 5);
- Cube c1 = apply_alg(a,(Cube){0}), c2 = apply_alg(b,(Cube){0});
- print_cube(compose(c2,c1));
- print_cube(compose(c1,c2));
-
- NissMove nm[10];
- read_moves("y(y)RU", nm, 10);
-
- print_moves(nm);
- cleanup(nm, 10);
- print_moves(nm);
- */
-
- return 0;
-}
diff --git a/old/2021-02-28-transformcube-works/src/moves.c b/old/2021-02-28-transformcube-works/src/moves.c
@@ -1,489 +0,0 @@
-#include "moves.h"
-
-Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-/* void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front); */
-bool read_ttables_file();
-bool write_ttables_file();
-
-/* Transition tables */
-uint16_t epose_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposs_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposm_ttable[NMOVES][factorial12/factorial8];
-uint16_t eofb_ttable[NMOVES][pow2to11];
-uint16_t eorl_ttable[NMOVES][pow2to11];
-uint16_t eoud_ttable[NMOVES][pow2to11];
-uint16_t cp_ttable[NMOVES][factorial8];
-uint16_t coud_ttable[NMOVES][pow3to7];
-uint16_t cofb_ttable[NMOVES][pow3to7];
-uint16_t corl_ttable[NMOVES][pow3to7];
-uint16_t cpos_ttable[NMOVES][factorial6];
-
-bool commute[NMOVES][NMOVES];
-bool possible_next[NMOVES][NMOVES][NMOVES];
-Move inverse[NMOVES];
-NissMove rotation_algs[24][3] = {
- { { .m = NULLMOVE }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = x2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y3 }, { .m = NULLMOVE } },
-};
-
-char move_string[NMOVES][5] =
- { "-",
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'" };
-
-/* For each type of pieces only the effects of U, x and y are described */
-int edge_cycle[NMOVES][12] =
- { [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [x] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL} };
-int eofb_flipped[NMOVES][12] =
- { [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eorl_flipped[NMOVES][12] =
- { [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eoud_flipped[NMOVES][12] =
- { [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-int corner_cycle[NMOVES][8] =
- { [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL} };
-int coud_flipped[NMOVES][8] =
- { [x] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2} };
-int corl_flipped[NMOVES][8] =
- { [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1} };
-int cofb_flipped[NMOVES][8] =
- { [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=1,[UFL]=2,[DBL]=2,[DFL]=1},
- [y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2} };
-int center_cycle[NMOVES][6] =
- { [x] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [y] = {U_center, D_center, B_center, F_center, R_center, L_center} };
-
-/* Each move is reduced to a combination of U, x and y using this table */
-Move equiv_moves[NMOVES][14] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 },
- [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 },
- [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 },
- [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 },
- [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 },
- [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 },
- [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 },
- [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 },
- [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 },
- [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 },
- [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 },
- [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 },
- [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 },
- [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 },
- [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 },
- [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 },
-
- [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 },
- [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 },
- [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 },
- [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 },
- [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 },
- [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 },
- [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 },
- [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 },
- [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 },
-
- [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* Movesets */
-bool standard_moveset[NMOVES] = {
- [U] = true, [U2] = true, [U3] = true, [D] = true, [D2] = true, [D3] = true,
- [R] = true, [R2] = true, [R3] = true, [L] = true, [L2] = true, [L3] = true,
- [F] = true, [F2] = true, [F3] = true, [B] = true, [B2] = true, [B3] = true,
-};
-
-bool is_solved_up_to_reorient(Cube cube) {
- for (int i = 0; i < 25; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube)))
- return true;
- return false;
-}
-
-Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f) {
- return move_via_arrays((CubeArray)
- { edge_cycle[m], eofb_flipped[m], eorl_flipped[m], eoud_flipped[m],
- corner_cycle[m], coud_flipped[m], corl_flipped[m], cofb_flipped[m],
- center_cycle[m] }, cube, f);
-}
-
-int len(NissMove *alg) {
- int i;
- for (i = 0; alg[i].m != NULLMOVE; i++);
- return i;
-}
-
-int copy_alg(NissMove *src, NissMove *dest) {
- int i;
- for (i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
- dest[i].m = NULLMOVE;
- return i;
-}
-
-int invert_alg(NissMove *src, NissMove *dest) {
- int n = len(src);
- for (int i = 0; i < n; i++)
- dest[n-i-1] = (NissMove){.m=inverse[src[i].m], .inverse=src[i].inverse};
- dest[n].m = NULLMOVE;
- return n;
-}
-
-int concat(NissMove *src1, NissMove *src2, NissMove *dest) {
- int n1 = len(src1), n2 = len(src2);
- copy_alg(src1, dest);
- copy_alg(src2, dest+n1);
- return n1+n2;
-}
-
-/* TODO: all strings start with space?? */
-void print_moves(NissMove *alg) {
- bool niss = false;
- for (int i = 0; alg[i].m != NULLMOVE; i++) {
- char *fill = !niss && alg[i].inverse ? " (" :
- (niss && !alg[i].inverse ? ") " : " ");
- printf("%s%s", fill, move_string[alg[i].m]);
- niss = alg[i].inverse;
- }
- printf("%s\n", niss ? ")" : "");
-}
-
-int read_moves(char *str, NissMove *alg, int n) {
- bool niss = false;
- int c = 0;
-
- for (int i = 0; str[i] && c < n; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' || str[i] == ')') {
- if ((niss && str[i] == '(') || (!niss && str[i] == ')'))
- return -1;
- niss = !niss;
- continue;
- }
-
- alg[c].inverse = niss; alg[c].m = NULLMOVE;
- for (Move j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- alg[c].m = j;
- if (alg[c].m <= B && str[i+1]=='w') { alg[c].m += Uw - U; i++; }
- if (str[i+1]=='2') { alg[c].m += 1; i++; }
- else if (str[i+1]=='\'' || str[i+1]=='3') { alg[c].m += 2; i++; }
- c++;
- break;
- }
- }
- }
-
- alg[c].m = NULLMOVE;
- return c;
-}
-
-/* Helper function for cleanup. alg must contain only basic moves, no 2 or '.
- top and front describe an admissible orientation of the cube. *
-void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front) {
- int c = 0, i = 0;
- PieceFilter cpos_only = { .cpos = true };
- NissMove aux[n+3];
- aux[0].m = NULLMOVE;
-
- while (i < n && alg[i].m != NULLMOVE) {
- int j = i;
- while (j < n && commute[alg[i].m][alg[j].m]) j++;
- Move base = 6*((alg[i].m-1)/6);
- int t1 = 0, t2 = 0;
- for (int k = i; k < j; k++)
- if (alg[k].m == base+1) t1 = (t1+1)%4;
- else t2 = (t2+1)%4;
- if (t1) { aux[c].inverse = inv; aux[c].m = base+t1; c++; }
- if (t2) { aux[c].inverse = inv; aux[c].m = base+t2+3; c++; }
- i = j;
- }
- aux[c].m = NULLMOVE;
-
- CubeArray q;
- cube_to_arrays((Cube){0}, &q, cpos_only);
- * First we try to rotate in one move, then we try an x or y rotation
- followed by a z rotation
- TODO: change once I implement the "is_rotaton(Move) function" *
- for (int r = x; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front && q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c].m = r;
-
- aux[++c].m = NULLMOVE;
- copy_alg(aux, alg);
- return;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = x; r <= y3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[F_center] == front) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
- for (int r = z; r <= z3; r++) {
- move_cubearray(r, &q, cpos_only);
- if (q.cpos[U_center] == top) {
- aux[c].inverse = inv; aux[c++].m = r;
- break;
- }
- move_cubearray(inverse[r], &q, cpos_only);
- }
-
- aux[c].m = NULLMOVE;
- copy_alg(aux, alg);
-}
-
-* TODO: does not work with niss + rotations *
-void cleanup(NissMove *alg, int n) {
- int count_n = 0, count_i = 0, *count;
- PieceFilter cpos_only = { .cpos = true };
- NissMove aux_n[n+1], aux_i[n+1], *aux;
- CubeArray cube_n, cube_i, *cube;
- cube_to_arrays((Cube){0}, &cube_n, cpos_only);
- cube_to_arrays((Cube){0}, &cube_i, cpos_only);
-
- for (int i = 0; count_n + count_i < n && alg[i].m != NULLMOVE; i++) {
- if (alg[i].inverse) { count = &count_i; aux = aux_i; cube = &cube_i; }
- else { count = &count_n; aux = aux_n; cube = &cube_n; }
-
- for (int j = 0; equiv_moves[alg[i].m][j]; j++) {
- Move m = equiv_moves[alg[i].m][j];
- aux[*count].inverse = alg[i].inverse;
- move_cubearray(m, cube, cpos_only);
- if (m == U) aux[(*count)++].m = 3 * cube->cpos[0] + 1;
- }
- }
-
- aux_n[count_n].m = NULLMOVE;
- aux_i[count_i].m = NULLMOVE;
- sort_cancel_rotate(aux_n, count_n, false, cube_n.cpos[0], cube_n.cpos[4]);
- sort_cancel_rotate(aux_i, count_i, true, cube_i.cpos[0], cube_n.cpos[4]);
- copy_alg(aux_n, alg);
- copy_alg(aux_i, alg+count_n);
-}
-*/
-
-bool read_ttables_file() {
- FILE *ttf;
- long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6 };
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NMOVES; m++) {
- r = r && fread(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fread(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fread(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fread(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fread(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fread(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5];
- r = r && fread(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fread(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fread(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fread(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9];
- r = r && fread(cpos_ttable[m], sizeof(uint16_t), me[10], ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-bool write_ttables_file() {
- FILE *ttf;
- long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6 };
- if ((ttf = fopen("ttables", "wb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fwrite(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fwrite(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fwrite(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fwrite(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fwrite(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5];
- r = r && fwrite(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fwrite(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fwrite(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fwrite(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9];
- r = r && fwrite(cpos_ttable[m], sizeof(uint16_t), me[10],ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-void init_ttables(bool read, bool write) {
- /* Generate all move cycles and flips; I do this regardless */
- for (int i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- Cube c = {0};
- for (int j = 0; equiv_moves[i][j]; j++)
- c = apply_move_cubearray(equiv_moves[i][j], c, pf_all);
-
- CubeArray arrs = {
- edge_cycle[i], eofb_flipped[i], eorl_flipped[i], eoud_flipped[i],
- corner_cycle[i], coud_flipped[i], corl_flipped[i], cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read)
- if (read_ttables_file())
- return;
-
- /* Initialize transition tables */
- for (int m = 0; m < NMOVES; m++) {
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- epose_ttable[m][i] = apply_move_cubearray(m,(Cube){.epose=i},pf_e).epose;
- eposs_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposs=i},pf_s).eposs;
- eposm_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposm=i},pf_m).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- eofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.eofb=i},pf_eo).eofb;
- eorl_ttable[m][i] = apply_move_cubearray(m,(Cube){.eorl=i},pf_eo).eorl;
- eoud_ttable[m][i] = apply_move_cubearray(m,(Cube){.eoud=i},pf_eo).eoud;
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- coud_ttable[m][i] = apply_move_cubearray(m,(Cube){.coud=i},pf_co).coud;
- corl_ttable[m][i] = apply_move_cubearray(m,(Cube){.corl=i},pf_co).corl;
- cofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.cofb=i},pf_co).cofb;
- }
- for (uint16_t i = 0; i < factorial8; i++)
- cp_ttable[m][i] = apply_move_cubearray(m,(Cube){.cp=i},pf_cp).cp;
- for (uint16_t i = 0; i < factorial6; i++)
- cpos_ttable[m][i] = apply_move_cubearray(m,(Cube){.cpos=i},pf_cpos).cpos;
- }
-
- if (write)
- if (!write_ttables_file())
- printf("Error in writing ttables: file not writable\n");
-}
-
-Cube move_cube(Move m, Cube cube) {
- Cube moved = {0};
-
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.cp = cp_ttable[m][cube.cp];
- moved.cpos = cpos_ttable[m][cube.cpos];
-
- return moved;
-}
-
-Cube apply_alg(NissMove *alg, Cube cube) {
- Cube ret = {0};
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
-
- ret = compose(cube, inverse_cube(ret));
-
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (!alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- return ret;
-}
-
-void init_aux_tables() {
- /* Commute */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- commute[i][j] = equal(move_cube(i, move_cube(j, (Cube){0})),
- move_cube(j, move_cube(i, (Cube){0})));
-
- /* Possible next (if the sequence i j k is valid) */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- for (int k = 0; k < NMOVES; k++)
- possible_next[i][j][k] =
- (j == 0) ||
- (j != 0 && (j-(j-1)%3) != (k-(k-1)%3) &&
- !(i != 0 && commute[i][j] && (i-(i-1)%3) == (k-(k-1)%3)));
-
- /* Inverse */
- for (int i = 0; i < NMOVES; i++)
- inverse[i] = i == NULLMOVE ? NULLMOVE : i + 2 - 2*((i-1)%3);
-
-}
-
diff --git a/old/2021-02-28-transformcube-works/src/moves.h b/old/2021-02-28-transformcube-works/src/moves.h
@@ -1,50 +0,0 @@
-#ifndef MOVES_H
-#define MOVES_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "utils.h"
-
-#define NMOVES (z3+1)
-
-typedef enum {
- NULLMOVE,
- U, U2, U3, D, D2, D3, R, R2, R3, L, L2, L3, F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3, Rw, Rw2, Rw3,
- Lw, Lw2, Lw3, Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3, S, S2, S3, E, E2, E3,
- x, x2, x3, y, y2, y3, z, z2, z3,
-} Move;
-
-/* An alg is an array of "NissMoves", which can be on normal or on inverse. */
-typedef struct { bool inverse; Move m; } NissMove;
-
-/* Movesets */
-extern bool standard_moveset[NMOVES];
-
-extern bool commute[NMOVES][NMOVES];
-extern bool possible_next[NMOVES][NMOVES][NMOVES];
-extern Move inverse[NMOVES];
-extern NissMove rotation_algs[24][3]; /* Same order as transformations */
-
-int len(NissMove *alg);
-int copy_alg(NissMove *src, NissMove *dest); /*return number of moves copied */
-int invert_alg(NissMove *src, NissMove *dest);
-int concat(NissMove *src1, NissMove *src2, NissMove *dest);
-void print_moves(NissMove *alg);
-int read_moves(char *str, NissMove *alg, int n); /* reads at most n moves */
-void cleanup(NissMove *src, int n); /* rewrites using basic moves, at most n */
-
-bool is_solved_up_to_reorient(Cube cube);
-Cube move_cube(Move m, Cube cube);
-Cube apply_alg(NissMove *alg, Cube cube);
-
-/* Merge the following two?
- always in this order */
-void init_ttables(bool read, bool write);
-void init_aux_tables();
-
-
-#endif
diff --git a/old/2021-02-28-transformcube-works/src/solve.c b/old/2021-02-28-transformcube-works/src/solve.c
@@ -1,180 +0,0 @@
-#include "solve.h"
-
-/* Data for creating a pruning table:
- - compressed: if set to true, each entry occupies only 4 bits, but values
- larger than 15 cannot be stored.
- - available[] is the list of availabel moves, as above.
- - *ptable is the actual table to fill.
- - n is the number of states (size of ptable).
- - index must "linearize" the cube, i.e. return its index in ptable.
- - fname is the name of the file where to store the table */
-typedef struct {
- bool compressed, *available;
- int max_moves;
- uint8_t *ptable;
- uint64_t n;
- uint64_t (*index)(Cube);
- char *fname;
-} PruneData;
-
-/* TODO: comment this */
-typedef struct {
- bool niss;
- int m, d;
- uint64_t *n;
- Move last1, last2;
-} DfsData;
-
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd);
-void init_ptable(PruneData *pd, bool read, bool write);
-
-/* Search solutions of lenght exactly d */
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd) {
- if (*dd.n >= sd->max_solutions ||
- ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d))
- return;
-
- (sd->solutions[*dd.n][dd.m]).inverse = dd.niss;
- (sd->solutions[*dd.n][dd.m]).m = NULLMOVE;
-
- if (!sd->f(cube)) { /* Solved */
- if (dd.m == dd.d) {
- (*dd.n)++;
- if (*dd.n < sd->max_solutions)
- copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]);
- }
- return;
- }
-
- for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) {
- Move move = sd->sorted_moves[i];
- if (possible_next[dd.last2][dd.last1][move]) {
- sd->solutions[*dd.n][dd.m].inverse = dd.niss;
- sd->solutions[*dd.n][dd.m].m = move;
- DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = move, .last2 = dd.last1 };
- solve_dfs(move_cube(move, cube), sd, nn);
- }
- }
-
- if (sd->can_niss && !dd.niss &&
- (!dd.m || (dd.m && sd->f(move_cube(dd.last1, (Cube){0}))))) {
- DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n };
- solve_dfs(inverse_cube(cube), sd, nn);
- }
-}
-
-/* Iterative deepening depth-first search: for i running from the minimum
- to the maximum number of moves allowed, looks for solutions of length i. */
-int solve(Cube cube, SolveData *sd) {
- if (sd->precondition != NULL && !sd->precondition(cube))
- return -1;
-
- /* If not given, generate sorted list of moves */
- if (sd->sorted_moves[0] == NULLMOVE) {
- int a[NMOVES], b[NMOVES], ia = 0, ib = 0;
- for (int i = 0; i < NMOVES; i++) {
- if (sd->available[i]) {
- if (sd->f(move_cube(i, (Cube){0})))
- a[ia++] = i;
- else
- b[ib++] = i;
- }
- }
- intarrcopy(a, (int *)sd->sorted_moves, ia);
- intarrcopy(b, (int *)sd->sorted_moves+ia, ib);
- sd->sorted_moves[ia+ib] = NULLMOVE;
- }
-
- sd->max_solutions = min(sd->max_solutions, MAXS);
- /*TODO
- Cube rotated = apply_alg(sd->pre_rotation, (Cube){0});
- cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
- */
-
- uint64_t ret = 0;
- for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
- DfsData dd = { .d = i, .n = &ret };
- solve_dfs(cube, sd, dd);
- }
-
- /* TODO: transform solutions with inverse of pre_rotation */
- /*
- for (uint64_t i = 0; i < ret; i++) {
- if (sd->cleanup)
- cleanup(sd->solutions[i], sd->max_moves*3);
- }*/
-
- return ret;
-}
-
-void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
- uint64_t ind = pd->index(cube);
- if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
- return;
- if (dd.m == dd.d) {
- if (ind && !pd->ptable[ind]) {
- pd->ptable[ind] = dd.m;
- (*dd.n)++;
- }
- return;
- }
-
- for (int i = 0; i < NMOVES; i++) {
- if (dd.m<20)
- if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
- DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = i, .last2 = dd.last1 };
- prune_dfs(move_cube(i, cube), pd, nn);
- }
- }
-}
-
-void init_ptable(PruneData *pd, bool read, bool write) {
- if (read) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "rb")) != NULL) {
- uint64_t r = fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- if (r == pd->n) return;
- }
- }
-
- /* TODO: for now it behaves always as if copressed = false */
- for (uint64_t i = 0; i < pd->n; i++)
- pd->ptable[i] = 0;
-
- uint64_t s = 1;
- for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
- DfsData dd = { .d = i, .n = &s };
- prune_dfs((Cube){0}, pd, dd);
- }
-
- if (write) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "wb")) != NULL) {
- fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-}
-
-/* Solving steps (and indexing functions) */
-
-uint64_t index_eofb(Cube cube) { return cube.eofb; }
-uint16_t f_eofb(Cube cube) {
- static bool initialized_ptable;
- static uint8_t pt_eofb[pow2to11];
- if (!initialized_ptable) {
- PruneData pd = {
- .compressed = false, .available = standard_moveset, .max_moves = 13,
- .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
- .fname = "ptable_eofb"
- };
- init_ptable(&pd, false, true);
- initialized_ptable = true;
- }
- return cube.eofb ? pt_eofb[cube.eofb] : 0;
-}
-
diff --git a/old/2021-02-28-transformcube-works/src/solve.h b/old/2021-02-28-transformcube-works/src/solve.h
@@ -1,56 +0,0 @@
-#ifndef SOLVE_H
-#define SOLVE_H
-
-#include <stdlib.h>
-#include "cube.h"
-#include "moves.h"
-
-/* Maximum number of moves per solution and of solutions */
-#define MAXM 30
-#define MAXS 999
-
-/* Data for solving a step:
- - can_niss is true niss can be used, false otherwise.
- - optimal_only if true, dynamically updates max_moves so non-optimal
- solutions are discarded.
- - cleanup determines whether the cleaunup() function should be used on
- the found solutions before returning.
- - available[m] is true if the move m can be used, false otherwise.
- - min_moves and max_moves are the minimum and maximum number of moves that
- can be used.
- - max_solution is the maximum number of solutions that can be returned.
- - precondition can be used to check wheter the step can actually be applied
- to the cube. If it returns false, solve() stops immediately returning -1.
- - f must return 0 if and only if the step is solve, otherwise it must return
- a lower bound for the number of moves required (without niss).
- - sorted_moves[] can be used to specify in which order moves are tried
- by the solving algorithm (for example if one wants to always try F' before
- F). If sorted_moves[0] == NULLMOVE, the list is generated automatically.
- It is advised to list first all the moves that actually influence the
- solved state of the step (this is the default choice). This is in order to
- avoid cases like B2 F for EO and to NISS only when it makes sense.
- - start_moves [Currently unused, REMOVE]
- are the moves that will be used as first moves of all
- solutions. For example giving R' U' F (F' U R) will generate FMC scrambles
- and y (y) will solve the step on another axis.
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wrt a different orientation
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wth respect to a different orientation.
- - solutions[][] is the array where to store the found solutions. */
-typedef struct {
- bool can_niss, optimal_only, cleanup, *available;
- int min_moves, max_moves;
- uint64_t max_solutions;
- bool (*precondition)(Cube);
- uint16_t (*f)(Cube);
- Move sorted_moves[NMOVES];
- NissMove pre_rotation[3], solutions[MAXS][MAXM];
-} SolveData;
-
-int solve(Cube cube, SolveData *data); /* Returns the number of solutions. */
-
-/* Steps */
-uint16_t f_eofb(Cube cube);
-
-#endif
diff --git a/old/2021-02-28-transformcube-works/src/transformations.c b/old/2021-02-28-transformcube-works/src/transformations.c
@@ -1,224 +0,0 @@
-#include "transformations.h"
-
-int edge_slice(int e); /* Return slice (e=0, s=1, m=2) to which e belongs */
-Cube rotate_via_compose(Transformation r, Cube c);
-bool read_rtables_file();
-bool write_rtables_file();
-
-/* Values mod 3 to determine from which side to take the state to convert */
-int epose_source[NROTATIONS]; /* 0 = epose, 1 = eposs, 2 = eposm */
-int eposs_source[NROTATIONS];
-int eposm_source[NROTATIONS];
-int eofb_source[NROTATIONS]; /* 0 = eoud, 1 = eorl, 2 = eofb */
-int eorl_source[NROTATIONS];
-int eoud_source[NROTATIONS];
-int coud_source[NROTATIONS]; /* 0 = coud, 1 = corl, 2 = cofb */
-int cofb_source[NROTATIONS];
-int corl_source[NROTATIONS];
-
-/* Transition tables for rotations (n+1 is mirror) */
-uint16_t epose_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eposs_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eposm_rtable[NROTATIONS][factorial12/factorial8];
-uint16_t eo_rtable[NROTATIONS][pow2to11];
-/*uint16_t eofb_rtable[NROTATIONS][pow2to11];
-uint16_t eorl_rtable[NROTATIONS][pow2to11];
-uint16_t eoud_rtable[NROTATIONS][pow2to11];*/
-uint16_t cp_rtable[NROTATIONS][factorial8];
-uint16_t co_rtable[NROTATIONS][pow3to7];
-/*uint16_t coud_rtable[NROTATIONS][pow3to7];
-uint16_t cofb_rtable[NROTATIONS][pow3to7];
-uint16_t corl_rtable[NROTATIONS][pow3to7];*/
-uint16_t cpos_rtable[NROTATIONS][factorial6];
-
-/* Same for moves */
-uint16_t move_rtable[NROTATIONS][NMOVES];
-
-NissMove rotation_niss[NROTATIONS][6];
-
-int edge_slice(int e) {
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
- return 2;
-}
-
-Cube rotate_via_compose(Transformation r, Cube c) {
- if (r != mirror) {
- return apply_alg(rotation_niss[r], c);
- } else {
- static int zero12[12] = {0,0,0,0,0,0,0,0,0,0,0,0},
- zero8[12] = {0,0,0,0,0,0,0,0},
- mirror_ep[12] = {UF,UR,UB,UL,DF,DR,DB,DL,FL,FR,BR,BL},
- mirror_cp[8] = {UFL, UFR, UBR, UBL, DFL, DFR, DBR, DBL},
- mirror_cpos[6] =
- {U_center,D_center,L_center,R_center,F_center,B_center};
- return move_via_arrays((CubeArray){
- .ep = mirror_ep, .eofb = zero12, .eorl = zero12, .eoud = zero12,
- .cp = mirror_cp, .coud = zero8, .corl = zero8, .cofb = zero8,
- .cpos = mirror_cpos}, c, pf_all);
- }
-}
-
-bool read_rtables_file() {
- FILE *ttf;
- long unsigned int me[12] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6, NMOVES };
- if ((ttf = fopen("rtables", "rb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NROTATIONS; m++) {
- r = r && fread(epose_rtable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fread(eposs_rtable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fread(eposm_rtable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fread(eo_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- /*r = r && fread(eofb_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fread(eorl_rtable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fread(eoud_rtable[m], sizeof(uint16_t), me[5], ttf) == me[5];*/
- r = r && fread(cp_rtable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fread(co_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- /*r = r && fread(coud_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fread(corl_rtable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fread(cofb_rtable[m], sizeof(uint16_t), me[9], ttf) == me[9];*/
- r = r && fread(cpos_rtable[m], sizeof(uint16_t), me[10], ttf) == me[10];
- r = r && fread(move_rtable[m], sizeof(uint16_t), me[11], ttf) == me[11];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-bool write_rtables_file() {
- FILE *ttf;
- long unsigned int me[12] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6, NMOVES };
- if ((ttf = fopen("rtables", "wb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NROTATIONS; m++) {
- r = r && fwrite(epose_rtable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fwrite(eposs_rtable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fwrite(eposm_rtable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fwrite(eo_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- /*r = r && fwrite(eofb_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fwrite(eorl_rtable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fwrite(eoud_rtable[m], sizeof(uint16_t), me[5], ttf) == me[5];*/
- r = r && fwrite(cp_rtable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fwrite(co_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- /*r = r && fwrite(coud_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fwrite(corl_rtable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fwrite(cofb_rtable[m], sizeof(uint16_t), me[9], ttf) == me[9];*/
- r = r && fwrite(cpos_rtable[m], sizeof(uint16_t), me[10],ttf) == me[10];
- r = r && fwrite(move_rtable[m], sizeof(uint16_t), me[11],ttf) == me[11];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-void init_transformations(bool read, bool write) {
- /* Compute sources */
- for (int i = 0; i < NROTATIONS; i++) {
- Cube cube = {0};
- if (i != mirror)
- cube = apply_alg(rotation_algs[i], (Cube){0});
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- /*TODO: maybe move down*/
- /* Compute rotation_niss array, necessary for rotate_via_compose */
- for (int r = 0; r != mirror; r++) {
- concat(rotation_algs[r], rotation_algs[r], rotation_niss[r]);
- for (int i = len(rotation_algs[r]); rotation_niss[r][i].m != NULLMOVE; i++)
- rotation_niss[r][i].inverse = true;
- }
-
- /* If I can read tables from file, I stop here */
- if (read)
- if (read_rtables_file())
- return;
-
- /* Initialize tables */
- for (int m = 0; m < NROTATIONS; m++) {
- int eparr[12] = {0,0,0,0,0,0,0,0,0,0,0,0}, cparr[8] = {0,0,0,0,0,0,0,0};
- CubeArray epcp = { .ep = eparr, .cp = cparr };
- cube_to_arrays(apply_alg(rotation_algs[m], (Cube){0}), &epcp,
- (PieceFilter){.epose=true,.eposs=true,.eposm=true,.cp=true});
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- Cube c[3] = { admissible_ep((Cube){ .epose = i}, pf_e),
- admissible_ep((Cube){ .eposs = i}, pf_s),
- admissible_ep((Cube){ .eposm = i}, pf_m) };
- epose_rtable[m][i] = rotate_via_compose(m, c[epose_source[m]]).epose;
- eposs_rtable[m][i] = rotate_via_compose(m, c[eposs_source[m]]).eposs;
- eposm_rtable[m][i] = rotate_via_compose(m, c[eposm_source[m]]).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- int eoarr[12];
- int_to_sum_zero_array(i, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_rtable[m][i] = digit_array_to_int(eoarr, 11, 2);
- /*Cube c[3] = {(Cube){.eoud=i}, (Cube){.eorl=i}, (Cube){.eofb=i}};
- eofb_rtable[m][i] = apply_alg(rotation_algs[m], (Cube){.eofb=i}).eofb;
- eorl_rtable[m][i] = rotate_via_compose(m, c[eorl_source[m]]).eorl;
- eoud_rtable[m][i] = rotate_via_compose(m, c[eoud_source[m]]).eoud;*/
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- int coarr[12];
- int_to_sum_zero_array(i, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_rtable[m][i] = digit_array_to_int(coarr, 8, 3);
- /*Cube c[3] = {(Cube){.coud=i}, (Cube){.corl=i}, (Cube){.cofb=i}};
- coud_rtable[m][i] = rotate_via_compose(m, c[coud_source[m]]).coud;
- corl_rtable[m][i] = rotate_via_compose(m, c[corl_source[m]]).corl;
- cofb_rtable[m][i] = rotate_via_compose(m, c[cofb_source[m]]).cofb;*/
- }
- for (uint16_t i = 0; i < factorial8; i++)
- cp_rtable[m][i] = rotate_via_compose(m, (Cube){.cp=i}).cp;
- for (uint16_t i = 0; i < factorial6; i++)
- cpos_rtable[m][i] = rotate_via_compose(m, (Cube){.cpos=i}).cpos;
- }
-
- if (write)
- if (!write_rtables_file())
- printf("Error in writing rtables: file not writable\n");
-}
-
-Cube transform_cube(Transformation t, Cube cube) {
- Cube transformed = {0};
-
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm },
- aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb },
- aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- transformed.epose = epose_rtable[t][aux_epos[epose_source[t]]];
- transformed.eposs = eposs_rtable[t][aux_epos[eposs_source[t]]];
- transformed.eposm = eposm_rtable[t][aux_epos[eposm_source[t]]];
- transformed.eofb = eo_rtable[t][aux_eo[eofb_source[t]]];
- transformed.eorl = eo_rtable[t][aux_eo[eorl_source[t]]];
- transformed.eoud = eo_rtable[t][aux_eo[eoud_source[t]]];
- transformed.coud = co_rtable[t][aux_co[coud_source[t]]];
- transformed.corl = co_rtable[t][aux_co[corl_source[t]]];
- transformed.cofb = co_rtable[t][aux_co[cofb_source[t]]];
- transformed.cp = cp_rtable[t][cube.cp];
- transformed.cpos = cpos_rtable[t][cube.cpos];
-
-/*
- printf("%d\n", coud_source[t]);
- int ccc[8];
- int_to_sum_zero_array(cube.cofb, 3, 8, ccc);
- for (int i = 0; i < 8; i++)
- printf("%d ", ccc[i]);
- printf("\n");
- */
-
- return transformed;
-}
diff --git a/old/2021-02-28-transformcube-works/src/transformations.h b/old/2021-02-28-transformcube-works/src/transformations.h
@@ -1,34 +0,0 @@
-#ifndef TRANSFORMATIONS_H
-#define TRANSFORMATIONS_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "moves.h"
-#include "utils.h"
-
-#define NROTATIONS (mirror+1)
-
-/* Letters indicate top and front centers
- * Mirror is wrt rl
- * Lowercase letter to distinguish from pieces */
-
-typedef enum {
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror,
-} Transformation;
-
-void print_transformation(Transformation t);
-
-Cube transform_cube(Transformation t, Cube cube);
-void transform_alg(Transformation t, NissMove *alg); /* Applied in-place */
-
-void init_transformations(bool read, bool write);
-
-#endif
diff --git a/old/2021-02-28-transformcube-works/src/utils.c b/old/2021-02-28-transformcube-works/src/utils.c
@@ -1,197 +0,0 @@
-#include "utils.h"
-
-void swap(int *a, int *b) {
- int aux = *a;
- *a = *b;
- *b = aux;
-}
-
-void intarrcopy(int *src, int *dst, int n) {
- for (int i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-int sum(int *a, int n) {
- int ret = 0;
- for (int i = 0; i < n; i++)
- ret += a[i];
- return ret;
-}
-
-bool is_perm(int *a, int n) {
- int aux[n]; for (int i = 0; i < n; i++) aux[i] = 0;
- for (int i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
- for (int i = 0; i < n; i++)
- if (!aux[i])
- return false;
- return true;
-}
-
-bool is_subset(int *a, int n, int k) {
- int sum = 0;
- for (int i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
- return sum == k;
-}
-
-int powint(int a, int b) {
- return 0;
- if (b == 0 || a == 1)
- return 1;
- if (a == 0)
- return 0;
- if (b < 0)
- return 0; /* Immediate truncate (integer part is 0) */
- if (b % 2) {
- return a * powint(a, b-1);
- } else {
- int x = powint(a, b/2);
- return x*x;
- }
-}
-
-int factorial(int n) {
- if (n < 0)
- return 0;
- int ret = 1;
- for (int i = 1; i <= n; i++)
- ret *= i;
- return ret;
-}
-
-int binomial(int n, int k) {
- if (n < 0 || k < 0 || k > n)
- return 0;
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-void int_to_digit_array(int a, int b, int n, int *r) {
- if (b <= 1)
- for (int i = 0; i < n; i++)
- r[i] = 0;
- else
- for (int i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-int digit_array_to_int(int *a, int n, int b) {
- int ret = 0, p = 1;
- for (int i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
- return ret;
-}
-
-int perm_to_index(int *a, int n) {
- if (!is_perm(a, n))
- return factorial(n); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- int c = 0;
- for (int j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
- return ret;
-}
-
-void index_to_perm(int p, int n, int *r) {
- if (p < 0 || p >= factorial(n)) /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- int a[n]; for (int j = 0; j < n; j++) a[j] = 0; /* picked elements */
- for (int i = 0; i < n; i++) {
- int c = 0, j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-}
-
-int perm_sign(int *a, int n) {
- if (!is_perm(a,n))
- return false;
- int ret = 0;
- for (int i = 0; i < n; i++)
- for (int j = i+1; j < n; j++)
- ret += (a[i]>a[j]) ? 1 : 0;
- return ret % 2;
-}
-
-int subset_to_index(int *a, int n, int k) {
- /* TODO: better checks */
- if (!is_subset(a, n, k))
- return binomial(n, k); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- /*ret += factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- ret += binomial(n-i-1, k);
- k--;
- }
- }
- return ret;
-}
-
-void index_to_subset(int s, int n, int k, int *r) {
- if (s < 0 || s >= binomial(n, k)) { /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
- for (int i = 0; i < n; i++) {
- if (k == n-i) {
- for (int j = i; j < n; j++)
- r[j] = 1;
- return;
- }
- if (k == 0) {
- for (int j = i; j < n; j++)
- r[j] = 0;
- return;
- }
- /*int v = factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- int v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-void int_to_sum_zero_array(int x, int b, int n, int *a) {
- if (b <= 1) {
- for (int i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- int s = 0;
- for (int i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-void apply_permutation(int *perm, int *set, int n) {
- if (!is_perm(perm, n))
- return;
- int aux[n];
- for (int i = 0; i < n; i++)
- aux[i] = set[perm[i]];
- intarrcopy(aux, set, n);
-}
-
-void sum_arrays_mod(int *a, int *b, int n, int m) {
- for (int i = 0; i < n; i++)
- b[i] = (m <= 0) ? 0 : (a[i] + b[i]) % m;
-}
diff --git a/old/2021-02-28-transformcube-works/src/utils.h b/old/2021-02-28-transformcube-works/src/utils.h
@@ -1,70 +0,0 @@
-/* General utility functions */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Some useful constants */
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-/* Generic utility functions */
-void swap(int *a, int *b);
-void intarrcopy(int *src, int *dst, int n);
-int sum(int *a, int n);
-bool is_perm(int *a, int n);
-bool is_perm(int *a, int n);
-
-
-/* Standard mathematical functions */
-int powint(int a, int b);
-int factorial(int n);
-int binomial(int n, int k);
-
-/* Converts the integer a to its representation in base b (first n digits
- * only) and saves the result in r. */
-void int_to_digit_array(int a, int b, int n, int *r);
-int digit_array_to_int(int *a, int n, int b);
-
-/* Converts the first n-1 digits of a number to an array a of digits in base b;
- * then adds one element to the array, so that the sum of the elements of a is
- * zero modulo b.
- * This is used for determing the edge orientation from an 11-bits integer or
- * the corner orientation from a 7-trits integer. */
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-
-/* Converts a permutation on [0..(n-1)] into the integer i which is the index
- * of the permutation in the sorted list of all n! such permutations. */
-int perm_to_index(int *a, int n);
-void index_to_perm(int p, int n, int *r);
-
-/* Determine the sign of a permutation */
-int perm_sign(int a[], int n);
-
-/* Converts a k-element subset of a set from an array of n elements, of which k
- * are 1 and n-k are 0, to its index in the sorted list of all such subsets. */
-int subset_to_index(int *a, int n, int k);
-void index_to_subset(int s, int n, int k, int *r);
-
-int ordered_subset_to_index(int *a, int n, int k);
-void index_to_ordered_subset(int s, int n, int k, int *r);
-
-void apply_permutation(int *perm, int *set, int n);
-
-/* b[i] = (a[i]+b[i])%m for i=1,...,n */
-void sum_arrays_mod(int *a, int *b, int n, int m);
-
-#endif
diff --git a/old/2021-05-26-before-restyle/cube.c b/old/2021-05-26-before-restyle/cube.c
@@ -1,293 +0,0 @@
-#include "cube.h"
-
-typedef struct {
- int ep[12],eofb[12],eorl[12],eoud[12],cp[8],coud[8],corl[8],cofb[8],cpos[6];
-} CubeArrayAllocated;
-
-void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all);
-
-char edge_string[12][5] =
- { "UF", "UL", "UB", "UR", "DF", "DL", "DB", "DR", "FR", "FL", "BL", "BR" };
-char corner_string[8][5] = { "UFR","UFL","UBL","UBR","DFR","DFL","DBL","DBR" };
-char center_string[6][5] = { "U", "D", "R", "L", "F", "B" };
-
-int epe_solved[4] = {FR, FL, BL, BR};
-int eps_solved[4] = {UL, UR, DL, DR};
-int epm_solved[4] = {UF, UB, DF, DB};
-
-PieceFilter pf_all = {true,true,true,true,true,true,true,true,true,true,true},
- pf_cpos = { .cpos = true }, pf_cp = { .cp = true },
- pf_ep = { .epose = true, .eposs = true, .eposm = true },
- pf_e = {.epose=true}, pf_s={.eposs=true}, pf_m={.eposm=true},
- pf_eo = { .eofb = true, .eorl = true, .eoud = true },
- pf_co = { .coud = true, .cofb = true, .corl = true };
-
-void allocate_cubearray(CubeArray *arr, CubeArrayAllocated *all) {
- arr->ep = all->ep;
- arr->eofb = all->eofb;
- arr->eorl = all->eorl;
- arr->eoud = all->eoud;
- arr->cp = all->cp;
- arr->coud = all->coud;
- arr->corl = all->corl;
- arr->cofb = all->cofb;
- arr->cpos = all->cpos;
-}
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f) {
- /* ep is the hardest */
- if (f.epose || f.eposs || f.eposm)
- for (int i = 0; i < 12; i++) arr->ep[i] = -1;
- if (f.epose) {
- int epe[4], epose[12];
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- for (int i = 0, ie = 0; i < 12; i++)
- if (epose[i]) arr->ep[i] = epe_solved[epe[ie++]];
- }
- if (f.eposs) {
- int eps[4], eposs[12];
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- for (int i = 0, is = 0; i < 12; i++)
- if (eposs[i]) arr->ep[i] = eps_solved[eps[is++]];
- }
- if (f.eposm) {
- int epm[4], eposm[12];
- index_to_perm(cube.eposm % factorial(4), 4, epm);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- for (int i = 0, im = 0; i < 12; i++)
- if (eposm[i]) arr->ep[i] = epm_solved[epm[im++]];
- }
-
- /* All the others */
- if (f.eofb) int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl) int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud) int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp) index_to_perm( cube.cp, 8, arr->cp);
- if (f.coud) int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl) int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb) int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos) index_to_perm( cube.cpos, 6, arr->cpos);
-}
-
-Cube arrays_to_cube(CubeArray arr, PieceFilter f) {
- Cube ret = {0};
-
- /* Again, ep is the hardest part */
- if (f.epose) {
- int epe[4], epose[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, ie = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epe_solved[j])
- { epe[ie++] = j; epose[i] = 1; }
- ret.epose = factorial(4)*subset_to_index(epose,12,4)+perm_to_index(epe,4);
- }
- if (f.eposs) {
- int eps[4], eposs[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, is = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == eps_solved[j])
- { eps[is++] = j; eposs[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposs[eps_solved[i]], &eposs[i+8]);
- ret.eposs = factorial(4)*subset_to_index(eposs,12,4)+perm_to_index(eps,4);
- }
- if (f.eposm) {
- int epm[4], eposm[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
- for (int i = 0, im = 0; i < 12; i++)
- for (int j = 0; j < 4; j++)
- if (arr.ep[i] == epm_solved[j])
- { epm[im++] = j; eposm[i] = 1; }
- for (int i = 0; i < 4; i++) swap(&eposm[epm_solved[i]], &eposm[i+8]);
- ret.eposm = factorial(4)*subset_to_index(eposm,12,4)+perm_to_index(epm,4);
- }
- if (f.eofb) ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
- if (f.eorl) ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
- if (f.eoud) ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
- if (f.cp) ret.cp = perm_to_index( arr.cp, 8 );
- if (f.coud) ret.coud = digit_array_to_int(arr.coud, 7, 3);
- if (f.corl) ret.corl = digit_array_to_int(arr.corl, 7, 3);
- if (f.cofb) ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
- if (f.cpos) ret.cpos = perm_to_index( arr.cpos, 6 );
-
- return ret;
-}
-
-int piece_orientation(Cube cube, int piece, char *orientation) {
- int arr[12], n, b;
- uint16_t x;
- if (!strcmp(orientation, "eofb")) { x = cube.eofb; n = 12; b = 2; } else
- if (!strcmp(orientation, "eorl")) { x = cube.eorl; n = 12; b = 2; } else
- if (!strcmp(orientation, "eoud")) { x = cube.eoud; n = 12; b = 2; } else
- if (!strcmp(orientation, "coud")) { x = cube.coud; n = 8; b = 3; } else
- if (!strcmp(orientation, "corl")) { x = cube.corl; n = 8; b = 3; } else
- if (!strcmp(orientation, "cofb")) { x = cube.cofb; n = 8; b = 3; }
- else return -1;
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
- return -1;
-}
-
-Center center_at(Cube cube, Center c) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_cpos);
- return arr.cpos[c];
-}
-
-Edge edge_at(Cube cube, Edge e) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_ep);
- return arr.ep[e];
-}
-
-Corner corner_at(Cube cube, Corner c) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_cp);
- return arr.cp[c];
-}
-
-bool block_solved(Cube cube, Block block) {
- static CubeArrayAllocated all = {0};
- CubeArray arr = {0};
- allocate_cubearray(&arr, &all);
- cube_to_arrays(cube, &arr, pf_all);
-
- bool ret = true;
-
- for (int i = 0; i < 12; i++)
- ret = ret && !(block.edge[i] && (arr.ep[i] != i || arr.eofb[i]));
- for (int i = 0; i < 8; i++)
- ret = ret && !(block.corner[i] && (arr.cp[i] != i || arr.coud[i]));
- for (int i = 0; i < 6; i++)
- ret = ret && !(block.center[i] && arr.cpos[i] != i);
-
- return ret;
-}
-
-bool equal(Cube c1, Cube c2) {
- return c1.eofb == c2.eofb && c1.epose == c2.epose &&
- c1.eposs == c2.eposs && c1.eposm == c2.eposm &&
- c1.coud == c2.coud && c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-bool is_solved(Cube cube) {
- /* TODO: might return true if cube is not solvable but looks solved form one
- of the incompatible interpretations (e.g. eofb and ep solved, but
- eorl not solve) */
- return !cube.eofb && !cube.coud && !cube.cp &&
- !cube.epose && !cube.eposs && !cube.eposm && !cube.cpos;
-}
-
-void print_cube(Cube cube) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
- cube_to_arrays(cube, &arrx, pf_all);
-
- for (int i = 0; i < 12; i++) printf(" %s ", edge_string[arrx.ep[i]]);
- printf("\n");
- for (int i = 0; i < 12; i++) printf(" %c ", arrx.eofb[i] + '0');
- printf("\n");
- for (int i = 0; i < 8; i++) printf("%s ", corner_string[arrx.cp[i]]);
- printf("\n");
- for (int i = 0; i < 8; i++) printf(" %c ", arrx.coud[i] + '0');
- printf("\n");
- for (int i = 0; i < 6; i++) printf(" %s ", center_string[arrx.cpos[i]]);
- printf("\n");
-}
-
-Cube admissible_ep(Cube cube, PieceFilter f) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
- cube_to_arrays(cube, &arrx, f);
-
- bool used[12] = {0};
- for (int i = 0; i < 12; i++)
- if (arrx.ep[i] != -1)
- used[arrx.ep[i]] = true;
- for (int i = 0, j = 0; i < 12; i++) {
- while (j < 11 && used[j]) j++;
- if (arrx.ep[i] == -1)
- arrx.ep[i] = j++;
- }
-
- return arrays_to_cube(arrx, pf_ep);
-}
-
-Cube inverse_cube(Cube cube) {
- static CubeArrayAllocated all = {0}, invall = {0};
- CubeArray arrx = {0}, invx = {0};
- allocate_cubearray(&arrx, &all);
- allocate_cubearray(&invx, &invall);
-
- cube_to_arrays(cube, &arrx, pf_all);
-
- for (int i = 0; i < 12; i++) {
- invx.ep[arrx.ep[i]] = i;
- invx.eofb[arrx.ep[i]] = arrx.eofb[i];
- invx.eorl[arrx.ep[i]] = arrx.eorl[i];
- invx.eoud[arrx.ep[i]] = arrx.eoud[i];
- }
- for (int i = 0; i < 8; i++) {
- invx.cp[arrx.cp[i]] = i;
- invx.coud[arrx.cp[i]] = (3 - arrx.coud[i])%3;
- invx.corl[arrx.cp[i]] = (3 - arrx.corl[i])%3;
- invx.cofb[arrx.cp[i]] = (3 - arrx.cofb[i])%3;
- }
- for (int i = 0; i < 6; i++)
- invx.cpos[arrx.cpos[i]] = i;
-
- return arrays_to_cube(invx, pf_all);
-}
-
-Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter f) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
-
- cube_to_arrays(c, &arrx, f);
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation( arr.ep, arrx.ep, 12 );
- if (f.eofb) { apply_permutation( arr.ep, arrx.eofb, 12 );
- sum_arrays_mod( arr.eofb, arrx.eofb, 12, 2 ); }
- if (f.eorl) { apply_permutation( arr.ep, arrx.eorl, 12 );
- sum_arrays_mod( arr.eorl, arrx.eorl, 12, 2 ); }
- if (f.eoud) { apply_permutation( arr.ep, arrx.eoud, 12 );
- sum_arrays_mod( arr.eoud, arrx.eoud, 12, 2 ); }
- if (f.cp) apply_permutation( arr.cp, arrx.cp, 8 );
- if (f.coud) { apply_permutation( arr.cp, arrx.coud, 8 );
- sum_arrays_mod( arr.coud, arrx.coud, 8, 3 ); }
- if (f.corl) { apply_permutation( arr.cp, arrx.corl, 8 );
- sum_arrays_mod( arr.corl, arrx.corl, 8, 3 ); }
- if (f.cofb) { apply_permutation( arr.cp, arrx.cofb, 8 );
- sum_arrays_mod( arr.cofb, arrx.cofb, 8, 3 ); }
- if (f.cpos) apply_permutation( arr.cpos, arrx.cpos, 6 );
-
- return arrays_to_cube(arrx, f);
-}
-
-Cube compose_filtered(Cube c2, Cube c1, PieceFilter f) {
- static CubeArrayAllocated all = {0};
- CubeArray arrx = {0};
- allocate_cubearray(&arrx, &all);
-
- cube_to_arrays(c2, &arrx, f);
- return move_via_arrays(arrx, c1, f);
-}
-
-Cube compose(Cube c2, Cube c1) {
- return compose_filtered(c2, c1, pf_all);
-}
diff --git a/old/2021-05-26-before-restyle/cube.h b/old/2021-05-26-before-restyle/cube.h
@@ -1,65 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include "utils.h"
-
-typedef enum {U_center,D_center,R_center,L_center,F_center,B_center} Center;
-typedef enum { UF, UL, UB, UR, DF, DL, DB, DR, FR, FL, BL, BR } Edge;
-typedef enum { UFR, UFL, UBL, UBR, DFR, DFL, DBL, DBR } Corner;
-
-typedef struct {
- uint16_t eofb, eorl, eoud, coud, cofb, corl,
- epose, eposs, eposm, cp, cpos;
-} Cube;
-
-typedef struct {
- bool edge[12], corner[8], center[6];
-} Block;
-
-typedef struct {
- bool epose, eposs, eposm, eofb, eorl, eoud, cp, coud, cofb, corl, cpos;
-} PieceFilter;
-
-typedef struct {
- int *ep, *eofb, *eorl, *eoud, *cp, *coud, *corl, *cofb, *cpos;
-} CubeArray;
-
-extern PieceFilter pf_all, pf_cpos, pf_ep, pf_cp,
- pf_e, pf_s, pf_m, pf_eo, pf_co;
-
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-Cube arrays_to_cube(CubeArray arr, PieceFilter f);
-
-/* piece can be edge or corner and orientation is any of the following:
- "eofb", "eorl", "eoud", "coud", "corl", "cofb"
- Return either 0 (oriented) or 1 for edges and 0, 1 or 2 for corners */
-int piece_orientation(Cube cube, int piece, char *orientation);
-Center center_at(Cube cube, Center c);
-Edge edge_at(Cube cube, Edge e);
-Corner corner_at(Cube cube, Corner c);
-bool block_solved(Cube cube, Block);
-/* Aggiungi funzioni per "queries" sul cubo: se pezzo è orientato rispetto ad
- un certo asse, se il pezzo è risolto... */
-/* Would be nice: a funciton block_solved(Cube c, Block b), where Block is
- something like struct {bool centers[6], edges[12], corners[8]}
- (The advantage over checking pieces one by one is that I can convert
- to cubearray only once and for all) */
-/* Altro TODO, ma forse non ne vale la pena: pre-calcolare tutti i possibili
- valori per questi, e salvare i risultati in array (facile per cp e cpos,
- mentre per ep bisogna anche cercare quale tra epose, eposs e eposm contiene
- il valore giusto) */
-
-bool equal(Cube c1, Cube c2);
-bool is_solved(Cube cube);
-void print_cube(Cube cube);
-Cube admissible_ep(Cube cube, PieceFilter f); /* Returns admissible ep */
-Cube inverse_cube(Cube cube);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter pf);
-
-#endif
diff --git a/old/2021-05-26-before-restyle/main.c b/old/2021-05-26-before-restyle/main.c
@@ -1,24 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "moves.h"
-#include "solve.h"
-#include "transformations.h"
-
-int main() {
- init_ttables(true, true);
- init_aux_tables();
- init_transformations(true, true);
-
-
- char moves[100] = "R' D2 F2 U2 R F2 R D2 L' R2 D2 F D' L' U' B R' D' U R' B";
- NissMove alg[100];
- read_moves(moves, alg, 100);
- Cube cube = apply_alg(alg, (Cube){0});
- print_cube(transform_cube(rd, cube));
-
- transform_alg(rd, alg);
- print_alg(alg);
-
-
- return 0;
-}
diff --git a/old/2021-05-26-before-restyle/moves.c b/old/2021-05-26-before-restyle/moves.c
@@ -1,412 +0,0 @@
-#include "moves.h"
-
-Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-/* void sort_cancel_rotate(NissMove *alg, int n, bool inv, int top, int front); */
-bool read_ttables_file();
-bool write_ttables_file();
-
-/* Transition tables */
-uint16_t epose_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposs_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposm_ttable[NMOVES][factorial12/factorial8];
-uint16_t eofb_ttable[NMOVES][pow2to11];
-uint16_t eorl_ttable[NMOVES][pow2to11];
-uint16_t eoud_ttable[NMOVES][pow2to11];
-uint16_t cp_ttable[NMOVES][factorial8];
-uint16_t coud_ttable[NMOVES][pow3to7];
-uint16_t cofb_ttable[NMOVES][pow3to7];
-uint16_t corl_ttable[NMOVES][pow3to7];
-uint16_t cpos_ttable[NMOVES][factorial6];
-
-bool commute[NMOVES][NMOVES];
-bool possible_next[NMOVES][NMOVES][NMOVES];
-Move inverse[NMOVES];
-NissMove rotation_algs[24][3] = {
- { { .m = NULLMOVE }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = x2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y3 }, { .m = NULLMOVE } },
-};
-
-char move_string[NMOVES][5] =
- { "-",
- "U", "U2", "U\'", "D", "D2", "D\'", "R", "R2", "R\'",
- "L", "L2", "L\'", "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'", "Rw", "Rw2", "Rw\'",
- "Lw", "Lw2", "Lw\'", "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'", "S", "S2", "S\'", "E", "E2", "E\'",
- "x", "x2", "x\'", "y", "y2", "y\'", "z", "z2", "z\'" };
-
-/* For each type of pieces only the effects of U, x and y are described */
-int edge_cycle[NMOVES][12] =
- { [U] = {UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR},
- [x] = {DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR},
- [y] = {UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL} };
-int eofb_flipped[NMOVES][12] =
- { [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eorl_flipped[NMOVES][12] =
- { [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 } };
-int eoud_flipped[NMOVES][12] =
- { [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-int corner_cycle[NMOVES][8] =
- { [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL} };
-int coud_flipped[NMOVES][8] =
- { [x] = {[UFR]=2,[UBR]=1,[DBR]=2,[DFR]=1,[UFL]=1,[UBL]=2,[DBL]=1,[DFL]=2} };
-int corl_flipped[NMOVES][8] =
- { [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {[UFR]=1,[UBR]=2,[UBL]=1,[UFL]=2,[DFR]=2,[DBR]=1,[DBL]=2,[DFL]=1} };
-int cofb_flipped[NMOVES][8] =
- { [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {[UFR]=1,[UBR]=2,[DFR]=2,[DBR]=1,[UBL]=1,[UFL]=2,[DBL]=2,[DFL]=1},
- [y] = {[UFR]=2,[UBR]=1,[UBL]=2,[UFL]=1,[DFR]=1,[DBR]=2,[DBL]=1,[DFL]=2} };
-int center_cycle[NMOVES][6] =
- { [x] = {F_center, B_center, R_center, L_center, D_center, U_center},
- [y] = {U_center, D_center, B_center, F_center, R_center, L_center} };
-
-/* Each move is reduced to a combination of U, x and y using this table */
-Move equiv_moves[NMOVES][14] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 },
- [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 },
- [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 },
- [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 },
- [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 },
- [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 },
- [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 },
- [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 },
- [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 },
- [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 },
- [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 },
- [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 },
- [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 },
- [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 },
- [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 },
- [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 },
-
- [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 },
- [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 },
- [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 },
- [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 },
- [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 },
- [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 },
- [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 },
- [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 },
- [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 },
-
- [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* Movesets */
-bool standard_moveset[NMOVES] = {
- [U] = true, [U2] = true, [U3] = true, [D] = true, [D2] = true, [D3] = true,
- [R] = true, [R2] = true, [R3] = true, [L] = true, [L2] = true, [L3] = true,
- [F] = true, [F2] = true, [F3] = true, [B] = true, [B2] = true, [B3] = true,
-};
-
-bool is_solved_up_to_reorient(Cube cube) {
- for (int i = 0; i < 25; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube)))
- return true;
- return false;
-}
-
-Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f) {
- return move_via_arrays((CubeArray)
- { edge_cycle[m], eofb_flipped[m], eorl_flipped[m], eoud_flipped[m],
- corner_cycle[m], coud_flipped[m], corl_flipped[m], cofb_flipped[m],
- center_cycle[m] }, cube, f);
-}
-
-int len(NissMove *alg) {
- int i;
- for (i = 0; alg[i].m != NULLMOVE; i++);
- return i;
-}
-
-int copy_alg(NissMove *src, NissMove *dest) {
- int i;
- for (i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
- dest[i].m = NULLMOVE;
- return i;
-}
-
-int invert_alg(NissMove *src, NissMove *dest) {
- int n = len(src);
- for (int i = 0; i < n; i++)
- dest[n-i-1] = (NissMove){.m=inverse[src[i].m], .inverse=src[i].inverse};
- dest[n].m = NULLMOVE;
- return n;
-}
-
-int concat(NissMove *src1, NissMove *src2, NissMove *dest) {
- int n1 = len(src1), n2 = len(src2);
- copy_alg(src1, dest);
- copy_alg(src2, dest+n1);
- return n1+n2;
-}
-
-/* TODO: all strings start with space?? */
-void print_alg(NissMove *alg) {
- bool niss = false;
- for (int i = 0; alg[i].m != NULLMOVE; i++) {
- char *fill = !niss && alg[i].inverse ? " (" :
- (niss && !alg[i].inverse ? ") " : " ");
- printf("%s%s", fill, move_string[alg[i].m]);
- niss = alg[i].inverse;
- }
- printf("%s\n", niss ? ")" : "");
-}
-
-int read_moves(char *str, NissMove *alg, int n) {
- bool niss = false;
- int c = 0;
-
- for (int i = 0; str[i] && c < n; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' || str[i] == ')') {
- if ((niss && str[i] == '(') || (!niss && str[i] == ')'))
- return -1;
- niss = !niss;
- continue;
- }
-
- alg[c].inverse = niss; alg[c].m = NULLMOVE;
- for (Move j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- alg[c].m = j;
- if (alg[c].m <= B && str[i+1]=='w') { alg[c].m += Uw - U; i++; }
- if (str[i+1]=='2') { alg[c].m += 1; i++; }
- else if (str[i+1]=='\'' || str[i+1]=='3') { alg[c].m += 2; i++; }
- c++;
- break;
- }
- }
- }
-
- alg[c].m = NULLMOVE;
- return c;
-}
-
-/* TODO: rewrite cleanup(). Idea:
- 1. split alg in normal + inverse part, rewriting each with equiv_moves
- 2. shift rotations to the end while transforming all moves in between
- ARGH! this uses transformation! One more reason to merge everything in
- one file.
- 3. cancellations
-*/
-
-bool read_ttables_file() {
- FILE *ttf;
- long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6 };
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NMOVES; m++) {
- r = r && fread(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fread(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fread(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fread(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fread(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fread(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5];
- r = r && fread(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fread(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fread(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fread(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9];
- r = r && fread(cpos_ttable[m], sizeof(uint16_t), me[10], ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-bool write_ttables_file() {
- FILE *ttf;
- long unsigned int me[11] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6 };
- if ((ttf = fopen("ttables", "wb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_ttable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fwrite(eposs_ttable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fwrite(eposm_ttable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fwrite(eofb_ttable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fwrite(eorl_ttable[m], sizeof(uint16_t), me[4], ttf) == me[4];
- r = r && fwrite(eoud_ttable[m], sizeof(uint16_t), me[5], ttf) == me[5];
- r = r && fwrite(cp_ttable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fwrite(coud_ttable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fwrite(corl_ttable[m], sizeof(uint16_t), me[8], ttf) == me[8];
- r = r && fwrite(cofb_ttable[m], sizeof(uint16_t), me[9], ttf) == me[9];
- r = r && fwrite(cpos_ttable[m], sizeof(uint16_t), me[10],ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-void init_ttables(bool read, bool write) {
- /* Generate all move cycles and flips; I do this regardless */
- for (int i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- Cube c = {0};
- for (int j = 0; equiv_moves[i][j]; j++)
- c = apply_move_cubearray(equiv_moves[i][j], c, pf_all);
-
- CubeArray arrs = {
- edge_cycle[i], eofb_flipped[i], eorl_flipped[i], eoud_flipped[i],
- corner_cycle[i], coud_flipped[i], corl_flipped[i], cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read)
- if (read_ttables_file())
- return;
-
- /* Initialize transition tables */
- for (int m = 0; m < NMOVES; m++) {
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- epose_ttable[m][i] = apply_move_cubearray(m,(Cube){.epose=i},pf_e).epose;
- eposs_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposs=i},pf_s).eposs;
- eposm_ttable[m][i] = apply_move_cubearray(m,(Cube){.eposm=i},pf_m).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- eofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.eofb=i},pf_eo).eofb;
- eorl_ttable[m][i] = apply_move_cubearray(m,(Cube){.eorl=i},pf_eo).eorl;
- eoud_ttable[m][i] = apply_move_cubearray(m,(Cube){.eoud=i},pf_eo).eoud;
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- coud_ttable[m][i] = apply_move_cubearray(m,(Cube){.coud=i},pf_co).coud;
- corl_ttable[m][i] = apply_move_cubearray(m,(Cube){.corl=i},pf_co).corl;
- cofb_ttable[m][i] = apply_move_cubearray(m,(Cube){.cofb=i},pf_co).cofb;
- }
- for (uint16_t i = 0; i < factorial8; i++)
- cp_ttable[m][i] = apply_move_cubearray(m,(Cube){.cp=i},pf_cp).cp;
- for (uint16_t i = 0; i < factorial6; i++)
- cpos_ttable[m][i] = apply_move_cubearray(m,(Cube){.cpos=i},pf_cpos).cpos;
- }
-
- if (write)
- if (!write_ttables_file())
- printf("Error in writing ttables: file not writable\n");
-}
-
-Cube move_cube(Move m, Cube cube) {
- Cube moved = {0};
-
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.cp = cp_ttable[m][cube.cp];
- moved.cpos = cpos_ttable[m][cube.cpos];
-
- return moved;
-}
-
-Cube apply_alg_filtered(NissMove *alg, Cube cube, PieceFilter f) {
- Cube ret = {0};
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
-
- ret = compose_filtered(cube, inverse_cube(ret), f);
-
- for (int i = 0; alg[i].m != NULLMOVE; i++)
- if (!alg[i].inverse)
- ret = move_cube(alg[i].m, ret);
- return ret;
-}
-
-Cube apply_alg(NissMove *alg, Cube cube) {
- return apply_alg_filtered(alg, cube, pf_all);
-}
-
-void init_aux_tables() {
- /* Commute */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- commute[i][j] = equal(move_cube(i, move_cube(j, (Cube){0})),
- move_cube(j, move_cube(i, (Cube){0})));
-
- /* Possible next (if the sequence i j k is valid) */
- for (int i = 0; i < NMOVES; i++)
- for (int j = 0; j < NMOVES; j++)
- for (int k = 0; k < NMOVES; k++)
- possible_next[i][j][k] =
- (j == 0) ||
- (j != 0 && (j-(j-1)%3) != (k-(k-1)%3) &&
- !(i != 0 && commute[i][j] && (i-(i-1)%3) == (k-(k-1)%3)));
-
- /* Inverse */
- for (int i = 0; i < NMOVES; i++)
- inverse[i] = i == NULLMOVE ? NULLMOVE : i + 2 - 2*((i-1)%3);
-
-}
-
diff --git a/old/2021-05-26-before-restyle/moves.h b/old/2021-05-26-before-restyle/moves.h
@@ -1,51 +0,0 @@
-#ifndef MOVES_H
-#define MOVES_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "utils.h"
-
-#define NMOVES (z3+1)
-
-typedef enum {
- NULLMOVE,
- U, U2, U3, D, D2, D3, R, R2, R3, L, L2, L3, F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3, Rw, Rw2, Rw3,
- Lw, Lw2, Lw3, Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3, S, S2, S3, E, E2, E3,
- x, x2, x3, y, y2, y3, z, z2, z3,
-} Move;
-
-/* An alg is an array of "NissMoves", which can be on normal or on inverse. */
-typedef struct { bool inverse; Move m; } NissMove;
-
-/* Movesets */
-extern bool standard_moveset[NMOVES];
-
-extern bool commute[NMOVES][NMOVES];
-extern bool possible_next[NMOVES][NMOVES][NMOVES];
-extern Move inverse[NMOVES];
-extern NissMove rotation_algs[24][3]; /* Same order as transformations */
-
-int len(NissMove *alg);
-int copy_alg(NissMove *src, NissMove *dest); /*return number of moves copied */
-int invert_alg(NissMove *src, NissMove *dest);
-int concat(NissMove *src1, NissMove *src2, NissMove *dest);
-void print_alg(NissMove *alg);
-int read_moves(char *str, NissMove *alg, int n); /* reads at most n moves */
-void cleanup(NissMove *src, int n); /* rewrites using basic moves, at most n */
-
-bool is_solved_up_to_reorient(Cube cube);
-Cube move_cube(Move m, Cube cube);
-Cube apply_alg(NissMove *alg, Cube cube);
-Cube apply_alg_filtered(NissMove *alg, Cube cube, PieceFilter f);
-
-/* Merge the following two?
- always in this order */
-void init_ttables(bool read, bool write);
-void init_aux_tables();
-
-
-#endif
diff --git a/old/2021-05-26-before-restyle/solve.c b/old/2021-05-26-before-restyle/solve.c
@@ -1,180 +0,0 @@
-#include "solve.h"
-
-/* Data for creating a pruning table:
- - compressed: if set to true, each entry occupies only 4 bits, but values
- larger than 15 cannot be stored.
- - available[] is the list of availabel moves, as above.
- - *ptable is the actual table to fill.
- - n is the number of states (size of ptable).
- - index must "linearize" the cube, i.e. return its index in ptable.
- - fname is the name of the file where to store the table */
-typedef struct {
- bool compressed, *available;
- int max_moves;
- uint8_t *ptable;
- uint64_t n;
- uint64_t (*index)(Cube);
- char *fname;
-} PruneData;
-
-/* TODO: comment this */
-typedef struct {
- bool niss;
- int m, d;
- uint64_t *n;
- Move last1, last2;
-} DfsData;
-
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd);
-void init_ptable(PruneData *pd, bool read, bool write);
-
-/* Search solutions of lenght exactly d */
-void solve_dfs(Cube cube, SolveData *sd, DfsData dd) {
- if (*dd.n >= sd->max_solutions ||
- ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d))
- return;
-
- (sd->solutions[*dd.n][dd.m]).inverse = dd.niss;
- (sd->solutions[*dd.n][dd.m]).m = NULLMOVE;
-
- if (!sd->f(cube)) { /* Solved */
- if (dd.m == dd.d) {
- (*dd.n)++;
- if (*dd.n < sd->max_solutions)
- copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]);
- }
- return;
- }
-
- for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) {
- Move move = sd->sorted_moves[i];
- if (possible_next[dd.last2][dd.last1][move]) {
- sd->solutions[*dd.n][dd.m].inverse = dd.niss;
- sd->solutions[*dd.n][dd.m].m = move;
- DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = move, .last2 = dd.last1 };
- solve_dfs(move_cube(move, cube), sd, nn);
- }
- }
-
- if (sd->can_niss && !dd.niss &&
- (!dd.m || (dd.m && sd->f(move_cube(dd.last1, (Cube){0}))))) {
- DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n };
- solve_dfs(inverse_cube(cube), sd, nn);
- }
-}
-
-/* Iterative deepening depth-first search: for i running from the minimum
- to the maximum number of moves allowed, looks for solutions of length i. */
-int solve(Cube cube, SolveData *sd) {
- if (sd->precondition != NULL && !sd->precondition(cube))
- return -1;
-
- /* If not given, generate sorted list of moves */
- if (sd->sorted_moves[0] == NULLMOVE) {
- int a[NMOVES], b[NMOVES], ia = 0, ib = 0;
- for (int i = 0; i < NMOVES; i++) {
- if (sd->available[i]) {
- if (sd->f(move_cube(i, (Cube){0})))
- a[ia++] = i;
- else
- b[ib++] = i;
- }
- }
- intarrcopy(a, (int *)sd->sorted_moves, ia);
- intarrcopy(b, (int *)sd->sorted_moves+ia, ib);
- sd->sorted_moves[ia+ib] = NULLMOVE;
- }
-
- sd->max_solutions = min(sd->max_solutions, MAXS);
- /*TODO
- Cube rotated = apply_alg(sd->pre_rotation, (Cube){0});
- cube = apply_alg(inverse_cube(rotated), compose(cube, rotated));
- */
-
- uint64_t ret = 0;
- for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) {
- DfsData dd = { .d = i, .n = &ret };
- solve_dfs(cube, sd, dd);
- }
-
- /* TODO: transform solutions with inverse of pre_rotation */
- /*
- for (uint64_t i = 0; i < ret; i++) {
- if (sd->cleanup)
- cleanup(sd->solutions[i], sd->max_moves*3);
- }*/
-
- return ret;
-}
-
-void prune_dfs(Cube cube, PruneData *pd, DfsData dd) {
- uint64_t ind = pd->index(cube);
- if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m)
- return;
- if (dd.m == dd.d) {
- if (ind && !pd->ptable[ind]) {
- pd->ptable[ind] = dd.m;
- (*dd.n)++;
- }
- return;
- }
-
- for (int i = 0; i < NMOVES; i++) {
- if (dd.m<20)
- if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) {
- DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n,
- .last1 = i, .last2 = dd.last1 };
- prune_dfs(move_cube(i, cube), pd, nn);
- }
- }
-}
-
-void init_ptable(PruneData *pd, bool read, bool write) {
- if (read) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "rb")) != NULL) {
- uint64_t r = fread(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- if (r == pd->n) return;
- }
- }
-
- /* TODO: for now it behaves always as if copressed = false */
- for (uint64_t i = 0; i < pd->n; i++)
- pd->ptable[i] = 0;
-
- uint64_t s = 1;
- for (int i = 1; i < pd->max_moves && s < pd->n; i++) {
- DfsData dd = { .d = i, .n = &s };
- prune_dfs((Cube){0}, pd, dd);
- }
-
- if (write) {
- FILE *ptf;
- if ((ptf = fopen(pd->fname, "wb")) != NULL) {
- fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf);
- fclose(ptf);
- return;
- }
- }
-}
-
-/* Solving steps (and indexing functions) */
-
-uint64_t index_eofb(Cube cube) { return cube.eofb; }
-int f_eofb(Cube cube) {
- static bool initialized_ptable;
- static uint8_t pt_eofb[pow2to11];
- if (!initialized_ptable) {
- PruneData pd = {
- .compressed = false, .available = standard_moveset, .max_moves = 13,
- .ptable = pt_eofb, .n = pow2to11, .index = index_eofb,
- .fname = "ptable_eofb"
- };
- init_ptable(&pd, false, true);
- initialized_ptable = true;
- }
- return cube.eofb ? pt_eofb[cube.eofb] : 0;
-}
-
diff --git a/old/2021-05-26-before-restyle/solve.h b/old/2021-05-26-before-restyle/solve.h
@@ -1,59 +0,0 @@
-#ifndef SOLVE_H
-#define SOLVE_H
-
-#include <stdlib.h>
-#include "cube.h"
-#include "moves.h"
-#include "transformations.h"
-
-/* Maximum number of moves per solution and of solutions */
-#define MAXM 30
-#define MAXS 999
-
-/* Data for solving a step:
- - can_niss is true niss can be used, false otherwise.
- - optimal_only if true, dynamically updates max_moves so non-optimal
- solutions are discarded.
- - cleanup determines whether the cleaunup() function should be used on
- the found solutions before returning.
- - available[m] is true if the move m can be used, false otherwise.
- (Rename to moveset[]?)
- - min_moves and max_moves are the minimum and maximum number of moves that
- can be used.
- - max_solution is the maximum number of solutions that can be returned.
- - precondition can be used to check wheter the step can actually be applied
- to the cube. If it returns false, solve() stops immediately returning -1.
- - f must return 0 if and only if the step is solve, otherwise it must return
- a lower bound for the number of moves required (without niss).
- - sorted_moves[] can be used to specify in which order moves are tried
- by the solving algorithm (for example if one wants to always try F' before
- F). If sorted_moves[0] == NULLMOVE, the list is generated automatically.
- It is advised to list first all the moves that actually influence the
- solved state of the step (this is the default choice). This is in order to
- avoid cases like B2 F for EO and to NISS only when it makes sense.
- - start_moves [Currently unused, REMOVE]
- are the moves that will be used as first moves of all
- solutions. For example giving R' U' F (F' U R) will generate FMC scrambles
- and y (y) will solve the step on another axis.
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wrt a different orientation
- - pre_rotation are the rotations to apply before the scamble to solve
- the step wth respect to a different orientation.
- TODO: cange name
- - solutions[][] is the array where to store the found solutions. */
-typedef struct {
- bool can_niss, optimal_only, cleanup, *available;
- int min_moves, max_moves, max_solutions;
- int (*f)(Cube);
- bool (*precondition)(Cube);
- Move sorted_moves[NMOVES];
- Transformation pre_rotation;
- NissMove solutions[MAXS][MAXM];
-} SolveData;
-
-int solve(Cube cube, SolveData *data); /* Returns the number of solutions. */
-
-/* Steps */
-int f_eofb(Cube cube);
-
-#endif
diff --git a/old/2021-05-26-before-restyle/transformations.c b/old/2021-05-26-before-restyle/transformations.c
@@ -1,200 +0,0 @@
-#include "transformations.h"
-
-int edge_slice(int e); /* Return slice (e=0, s=1, m=2) to which e belongs */
-Cube rotate_via_compose(Transformation r, Cube c, PieceFilter f);
-bool read_rtables_file();
-bool write_rtables_file();
-
-/* Values mod 3 to determine from which side to take the state to convert */
-int epose_source[NTRANS]; /* 0 = epose, 1 = eposs, 2 = eposm */
-int eposs_source[NTRANS];
-int eposm_source[NTRANS];
-int eofb_source[NTRANS]; /* 0 = eoud, 1 = eorl, 2 = eofb */
-int eorl_source[NTRANS];
-int eoud_source[NTRANS];
-int coud_source[NTRANS]; /* 0 = coud, 1 = corl, 2 = cofb */
-int cofb_source[NTRANS];
-int corl_source[NTRANS];
-
-/* Transition tables for rotations (n+1 is mirror) */
-uint16_t epose_rtable[NTRANS][factorial12/factorial8];
-uint16_t eposs_rtable[NTRANS][factorial12/factorial8];
-uint16_t eposm_rtable[NTRANS][factorial12/factorial8];
-uint16_t eo_rtable[NTRANS][pow2to11];
-uint16_t cp_rtable[NTRANS][factorial8];
-uint16_t co_rtable[NTRANS][pow3to7];
-uint16_t cpos_rtable[NTRANS][factorial6];
-
-/* Same for moves */
-uint16_t moves_rtable[NTRANS][NMOVES];
-
-NissMove rotation_niss[NTRANS][6];
-
-int edge_slice(int e) {
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
- return 2;
-}
-
-Cube rotate_via_compose(Transformation r, Cube c, PieceFilter f) {
- if (r != mirror) {
- return apply_alg_filtered(rotation_niss[r], c, f);
- } else {
- static int zero12[12] = {0,0,0,0,0,0,0,0,0,0,0,0},
- zero8[12] = {0,0,0,0,0,0,0,0},
- mirror_ep[12] = {UF,UR,UB,UL,DF,DR,DB,DL,FL,FR,BR,BL},
- mirror_cp[8] = {UFL, UFR, UBR, UBL, DFL, DFR, DBR, DBL},
- mirror_cpos[6] =
- {U_center,D_center,L_center,R_center,F_center,B_center};
- return move_via_arrays((CubeArray){
- .ep = mirror_ep, .eofb = zero12, .eorl = zero12, .eoud = zero12,
- .cp = mirror_cp, .coud = zero8, .corl = zero8, .cofb = zero8,
- .cpos = mirror_cpos}, c, f);
- }
-}
-
-bool read_rtables_file() {
- FILE *ttf;
- long unsigned int me[12] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6, NMOVES };
- if ((ttf = fopen("rtables", "rb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NTRANS; m++) {
- r = r && fread(epose_rtable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fread(eposs_rtable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fread(eposm_rtable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fread(eo_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fread(cp_rtable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fread(co_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fread(cpos_rtable[m], sizeof(uint16_t), me[10], ttf) == me[10];
- r = r && fread(moves_rtable[m], sizeof(uint16_t), me[11], ttf) == me[11];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-bool write_rtables_file() {
- FILE *ttf;
- long unsigned int me[12] = { factorial12/factorial8, factorial12/factorial8,
- factorial12/factorial8, pow2to11, pow2to11, pow2to11,
- factorial8, pow3to7, pow3to7, pow3to7, factorial6, NMOVES };
- if ((ttf = fopen("rtables", "wb")) != NULL) {
- bool r = true;
- for (int m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_rtable[m], sizeof(uint16_t), me[0], ttf) == me[0];
- r = r && fwrite(eposs_rtable[m], sizeof(uint16_t), me[1], ttf) == me[1];
- r = r && fwrite(eposm_rtable[m], sizeof(uint16_t), me[2], ttf) == me[2];
- r = r && fwrite(eo_rtable[m], sizeof(uint16_t), me[3], ttf) == me[3];
- r = r && fwrite(cp_rtable[m], sizeof(uint16_t), me[6], ttf) == me[6];
- r = r && fwrite(co_rtable[m], sizeof(uint16_t), me[7], ttf) == me[7];
- r = r && fwrite(cpos_rtable[m], sizeof(uint16_t), me[10],ttf) == me[10];
- r = r && fwrite(moves_rtable[m], sizeof(uint16_t), me[11],ttf) == me[11];
- }
- fclose(ttf);
- return r;
- } else return false;
-}
-
-void init_transformations(bool read, bool write) {
- /* Compute sources */
- for (int i = 0; i < NTRANS; i++) {
- Cube cube = {0};
- if (i != mirror)
- cube = apply_alg(rotation_algs[i], (Cube){0});
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- /*TODO: maybe move down*/
- /* Compute rotation_niss array, necessary for rotate_via_compose */
- for (int r = 0; r != mirror; r++) {
- concat(rotation_algs[r], rotation_algs[r], rotation_niss[r]);
- for (int i = len(rotation_algs[r]); rotation_niss[r][i].m != NULLMOVE; i++)
- rotation_niss[r][i].inverse = true;
- }
-
- /* If I can read tables from file, I stop here */
- if (read)
- if (read_rtables_file())
- return;
-
- /* Initialize tables */
- for (int m = 0; m < NTRANS; m++) {
- int eparr[12] = {0,0,0,0,0,0,0,0,0,0,0,0}, cparr[8] = {0,0,0,0,0,0,0,0};
- CubeArray epcp = { .ep = eparr, .cp = cparr };
- cube_to_arrays(apply_alg(rotation_algs[m], (Cube){0}), &epcp,
- (PieceFilter){.epose=true,.eposs=true,.eposm=true,.cp=true});
- for (uint16_t i = 0; i < factorial12/factorial8; i++) {
- Cube c[3] = { admissible_ep((Cube){ .epose = i}, pf_e),
- admissible_ep((Cube){ .eposs = i}, pf_s),
- admissible_ep((Cube){ .eposm = i}, pf_m) };
- epose_rtable[m][i]=rotate_via_compose(m,c[epose_source[m]],pf_ep).epose;
- eposs_rtable[m][i]=rotate_via_compose(m,c[eposs_source[m]],pf_ep).eposs;
- eposm_rtable[m][i]=rotate_via_compose(m,c[eposm_source[m]],pf_ep).eposm;
- }
- for (uint16_t i = 0; i < pow2to11; i++ ) {
- int eoarr[12];
- int_to_sum_zero_array(i, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_rtable[m][i] = digit_array_to_int(eoarr, 11, 2);
- }
- for (uint16_t i = 0; i < pow3to7; i++) {
- int coarr[12];
- int_to_sum_zero_array(i, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_rtable[m][i] = digit_array_to_int(coarr, 7, 3);
- }
- for (uint16_t i = 0; i < factorial8; i++)
- cp_rtable[m][i] = rotate_via_compose(m, (Cube){.cp=i}, pf_cp).cp;
- for (uint16_t i = 0; i < factorial6; i++)
- cpos_rtable[m][i] = rotate_via_compose(m, (Cube){.cpos=i}, pf_cpos).cpos;
- for (Move i = 0; i < NMOVES; i++) {
- Cube aux = transform_cube(m, move_cube(i, (Cube){0}));
- for (Move move = 0; move < NMOVES; move++)
- if (is_solved(move_cube(inverse[move], aux)))
- moves_rtable[m][i] = move;
- }
- }
-
- if (write)
- if (!write_rtables_file())
- printf("Error in writing rtables: file not writable\n");
-}
-
-Cube transform_cube(Transformation t, Cube cube) {
- Cube transformed = {0};
-
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm },
- aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb },
- aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- transformed.epose = epose_rtable[t][aux_epos[epose_source[t]]];
- transformed.eposs = eposs_rtable[t][aux_epos[eposs_source[t]]];
- transformed.eposm = eposm_rtable[t][aux_epos[eposm_source[t]]];
- transformed.eofb = eo_rtable[t][aux_eo[eofb_source[t]]];
- transformed.eorl = eo_rtable[t][aux_eo[eorl_source[t]]];
- transformed.eoud = eo_rtable[t][aux_eo[eoud_source[t]]];
- transformed.coud = co_rtable[t][aux_co[coud_source[t]]];
- transformed.corl = co_rtable[t][aux_co[corl_source[t]]];
- transformed.cofb = co_rtable[t][aux_co[cofb_source[t]]];
- transformed.cp = cp_rtable[t][cube.cp];
- transformed.cpos = cpos_rtable[t][cube.cpos];
-
- return transformed;
-}
-
-void transform_alg(Transformation t, NissMove *alg) {
- for (int i = 0; alg[i].m; i++)
- alg[i].m = moves_rtable[t][alg[i].m];
-}
diff --git a/old/2021-05-26-before-restyle/transformations.h b/old/2021-05-26-before-restyle/transformations.h
@@ -1,34 +0,0 @@
-#ifndef TRANSFORMATIONS_H
-#define TRANSFORMATIONS_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "cube.h"
-#include "moves.h"
-#include "utils.h"
-
-#define NTRANS (mirror+1)
-
-/* Letters indicate top and front centers
- * Mirror is wrt rl
- * Lowercase letter to distinguish from pieces */
-
-typedef enum {
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror,
-} Transformation;
-
-void print_transformation(Transformation t);
-
-Cube transform_cube(Transformation t, Cube cube);
-void transform_alg(Transformation t, NissMove *alg); /* Applied in-place */
-
-void init_transformations(bool read, bool write);
-
-#endif
diff --git a/old/2021-05-26-before-restyle/utils.c b/old/2021-05-26-before-restyle/utils.c
@@ -1,197 +0,0 @@
-#include "utils.h"
-
-void swap(int *a, int *b) {
- int aux = *a;
- *a = *b;
- *b = aux;
-}
-
-void intarrcopy(int *src, int *dst, int n) {
- for (int i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-int sum(int *a, int n) {
- int ret = 0;
- for (int i = 0; i < n; i++)
- ret += a[i];
- return ret;
-}
-
-bool is_perm(int *a, int n) {
- int aux[n]; for (int i = 0; i < n; i++) aux[i] = 0;
- for (int i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
- for (int i = 0; i < n; i++)
- if (!aux[i])
- return false;
- return true;
-}
-
-bool is_subset(int *a, int n, int k) {
- int sum = 0;
- for (int i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
- return sum == k;
-}
-
-int powint(int a, int b) {
- return 0;
- if (b == 0 || a == 1)
- return 1;
- if (a == 0)
- return 0;
- if (b < 0)
- return 0; /* Immediate truncate (integer part is 0) */
- if (b % 2) {
- return a * powint(a, b-1);
- } else {
- int x = powint(a, b/2);
- return x*x;
- }
-}
-
-int factorial(int n) {
- if (n < 0)
- return 0;
- int ret = 1;
- for (int i = 1; i <= n; i++)
- ret *= i;
- return ret;
-}
-
-int binomial(int n, int k) {
- if (n < 0 || k < 0 || k > n)
- return 0;
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-void int_to_digit_array(int a, int b, int n, int *r) {
- if (b <= 1)
- for (int i = 0; i < n; i++)
- r[i] = 0;
- else
- for (int i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-int digit_array_to_int(int *a, int n, int b) {
- int ret = 0, p = 1;
- for (int i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
- return ret;
-}
-
-int perm_to_index(int *a, int n) {
- if (!is_perm(a, n))
- return factorial(n); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- int c = 0;
- for (int j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
- return ret;
-}
-
-void index_to_perm(int p, int n, int *r) {
- if (p < 0 || p >= factorial(n)) /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- int a[n]; for (int j = 0; j < n; j++) a[j] = 0; /* picked elements */
- for (int i = 0; i < n; i++) {
- int c = 0, j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-}
-
-int perm_sign(int *a, int n) {
- if (!is_perm(a,n))
- return false;
- int ret = 0;
- for (int i = 0; i < n; i++)
- for (int j = i+1; j < n; j++)
- ret += (a[i]>a[j]) ? 1 : 0;
- return ret % 2;
-}
-
-int subset_to_index(int *a, int n, int k) {
- /* TODO: better checks */
- if (!is_subset(a, n, k))
- return binomial(n, k); /* Error */
- int ret = 0;
- for (int i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- /*ret += factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- ret += binomial(n-i-1, k);
- k--;
- }
- }
- return ret;
-}
-
-void index_to_subset(int s, int n, int k, int *r) {
- if (s < 0 || s >= binomial(n, k)) { /* Error */
- for (int i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
- for (int i = 0; i < n; i++) {
- if (k == n-i) {
- for (int j = i; j < n; j++)
- r[j] = 1;
- return;
- }
- if (k == 0) {
- for (int j = i; j < n; j++)
- r[j] = 0;
- return;
- }
- /*int v = factorial(n-i-1) / (factorial(k) * factorial(n-i-1-k));*/
- int v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-void int_to_sum_zero_array(int x, int b, int n, int *a) {
- if (b <= 1) {
- for (int i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- int s = 0;
- for (int i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-void apply_permutation(int *perm, int *set, int n) {
- if (!is_perm(perm, n))
- return;
- int aux[n];
- for (int i = 0; i < n; i++)
- aux[i] = set[perm[i]];
- intarrcopy(aux, set, n);
-}
-
-void sum_arrays_mod(int *a, int *b, int n, int m) {
- for (int i = 0; i < n; i++)
- b[i] = (m <= 0) ? 0 : (a[i] + b[i]) % m;
-}
diff --git a/old/2021-05-26-before-restyle/utils.h b/old/2021-05-26-before-restyle/utils.h
@@ -1,70 +0,0 @@
-/* General utility functions */
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Some useful constants */
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-/* Generic utility functions */
-void swap(int *a, int *b);
-void intarrcopy(int *src, int *dst, int n);
-int sum(int *a, int n);
-bool is_perm(int *a, int n);
-bool is_perm(int *a, int n);
-
-
-/* Standard mathematical functions */
-int powint(int a, int b);
-int factorial(int n);
-int binomial(int n, int k);
-
-/* Converts the integer a to its representation in base b (first n digits
- * only) and saves the result in r. */
-void int_to_digit_array(int a, int b, int n, int *r);
-int digit_array_to_int(int *a, int n, int b);
-
-/* Converts the first n-1 digits of a number to an array a of digits in base b;
- * then adds one element to the array, so that the sum of the elements of a is
- * zero modulo b.
- * This is used for determing the edge orientation from an 11-bits integer or
- * the corner orientation from a 7-trits integer. */
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-
-/* Converts a permutation on [0..(n-1)] into the integer i which is the index
- * of the permutation in the sorted list of all n! such permutations. */
-int perm_to_index(int *a, int n);
-void index_to_perm(int p, int n, int *r);
-
-/* Determine the sign of a permutation */
-int perm_sign(int a[], int n);
-
-/* Converts a k-element subset of a set from an array of n elements, of which k
- * are 1 and n-k are 0, to its index in the sorted list of all such subsets. */
-int subset_to_index(int *a, int n, int k);
-void index_to_subset(int s, int n, int k, int *r);
-
-int ordered_subset_to_index(int *a, int n, int k);
-void index_to_ordered_subset(int s, int n, int k, int *r);
-
-void apply_permutation(int *perm, int *set, int n);
-
-/* b[i] = (a[i]+b[i])%m for i=1,...,n */
-void sum_arrays_mod(int *a, int *b, int n, int m);
-
-#endif
diff --git a/old/2021-06-02-cleanedup/cube.c b/old/2021-06-02-cleanedup/cube.c
@@ -1,2010 +0,0 @@
-#include "cube.h"
-
-/* Constants and macros *****************************************************/
-
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-#define BASEALGLEN 50
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Local types ***************************************************************/
-
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-
-struct
-cubearray
-{
- int *ep;
- int *eofb;
- int *eorl;
- int *eoud;
- int *cp;
- int *coud;
- int *corl;
- int *cofb;
- int *cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- bool niss;
- Move last1;
- Move last2;
- AlgList *sols;
- Alg current_alg;
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static CubeArray * alloc_cubearray(CubeArray *arr, PieceFilter f);
-static void append_alg(AlgList *l, Alg alg);
-static void append_move(Alg alg, NissMove m);
-static Cube apply_alg_filtered(Alg alg, Cube cube, PieceFilter f);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static Cube arrays_to_cube(CubeArray arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static uint16_t epos_from_arrays(int *epos, int *ep);
-static int factorial(int n);
-static void free_alglist(AlgList *l);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-static void init_moves();
-static void init_trans();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static void intarrcopy(int *src, int *dst, int n);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray arr, Cube c, PieceFilter pf);
-static Move * moveset_to_movelist(bool *moveset, Step step);
-static AlgList * new_alglist();
-static int perm_sign(int a[], int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static bool read_rtables_file();
-static bool read_ttables_file();
-static bool realloc_alg(Alg alg, int n);
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static void solve_dfs(Cube c, Step s, SolveOptions opts, DfsData dd);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_rtables_file();
-static bool write_ttables_file();
-
-/* Aux tables ****************************************************************/
-
-bool commute[NMOVES][NMOVES];
-bool possible_next[NMOVES][NMOVES][NMOVES];
-Move inverse_move_aux[NMOVES];
-Trans inverse_trans_aux[NTRANS];
-
-/* Some utility constants ****************************************************/
-
-static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
-static int epe_solved[4] = { FR, FL, BL, BR };
-static int eps_solved[4] = { UL, UR, DL, DR };
-static int epm_solved[4] = { UF, UB, DF, DB };
-
-static int ep_mirror[12] = { UF, UR, UB, UL, DF, DR, DB, DL, FL, FR, BR, BL };
-static int cp_mirror[8] = { UFL, UFR, UBR, UBL, DFL, DFR, DBR, DBL };
-static int cpos_mirror[6] = {
- U_center, D_center,
- L_center, R_center,
- F_center, B_center
-};
-
-static long unsigned int me[12] = {
- factorial12/factorial8,
- factorial12/factorial8,
- factorial12/factorial8,
- pow2to11,
- pow2to11,
- pow2to11,
- factorial8,
- pow3to7,
- pow3to7,
- pow3to7,
- factorial6,
- NMOVES
-};
-
-static PieceFilter pf_all = {
- true, true, true, true, true, true, true, true, true, true, true
-};
-static PieceFilter pf_epcp = {
- .epose = true, .eposs = true, .eposm = true, .cp = true
-};
-static PieceFilter pf_cpos = { .cpos = true };
-static PieceFilter pf_cp = { .cp = true };
-static PieceFilter pf_ep = { .epose = true, .eposs = true, .eposm = true };
-static PieceFilter pf_e = { .epose = true };
-static PieceFilter pf_s = { .eposs = true };
-static PieceFilter pf_m = { .eposm = true };
-static PieceFilter pf_eo = { .eofb = true, .eorl = true, .eoud = true };
-static PieceFilter pf_co = { .coud = true, .cofb = true, .corl = true };
-
-/* Strings for moves and pieces **********************************************/
-
-char move_string[NMOVES][5] = {
- "-",
- "U", "U2", "U\'", "D", "D2", "D\'",
- "R", "R2", "R\'", "L", "L2", "L\'",
- "F", "F2", "F\'", "B", "B2", "B\'",
- "Uw", "Uw2", "Uw\'", "Dw", "Dw2", "Dw\'",
- "Rw", "Rw2", "Rw\'", "Lw", "Lw2", "Lw\'",
- "Fw", "Fw2", "Fw\'", "Bw", "Bw2", "Bw\'",
- "M", "M2", "M\'",
- "S", "S2", "S\'",
- "E", "E2", "E\'",
- "x", "x2", "x\'",
- "y", "y2", "y\'",
- "z", "z2", "z\'"
-};
-char edge_string[12][5] = {
- "UF", "UL", "UB", "UR",
- "DF", "DL", "DB", "DR",
- "FR", "FL", "BL", "BR"
-};
-char corner_string[8][5] = {
- "UFR", "UFL", "UBL", "UBR",
- "DFR", "DFL", "DBL", "DBR"
-};
-char center_string[6][5] = {
- "U", "D",
- "R", "L",
- "F", "B"
-};
-
-/* Transition tables for transformations and moves ***************************/
-
-uint16_t epose_rtable[NTRANS][factorial12/factorial8];
-uint16_t eposs_rtable[NTRANS][factorial12/factorial8];
-uint16_t eposm_rtable[NTRANS][factorial12/factorial8];
-uint16_t eo_rtable[NTRANS][pow2to11];
-uint16_t cp_rtable[NTRANS][factorial8];
-uint16_t co_rtable[NTRANS][pow3to7];
-uint16_t cpos_rtable[NTRANS][factorial6];
-Move moves_rtable[NTRANS][NMOVES];
-
-uint16_t epose_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposs_ttable[NMOVES][factorial12/factorial8];
-uint16_t eposm_ttable[NMOVES][factorial12/factorial8];
-uint16_t eofb_ttable[NMOVES][pow2to11];
-uint16_t eorl_ttable[NMOVES][pow2to11];
-uint16_t eoud_ttable[NMOVES][pow2to11];
-uint16_t cp_ttable[NMOVES][factorial8];
-uint16_t coud_ttable[NMOVES][pow3to7];
-uint16_t cofb_ttable[NMOVES][pow3to7];
-uint16_t corl_ttable[NMOVES][pow3to7];
-uint16_t cpos_ttable[NMOVES][factorial6];
-
-/* Used to compute the full transition tables for moves and transformations **/
-
-int epose_source[NTRANS]; /* 0 = epose, 1 = eposs, 2 = eposm */
-int eposs_source[NTRANS];
-int eposm_source[NTRANS];
-int eofb_source[NTRANS]; /* 0 = eoud, 1 = eorl, 2 = eofb */
-int eorl_source[NTRANS];
-int eoud_source[NTRANS];
-int coud_source[NTRANS]; /* 0 = coud, 1 = corl, 2 = cofb */
-int cofb_source[NTRANS];
-int corl_source[NTRANS];
-
-NissMove rotation_niss[NTRANS][6];
-NissMove rotation_algs[NROTATIONS][3] = {
- { { .m = NULLMOVE }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = x2 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = y3 }, { .m = z2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z3 }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = z }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x }, { .m = y3 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = NULLMOVE }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y2 }, { .m = NULLMOVE } },
- { { .m = x3 }, { .m = y3 }, { .m = NULLMOVE } },
-};
-
-/* For each type of pieces only the effects of U, x and y are described */
-int edge_cycle[NMOVES][12] = {
- [U] = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR },
- [x] = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR },
- [y] = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL }
-};
-int eofb_flipped[NMOVES][12] = {
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
-};
-int eorl_flipped[NMOVES][12] = {
- [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
-};
-int eoud_flipped[NMOVES][12] = {
- [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
-};
-int corner_cycle[NMOVES][8] = {
- [U] = {UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR},
- [x] = {DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR},
- [y] = {UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL}
-};
-int coud_flipped[NMOVES][8] = {
- [x] = {
- [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2,
- [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2
- }
-};
-int corl_flipped[NMOVES][8] = {
- [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {
- [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
- [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
- }
-};
-int cofb_flipped[NMOVES][8] = {
- [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {
- [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
- [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
- },
- [y] = {
- [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1,
- [DFR] = 1, [DBR] = 2, [DBL] = 1, [DFL] = 2
- }
-};
-int center_cycle[NMOVES][6] = {
- [x] = { F_center, B_center, R_center, L_center, D_center, U_center },
- [y] = { U_center, D_center, B_center, F_center, R_center, L_center }
-};
-
-/* Each move is reduced to a combination of U, x and y using this table */
-Move equiv_moves[NMOVES][14] = {
- [U] = { U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U2] = { U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [U3] = { U, U, U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D] = { x, x, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D2] = { x, x, U, U, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [D3] = { x, x, U, U, U, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [R] = { y, x, U, x, x, x, y, y, y, 0, 0, 0, 0, 0 },
- [R2] = { y, x, U, U, x, x, x, y, y, y, 0, 0, 0, 0 },
- [R3] = { y, x, U, U, U, x, x, x, y, y, y, 0, 0, 0 },
- [L] = { y, y, y, x, U, x, x, x, y, 0, 0, 0, 0, 0 },
- [L2] = { y, y, y, x, U, U, x, x, x, y, 0, 0, 0, 0 },
- [L3] = { y, y, y, x, U, U, U, x, x, x, y, 0, 0, 0 },
- [F] = { x, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F2] = { x, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [F3] = { x, U, U, U, x, x, x, 0, 0, 0, 0, 0, 0, 0 },
- [B] = { x, x, x, U, x, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B2] = { x, x, x, U, U, x, 0, 0, 0, 0, 0, 0, 0, 0 },
- [B3] = { x, x, x, U, U, U, x, 0, 0, 0, 0, 0, 0, 0 },
-
- [Uw] = { x, x, U, x, x, y, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Uw2] = { x, x, U, U, x, x, y, y, 0, 0, 0, 0, 0, 0 },
- [Uw3] = { x, x, U, U, U, x, x, y, y, y, 0, 0, 0, 0 },
- [Dw] = { U, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw2] = { U, U, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Dw3] = { U, U, U, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [Rw] = { y, y, y, x, U, x, x, x, y, x, 0, 0, 0, 0 },
- [Rw2] = { y, y, y, x, U, U, x, x, x, y, x, x, 0, 0 },
- [Rw3] = { y, y, y, x, U, U, U, y, x, x, x, y, 0, 0 },
- [Lw] = { y, x, U, x, x, x, y, y, y, x, x, x, 0, 0 },
- [Lw2] = { y, x, U, U, x, x, x, y, y, y, x, x, 0, 0 },
- [Lw3] = { y, x, U, U, U, x, x, x, y, y, y, x, 0, 0 },
- [Fw] = { x, x, x, U, y, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw2] = { x, x, x, U, U, y, y, x, 0, 0, 0, 0, 0, 0 },
- [Fw3] = { x, x, x, U, U, U, y, x, 0, 0, 0, 0, 0, 0 },
- [Bw] = { x, U, y, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw2] = { x, U, U, y, y, x, x, x, 0, 0, 0, 0, 0, 0 },
- [Bw3] = { x, U, U, U, y, x, x, x, 0, 0, 0, 0, 0, 0 },
-
- [M] = { y, x, U, x, x, U, U, U, y, x, y, y, y, 0 },
- [M2] = { y, x, U, U, x, x, U, U, x, x, x, y, 0, 0 },
- [M3] = { y, x, U, U, U, x, x, U, y, x, x, x, y, 0 },
- [S] = { x, U, U, U, x, x, U, y, y, y, x, 0, 0, 0 },
- [S2] = { x, U, U, x, x, U, U, y, y, x, 0, 0, 0, 0 },
- [S3] = { x, U, x, x, U, U, U, y, x, 0, 0, 0, 0, 0 },
- [E] = { U, x, x, U, U, U, x, x, y, y, y, 0, 0, 0 },
- [E2] = { U, U, x, x, U, U, x, x, y, y, 0, 0, 0, 0 },
- [E3] = { U, U, U, x, x, U, x, x, y, 0, 0, 0, 0, 0 },
-
- [x] = { x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x2] = { x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [x3] = { x, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y] = { y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y2] = { y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [y3] = { y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z] = { y, y, y, x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z2] = { y, y, x, x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- [z3] = { y, x, y, y, y, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray arr;
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- alloc_cubearray(&arr, f);
- cube_to_arrays(cube, &arr, f);
-
- for (i = 0; i < 12; i++)
- if (arr.ep[i] != -1)
- used[arr.ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr.ep[i] == -1)
- arr.ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(&arr, f);
-
- return ret;
-}
-
-static CubeArray *
-alloc_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- return arr;
-}
-
-static void
-append_alg(AlgList *l, Alg alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
-
- node->alg = new_alg("");
- copy_alg(alg, node->alg);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg alg, NissMove m)
-{
- int n = len(alg);
-
- if (!realloc_alg(alg, n))
- return;
-
- alg[n] = m;
- alg[n+1] = (NissMove) { .m = NULLMOVE };
-}
-
-static Cube
-apply_alg_filtered(Alg alg, Cube cube, PieceFilter f)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; alg[i].m != NULLMOVE; i++)
- if (alg[i].inverse)
- ret = apply_move(alg[i].m, ret);
-
- ret = compose_filtered(cube, inverse_cube(ret), f);
-
- for (i = 0; alg[i].m != NULLMOVE; i++)
- if (!alg[i].inverse)
- ret = apply_move(alg[i].m, ret);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- intarrcopy(aux, set, n);
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(m_arr, cube, f);
-}
-
-static Cube
-arrays_to_cube(CubeArray arr, PieceFilter f)
-{
- Cube ret = {0};
- int epose[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposs[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int eposm[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int epe[4], eps[4], epm[4];
- int i, ie, is, im, j;
-
- /* Again, ep is the hardest part */
- if (f.epose) {
- for (i = 0, ie = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (arr.ep[i] == epe_solved[j]) {
- epe[ie++] = j;
- epose[i] = 1;
- }
- }
- }
- ret.epose = epos_from_arrays(epose, epe);
- }
-
- if (f.eposs) {
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (arr.ep[i] == eps_solved[j]) {
- eps[is++] = j;
- eposs[i] = 1;
- }
- }
- }
- for (i = 0; i < 4; i++)
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- ret.eposs = epos_from_arrays(eposs, eps);
- }
-
- if (f.eposm) {
- for (i = 0, im = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (arr.ep[i] == epm_solved[j]) {
- epm[im++] = j;
- eposm[i] = 1;
- }
- }
- }
- for (i = 0; i < 4; i++)
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- ret.eposm = epos_from_arrays(eposm, epm);
- }
-
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr.eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr.eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr.eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr.cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr.coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr.corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr.cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr.cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray arr;
- Cube ret;
-
- alloc_cubearray(&arr, f);
- cube_to_arrays(c2, &arr, f);
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(&arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int epose[12], eposs[12], eposm[12];
- int epe[4], eps[4], epm[4];
- int i, ie, is, im;
-
- /* ep is the hardest */
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose) {
- index_to_perm(cube.epose % factorial(4), 4, epe);
- index_to_subset(cube.epose / factorial(4), 12, 4, epose);
- for (i = 0, ie = 0; i < 12; i++)
- if (epose[i])
- arr->ep[i] = epe_solved[epe[ie++]];
- }
-
- if (f.eposs) {
- index_to_perm(cube.eposs % factorial(4), 4, eps);
- index_to_subset(cube.eposs / factorial(4), 12, 4, eposs);
- for (i = 0; i < 4; i++)
- swap(&eposs[eps_solved[i]], &eposs[i+8]);
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- arr->ep[i] = eps_solved[eps[is++]];
- }
-
- if (f.eposm) {
- index_to_perm(cube.eposm % factorial(4), 4, epm);
- index_to_subset(cube.eposm / factorial(4), 12, 4, eposm);
- for (i = 0; i < 4; i++)
- swap(&eposm[epm_solved[i]], &eposm[i+8]);
- for (i = 0, im = 0; i < 12; i++)
- if (eposm[i])
- arr->ep[i] = epm_solved[epm[im++]];
- }
-
- /* All the others */
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static uint16_t
-epos_from_arrays(int *epos, int *ep)
-{
- return factorial4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-static void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free(i);
- i = aux;
- }
- free(l);
-
- return;
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- int i, j, k;
- bool cij, p1, p2;
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2);
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && (j-(j-1)%3) == (k-(k-1)%3);
- p2 = i && (i-(i-1)%3) == (k-(k-1)%3);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] =
- i == NULLMOVE ? NULLMOVE : i + 2 - 2*((i-1)%3);
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i, j;
- uint16_t ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = (Cube){0};
- for (j = 0; equiv_moves[i][j]; j++)
- c = apply_move_cubearray(equiv_moves[i][j], c, pf_all);
-
- arrs = (CubeArray){
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "ttables not found, generating them.\n");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < factorial12/factorial8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_ttable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_ttable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_ttable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < pow2to11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_ttable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_ttable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_ttable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < pow3to7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_ttable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_ttable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_ttable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < factorial8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_ttable[m][ui] = c.cp;
- }
- for (ui = 0; ui < factorial6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_ttable[m][ui] = c.cpos;
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- bool b1, b2, b3;
- uint16_t ui;
- Move mi, move;
- Trans r, m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(rotation_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- /* Compute rotation_niss array, necessary for rotate_via_compose */
- for (r = 0; r != mirror; r++) {
- concat(rotation_algs[r], rotation_algs[r], rotation_niss[r]);
- for (i = len(rotation_algs[r]); rotation_niss[r][i].m; i++)
- rotation_niss[r][i].inverse = true;
- }
-
- if (read_rtables_file())
- return;
-
- fprintf(stderr, "rtables not found, generating them.\n");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- intarrcopy(ep_mirror, eparr, 12);
- intarrcopy(cp_mirror, cparr, 8);
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < factorial12/factorial8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_rtable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_rtable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_rtable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < pow2to11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_rtable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < pow3to7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_rtable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_rtable[m][ui] =
- invert_digits(co_rtable[m][ui], 3, 7);
- }
- for (ui = 0; ui < factorial8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_rtable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < factorial6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_rtable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_rtable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_rtable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_rtable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_rtable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_rtable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_rtables_file())
- fprintf(stderr, "Error writing rtables\n");
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static void
-intarrcopy(int *src, int *dst, int n)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- return digit_array_to_int(r, n, b);
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray arr, Cube c, PieceFilter f)
-{
- CubeArray arrc;
- Cube ret;
-
- alloc_cubearray(&arrc, f);
- cube_to_arrays(c, &arrc, f);
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr.ep, arrc.ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr.ep, arrc.eofb, 12);
- sum_arrays_mod(arr.eofb, arrc.eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr.ep, arrc.eorl, 12);
- sum_arrays_mod(arr.eorl, arrc.eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr.ep, arrc.eoud, 12);
- sum_arrays_mod(arr.eoud, arrc.eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr.cp, arrc.cp, 8);
-
- if (f.coud) {
- apply_permutation(arr.cp, arrc.coud, 8);
- sum_arrays_mod(arr.coud, arrc.coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr.cp, arrc.corl, 8);
- sum_arrays_mod(arr.corl, arrc.corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr.cp, arrc.cofb, 8);
- sum_arrays_mod(arr.cofb, arrc.cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr.cpos, arrc.cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(&arrc, f);
-
- return ret;
-}
-
-static Move *
-moveset_to_movelist(bool *moveset, Step step)
-{
- Cube c;
- int *a = malloc(NMOVES * sizeof(int)), b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (moveset != NULL) {
- for (i = NULLMOVE+1; i < NMOVES; i++) {
- if (moveset[i]) {
- c = apply_move(i, (Cube){0});
- if (step.f != NULL && step.f(c)) {
- a[na++] = i;
- } else {
- b[nb++] = i;
- }
- }
- }
- }
-
- intarrcopy(b, a+na, nb);
- a[na+nb] = NULLMOVE;
-
- return (Move *)a;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0; /* Truncate */
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static bool
-read_rtables_file()
-{
- FILE *ttf;
- int b = sizeof(uint16_t);
- bool r = true;
- Move m;
-
- if ((ttf = fopen("rtables", "rb")) != NULL) {
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_rtable[m],b,me[0],ttf) == me[0];
- r = r && fread(eposs_rtable[m],b,me[1],ttf) == me[1];
- r = r && fread(eposm_rtable[m],b,me[2],ttf) == me[2];
- r = r && fread(eo_rtable[m],b,me[3],ttf) == me[3];
- r = r && fread(cp_rtable[m],b,me[6],ttf) == me[6];
- r = r && fread(co_rtable[m],b,me[7],ttf) == me[7];
- r = r && fread(cpos_rtable[m],b,me[10],ttf) == me[10];
- r = r && fread(moves_rtable[m],b,me[11],ttf) == me[11];
- }
- fclose(ttf);
- return r;
- } else {
- return false;
- }
-}
-
-static bool
-read_ttables_file()
-{
- FILE *ttf;
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- if ((ttf = fopen("ttables", "rb")) != NULL) {
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_ttable[m],b,me[0],ttf) == me[0];
- r = r && fread(eposs_ttable[m],b,me[1],ttf) == me[1];
- r = r && fread(eposm_ttable[m],b,me[2],ttf) == me[2];
- r = r && fread(eofb_ttable[m],b,me[3],ttf) == me[3];
- r = r && fread(eorl_ttable[m],b,me[4],ttf) == me[4];
- r = r && fread(eoud_ttable[m],b,me[5],ttf) == me[5];
- r = r && fread(cp_ttable[m],b,me[6],ttf) == me[6];
- r = r && fread(coud_ttable[m],b,me[7],ttf) == me[7];
- r = r && fread(corl_ttable[m],b,me[8],ttf) == me[8];
- r = r && fread(cofb_ttable[m],b,me[9],ttf) == me[9];
- r = r && fread(cpos_ttable[m],b,me[10],ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else {
- return false;
- }
-}
-
-static bool
-realloc_alg(Alg alg, int n)
-{
- if (n+1 >= BASEALGLEN) {
- if (reallocarray(alg, n+2, sizeof(NissMove)) == NULL) {
- fprintf(stderr, "Error reallocating alg\n");
- return false;
- }
- }
-
- return true;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Cube ret;
- CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- if (r != mirror) {
- ret = apply_alg_filtered(rotation_niss[r], c, f);
- } else {
- ret = move_via_arrays(ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(ma, ret, f);
- }
-
- return ret;
-}
-
-static void
-solve_dfs(Cube c, Step s, SolveOptions opts, DfsData dd)
-{
- DfsData newdd;
- Move move;
- NissMove nm;
- int i;
- bool found_many, prune, niss_makes_sense;
-
- found_many = dd.sols->len >= opts.max_solutions;
- prune = (!opts.can_niss || dd.niss) && dd.m + s.f(c) > dd.d;
- if (found_many || prune)
- return;
-
- if (!s.f(c)) {
- if (dd.m == dd.d)
- append_alg(dd.sols, dd.current_alg);
- return;
- }
-
- for (i = 0; opts.sorted_moves[i] != NULLMOVE; i++) {
- move = opts.sorted_moves[i];
- if (possible_next[dd.last2][dd.last1][move]) {
- nm = (NissMove){ .m = move, .inverse = dd.niss };
- newdd = (DfsData) {
- .d = dd.d,
- .m = dd.m + 1,
- .niss = dd.niss,
- .last1 = move,
- .last2 = dd.last1,
- .sols = dd.sols,
- .current_alg = dd.current_alg,
- };
-
- append_move(dd.current_alg, nm);
- solve_dfs(apply_move(move, c), s, opts, newdd);
- remove_last_moves(dd.current_alg, 1);
- }
- }
-
- niss_makes_sense = !dd.m || (s.f(apply_move(dd.last1, (Cube){0})));
- if (opts.can_niss && !dd.niss && niss_makes_sense) {
- newdd = (DfsData) {
- .d = dd.d,
- .m = dd.m,
- .niss = true,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = dd.sols,
- .current_alg = dd.current_alg,
- };
- solve_dfs(inverse_cube(c), s, opts, newdd);
- }
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_rtables_file()
-{
- FILE *ttf;
- bool r = true;
- int b = sizeof(uint16_t);
- Move m;
-
- if ((ttf = fopen("rtables", "wb")) != NULL) {
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_rtable[m],b,me[0], ttf) == me[0];
- r = r && fwrite(eposs_rtable[m],b,me[1], ttf) == me[1];
- r = r && fwrite(eposm_rtable[m],b,me[2], ttf) == me[2];
- r = r && fwrite(eo_rtable[m],b,me[3], ttf) == me[3];
- r = r && fwrite(cp_rtable[m],b,me[6], ttf) == me[6];
- r = r && fwrite(co_rtable[m],b,me[7], ttf) == me[7];
- r = r && fwrite(cpos_rtable[m],b,me[10],ttf) == me[10];
- r = r && fwrite(moves_rtable[m],b,me[11],ttf)== me[11];
- }
- fclose(ttf);
- return r;
- } else {
- return false;
- }
-}
-
-static bool
-write_ttables_file()
-{
- FILE *ttf;
- int m, b = sizeof(uint16_t);;
- bool r = true;
-
- if ((ttf = fopen("ttables", "wb")) != NULL) {
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_ttable[m],b,me[0],ttf) == me[0];
- r = r && fwrite(eposs_ttable[m],b,me[1],ttf) == me[1];
- r = r && fwrite(eposm_ttable[m],b,me[2],ttf) == me[2];
- r = r && fwrite(eofb_ttable[m],b,me[3],ttf) == me[3];
- r = r && fwrite(eorl_ttable[m],b,me[4],ttf) == me[4];
- r = r && fwrite(eoud_ttable[m],b,me[5],ttf) == me[5];
- r = r && fwrite(cp_ttable[m],b,me[6],ttf) == me[6];
- r = r && fwrite(coud_ttable[m],b,me[7],ttf) == me[7];
- r = r && fwrite(corl_ttable[m],b,me[8],ttf) == me[8];
- r = r && fwrite(cofb_ttable[m],b,me[9],ttf) == me[9];
- r = r && fwrite(cpos_ttable[m],b,me[10],ttf) == me[10];
- }
- fclose(ttf);
- return r;
- } else {
- return false;
- }
-}
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg alg, Cube cube)
-{
- return apply_alg_filtered(alg, cube, pf_all);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- Cube moved = {0};
-
- moved.epose = epose_ttable[m][cube.epose];
- moved.eposs = eposs_ttable[m][cube.eposs];
- moved.eposm = eposm_ttable[m][cube.eposm];
- moved.eofb = eofb_ttable[m][cube.eofb];
- moved.eorl = eorl_ttable[m][cube.eorl];
- moved.eoud = eoud_ttable[m][cube.eoud];
- moved.coud = coud_ttable[m][cube.coud];
- moved.cofb = cofb_ttable[m][cube.cofb];
- moved.corl = corl_ttable[m][cube.corl];
- moved.cp = cp_ttable[m][cube.cp];
- moved.cpos = cpos_ttable[m][cube.cpos];
-
- return moved;
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- Cube transformed = {0};
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- uint16_t aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- uint16_t aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- transformed.epose = epose_rtable[t][aux_epos[epose_source[t]]];
- transformed.eposs = eposs_rtable[t][aux_epos[eposs_source[t]]];
- transformed.eposm = eposm_rtable[t][aux_epos[eposm_source[t]]];
- transformed.eofb = eo_rtable[t][aux_eo[eofb_source[t]]];
- transformed.eorl = eo_rtable[t][aux_eo[eorl_source[t]]];
- transformed.eoud = eo_rtable[t][aux_eo[eoud_source[t]]];
- transformed.coud = co_rtable[t][aux_co[coud_source[t]]];
- transformed.corl = co_rtable[t][aux_co[corl_source[t]]];
- transformed.cofb = co_rtable[t][aux_co[cofb_source[t]]];
- transformed.cp = cp_rtable[t][cube.cp];
- transformed.cpos = cpos_rtable[t][cube.cpos];
-
- return transformed;
-}
-
-/* TODO: this has to be changed using pre-computations */
-bool
-block_solved(Cube cube, Block block)
-{
- CubeArray arr;
- int i;
- bool ret = true;
-
- alloc_cubearray(&arr, pf_all);
- cube_to_arrays(cube, &arr, pf_all);
-
- for (i = 0; i < 12; i++)
- ret = ret && !(block.edge[i] && (arr.ep[i] != i || arr.eofb[i]));
- for (i = 0; i < 8; i++)
- ret = ret && !(block.corner[i] && (arr.cp[i] != i || arr.coud[i]));
- for (i = 0; i < 6; i++)
- ret = ret && !(block.center[i] && arr.cpos[i] != i);
-
- free_cubearray(&arr, pf_all);
-
- return ret;
-}
-
-Center
-center_at(Cube cube, Center c)
-{
- int ret;
- CubeArray arr;
-
- alloc_cubearray(&arr, pf_cpos);
- cube_to_arrays(cube, &arr, pf_cpos);
- ret = arr.cpos[c];
- free_cubearray(&arr, pf_cpos);
-
- return ret;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-Corner
-corner_at(Cube cube, Corner c)
-{
- int ret;
- CubeArray arr;
-
- alloc_cubearray(&arr, pf_cp);
- cube_to_arrays(cube, &arr, pf_cp);
- ret = arr.cp[c];
- free_cubearray(&arr, pf_cp);
-
- return ret;
-}
-
-Edge
-edge_at(Cube cube, Edge e)
-{
- int ret;
- CubeArray arr;
-
- alloc_cubearray(&arr, pf_ep);
- cube_to_arrays(cube, &arr, pf_ep);
- ret = arr.ep[e];
- free_cubearray(&arr, pf_ep);
-
- return ret;
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray arr, inv;
- Cube ret;
- int i;
-
- alloc_cubearray(&arr, pf_all);
- alloc_cubearray(&inv, pf_all);
-
- cube_to_arrays(cube, &arr, pf_all);
-
- for (i = 0; i < 12; i++) {
- inv.ep[arr.ep[i]] = i;
- inv.eofb[arr.ep[i]] = arr.eofb[i];
- inv.eorl[arr.ep[i]] = arr.eorl[i];
- inv.eoud[arr.ep[i]] = arr.eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv.cp[arr.cp[i]] = i;
- inv.coud[arr.cp[i]] = (3 - arr.coud[i]) % 3;
- inv.corl[arr.cp[i]] = (3 - arr.corl[i]) % 3;
- inv.cofb[arr.cp[i]] = (3 - arr.cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv.cpos[arr.cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(&arr, pf_all);
- free_cubearray(&inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b;
- uint16_t x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
- CubeArray arr;
-
- alloc_cubearray(&arr, pf_all);
- cube_to_arrays(cube, &arr, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr.ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr.eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr.cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr.coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr.cpos[i]]);
- printf("\n");
-
- free_cubearray(&arr, pf_all);
-}
-
-void
-concat(Alg src1, Alg src2, Alg dest)
-{
- int n1 = len(src1), n2 = len(src2);
-
- if (!realloc_alg(dest, n1+n2))
- return;
-
- copy_alg(src1, dest);
- copy_alg(src2, dest + n1);
-}
-
-void
-copy_alg(Alg src, Alg dest)
-{
- int i, n = len(src);
-
- if (!realloc_alg(dest, n))
- return;
-
- for (i = 0; src[i].m != NULLMOVE; i++)
- dest[i] = src[i];
- dest[i].m = NULLMOVE;
-}
-
-void
-invert_alg(Alg src, Alg dest)
-{
- Move m;
- int i, n = len(src);
-
- if (!realloc_alg(dest, n))
- return;
-
- for (i = 0; i < n; i++) {
- m = inverse_move_aux[src[i].m];
- dest[n-i-1] = (NissMove) { .m = m, .inverse = src[i].inverse };
- }
- dest[n].m = NULLMOVE;
-}
-
-int
-len(Alg alg)
-{
- int i;
-
- for (i = 0; alg[i].m != NULLMOVE; i++);
-
- return i;
-}
-
-Alg
-new_alg(char *str)
-{
- Alg alg = malloc(BASEALGLEN * sizeof(NissMove));
- int i;
- bool niss = false;
- Move j, m;
- NissMove nm;
-
- alg[0] = (NissMove){ .m = NULLMOVE };
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- nm = (NissMove){ .m = m, .inverse = niss };
- append_move(alg, nm);
- break;
- }
- }
- }
- append_move(alg, (NissMove){ .m = NULLMOVE });
-
- return alg;
-}
-
-void
-print_alg(Alg alg)
-{
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; alg[i].m != NULLMOVE; i++) {
- if (!niss && alg[i].inverse)
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg[i].inverse)
- strcpy(fill, ") ");
- if (niss == alg[i].inverse)
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg[i].m]);
- niss = alg[i].inverse;
- }
- printf("%s\n", niss ? ")" : "");
-}
-
-void
-remove_last_moves(Alg alg, int k)
-{
- int n = len(alg);
- int i = max(0, n-k);
-
- alg[i].m = NULLMOVE;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions opts)
-{
- AlgList *sols = new_alglist();
- AlgListNode *node;
- Cube c;
- DfsData dd;
- int i;
-
- if (step.ready != NULL && !step.ready(cube))
- return sols;
-
- if (opts.sorted_moves == NULL)
- opts.sorted_moves = moveset_to_movelist(opts.moveset, step);
-
- for (i = opts.min_moves; i <= opts.max_moves; i++) {
- if (sols->len && opts.optimal_only)
- break;
-
- c = apply_trans(opts.pre_trans, cube);
- dd = (DfsData) {
- .d = i,
- .m = 0,
- .niss = false,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- solve_dfs(c, step, opts, dd);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[opts.pre_trans], node->alg);
-
- return sols;
-}
-
-void
-transform_alg(Trans t, Alg alg)
-{
- int i;
-
- for (i = 0; alg[i].m != NULLMOVE; i++)
- alg[i].m = moves_rtable[t][alg[i].m];
-}
-
-
-void
-init()
-{
- init_moves();
- init_auxtables();
- init_trans();
-}
diff --git a/old/2021-06-02-cleanedup/cube.h b/old/2021-06-02-cleanedup/cube.h
@@ -1,179 +0,0 @@
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Constants ****************************************************************/
-
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-
-/* Typedefs *****************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct nissmove * Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct cube Cube;
-typedef struct nissmove NissMove;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-/* Type specifications *******************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-struct
-alglist
-{
- AlgListNode *first;
- AlgListNode *last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg alg;
- AlgListNode *next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cube
-{
- uint16_t epose;
- uint16_t eposs;
- uint16_t eposm;
- uint16_t eofb;
- uint16_t eorl;
- uint16_t eoud;
- uint16_t cp;
- uint16_t coud;
- uint16_t cofb;
- uint16_t corl;
- uint16_t cpos;
-};
-
-struct
-nissmove
-{
- Move m;
- bool inverse;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool *moveset;
- Move *sorted_moves;
- Trans pre_trans;
-};
-
-struct
-step
-{
- int (*f)(Cube);
- bool (*ready)(Cube);
-};
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Center center_at(Cube cube, Center c);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Corner corner_at(Cube cube, Corner c);
-Edge edge_at(Cube cube, Edge e);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_solved(Cube cube, bool reorient);
-int piece_orientation(Cube cube, int piece, char *orientation);
-void print_cube(Cube cube);
-AlgList * solve(Cube cube, Step step, SolveOptions opts);
-
-void concat(Alg src1, Alg src2, Alg dest);
-void copy_alg(Alg src, Alg dest);
-void invert_alg(Alg src, Alg dest);
-int len(Alg alg);
-Alg new_alg(char *str);
-void print_alg(Alg alg);
-void remove_last_moves(Alg alg, int k);
-void transform_alg(Trans t, Alg alg);
-
-void init();
diff --git a/old/2021-06-02-cleanedup/main.c b/old/2021-06-02-cleanedup/main.c
@@ -1,35 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
-
- init();
-
- algo = new_alg("R U R' F");
- cube = apply_alg(algo, (Cube){0});
-
- print_cube(apply_trans(rd, cube));
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 5,
- .optimal_only = true,
- .max_solutions = 3,
- .can_niss = false,
- .moveset = standard_moveset,
- .pre_trans = fu
- };
- sols = solve(cube, step_eofb, opts);
- if (sols->len == 0)
- fprintf(stderr, "No solution found\n");
- else
- print_alg(sols->first->alg);
-
-
- return 0;
-}
diff --git a/old/2021-06-02-cleanedup/steps.h b/old/2021-06-02-cleanedup/steps.h
@@ -1,22 +0,0 @@
-/* Pre-conditions, i.e. "ready(cube)" functions ******************************/
-
-bool always_ready(Cube cube) { return true; }
-
-/* Main functions, i.e. "f(cube)" ********************************************/
-
-int f_eofb(Cube cube) { return (cube.eofb != 0) ? 1 : 0; }
-
-/* Steps *********************************************************************/
-
-Step step_eofb = { .f = f_eofb, .ready = always_ready };
-
-/* Movesets ******************************************************************/
-
-bool standard_moveset[NMOVES] = {
- [U] = true, [U2] = true, [U3] = true,
- [D] = true, [D2] = true, [D3] = true,
- [R] = true, [R2] = true, [R3] = true,
- [L] = true, [L2] = true, [L3] = true,
- [F] = true, [F2] = true, [F3] = true,
- [B] = true, [B2] = true, [B3] = true,
-};
diff --git a/old/2021-06-14-oldalg/cube.c b/old/2021-06-14-oldalg/cube.c
@@ -1,2849 +0,0 @@
-#include "cube.h"
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define BASEALGLEN 50
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-#define PTABLESIZE(n) ((n+1) / 2)
-#define PTABLEVAL(tab,ind) (((ind)%2) ? (tab[(ind)/2] / 16) : \
- (tab[(ind)/2] % 16))
-
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static uint16_t array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static Move base_move(Move m);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent(int pos1, int pos2);
-static uint16_t epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(uint16_t epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void generate_ptable(PruneData *pd);
-static void generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void moveset_to_list(bool (*ms)(Move), int (*f)(Cube), Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_set_reached(PruneData *pd, uint64_t ind);
-static void ptable_update(PruneData *pd, uint64_t ind, int m);
-static bool read_ptable_file(PruneData *pd);
-static bool read_ttables_file();
-static bool read_mtables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static void solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_ptable_file(PruneData *pd);
-static bool write_ttables_file();
-static bool write_mtables_file();
-
-static void init_auxtables();
-static void init_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_steps();
-static void init_strings();
-static void init_trans();
-static void init_trans_aux();
-
-static bool moveset_HTM(Move m);
-static bool moveset_URF(Move m);
-
-/* Steps and related functions and data **************************************/
-
-Step eofb_HTM;
-Step eorl_HTM;
-Step eoud_HTM;
-Step coud_HTM;
-Step corl_HTM;
-Step cofb_HTM;
-Step coud_URF;
-Step corl_URF;
-Step cofb_URF;
-Step corners_HTM;
-Step corners_URF;
-Step edges_HTM;
-Step drud_HTM;
-Step optimal_HTM;
-
-PruneData pd_eofb_HTM;
-PruneData pd_coud_HTM;
-PruneData pd_corners_HTM;
-PruneData pd_ep_HTM;
-PruneData pd_drud_HTM;
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_ep(Cube cube);
-static uint64_t index_drud(Cube cube);
-
-static int check_nothing(Cube cube);
-static int check_eofb_HTM(Cube cube);
-static int check_coud_HTM(Cube cube);
-static int check_coud_URF(Cube cube);
-static int check_corners_HTM(Cube cube);
-static int check_corners_URF(Cube cube);
-static int check_edges_HTM(Cube cube);
-static int check_drud_HTM(Cube cube);
-static int check_optimal_HTM(Cube cube);
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-
-static uint16_t epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eo_ttable[NTRANS][POW2TO11];
-static uint16_t cp_ttable[NTRANS][FACTORIAL8];
-static uint16_t co_ttable[NTRANS][POW3TO7];
-static uint16_t cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static uint16_t epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eofb_mtable[NMOVES][POW2TO11];
-static uint16_t eorl_mtable[NMOVES][POW2TO11];
-static uint16_t eoud_mtable[NMOVES][POW2TO11];
-static uint16_t cp_mtable[NMOVES][FACTORIAL8];
-static uint16_t coud_mtable[NMOVES][POW3TO7];
-static uint16_t cofb_mtable[NMOVES][POW3TO7];
-static uint16_t corl_mtable[NMOVES][POW3TO7];
-static uint16_t cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * trans_algs[NROTATIONS];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- AlgNode *i;
-
- node->alg = new_alg("");
- for (i = alg->first; i != NULL; i = i->next)
- append_move(node->alg, i->m, i->inverse);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- AlgNode *node = malloc(sizeof(AlgNode));
-
- node->m = m;
- node->inverse = inverse;
- node->next = NULL;
- node->prev = alg->last;
-
- if (++alg->len == 1)
- alg->first = node;
- else
- alg->last->next = node;
- alg->last = node;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- AlgNode *i;
-
- for (i = alg->first; i != NULL; i = i->next)
- if (i->inverse)
- ret = a ? apply_move(i->m, ret) :
- apply_move_cubearray(i->m, ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = alg->first; i != NULL; i = i->next)
- if (!i->inverse)
- ret = a ? apply_move(i->m, ret) :
- apply_move_cubearray(i->m, ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static uint16_t
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 1)
- ep8[j++] = (edge_slice(ep[i]) == 0) ? 1 : 0;
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static uint16_t
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(uint16_t epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- AlgNode *aux, *i = alg->first;
-
- while (i != NULL) {
- aux = i->next;
- free(i);
- i = aux;
- }
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-generate_ptable(PruneData *pd)
-{
- uint64_t j;
- DfsData dd;
-
- if (pd->generated)
- return;
-
- pd->ptable = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- dd.m = 0;
- dd.last1 = NULLMOVE;
- dd.last2 = NULLMOVE;
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->size; j++)
- ptable_update(pd, j, 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
-
- pd->reached = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->size; dd.d++) {
- memset(pd->reached, 0, PTABLESIZE(pd->size)*sizeof(uint8_t));
- generate_ptable_dfs((Cube){0}, pd, &dd);
- fprintf(stderr, "Depth %d completed, generated %lu/%lu\n",
- dd.d, pd->n, pd->size);
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-static void
-generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- uint64_t ind = pd->index(c);
- int oldval = PTABLEVAL(pd->ptable, ind);
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- if (oldval < dd->m || PTABLEVAL(pd->reached, ind) || pd->n == pd->size)
- return;
-
- ptable_set_reached(pd, ind);
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, ind, dd->m);
- return;
- }
-
- dd->m++;
- dd->last2 = dd->last1;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (possible_next[l2][l1][move]) {
- dd->last1 = move;
- generate_ptable_dfs(apply_move(move, c), pd, dd);
- }
- }
-
- dd->m--;
- dd->last1 = l1;
- dd->last2 = l2;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-moveset_to_list(bool (*ms)(Move m), int (*f)(Cube), Move *r)
-{
- Cube c;
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- c = apply_move(i, (Cube){0});
- if (f != NULL && f(c))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0; /* Truncate */
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_set_reached(PruneData *pd, uint64_t ind)
-{
- uint8_t oldval2 = pd->reached[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = ind % 2 ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = ind % 2 ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return r == PTABLESIZE(pd->size);
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(uint16_t);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Alg *inv;
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Cube ret;
-
- if (r != mirror) {
- ret = apply_alg_generic(trans_algs[r], c, f, true);
- inv = on_inverse(trans_algs[r]);
- ret = apply_alg_generic(inv, ret, f, true);
- free_alg(inv);
- } else {
- ret = move_via_arrays(&ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(&ma, ret, f);
- }
-
- return ret;
-}
-
-static void
-solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move move, l1 = dd->last1, l2 = dd->last2;
- int i, lower_bound = s.check(c);
- bool found_many, prune, niss_make_sense, nissbackup = dd->niss;
-
- if (opts->can_niss && !dd->niss)
- lower_bound = MIN(1, lower_bound);
-
- found_many = dd->sols->len >= opts->max_solutions;
- prune = dd->current_alg->len + lower_bound > dd->d;
- if (found_many || prune)
- return;
-
- if (!lower_bound) { /* solved */
- if (dd->current_alg->len == dd->d)
- append_alg(dd->sols, dd->current_alg);
- return;
- }
-
- dd->last2 = dd->last1;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (possible_next[l2][l1][move]) {
- dd->last1 = move;
- append_move(dd->current_alg, move, dd->niss);
- solve_dfs(apply_move(move, c), s, opts, dd);
- remove_last_move(dd->current_alg);
- }
- }
-
- niss_make_sense = !dd->current_alg->len ||
- (s.check(apply_move(l1,(Cube){0})));
- if (opts->can_niss && !dd->niss && niss_make_sense) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
- solve_dfs(inverse_cube(c), s, opts, dd);
- }
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = nissbackup;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return written == PTABLESIZE(pd->size);
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(uint16_t);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- uint64_t ui, uj;
- int i, j, k;
- bool cij, p1, p2;
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj] = epos_dependent(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2);
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- uint16_t ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray){
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_steps()
-{
- /* PruneData */
- pd_eofb_HTM.filename = "ptable_eofb_HTM";
- pd_eofb_HTM.size = POW2TO11;
- pd_eofb_HTM.index = index_eofb;
- pd_eofb_HTM.moveset = moveset_HTM;
-
- pd_coud_HTM.filename = "ptable_coud_HTM";
- pd_coud_HTM.size = POW3TO7;
- pd_coud_HTM.index = index_coud;
- pd_coud_HTM.moveset = moveset_HTM;
-
- pd_corners_HTM.filename = "ptable_corners_HTM";
- pd_corners_HTM.size = POW3TO7 * FACTORIAL8;
- pd_corners_HTM.index = index_corners;
- pd_corners_HTM.moveset = moveset_HTM;
-
- pd_ep_HTM.filename = "ptable_ep_HTM";
- pd_ep_HTM.size = FACTORIAL12;
- pd_ep_HTM.index = index_ep;
- pd_ep_HTM.moveset = moveset_HTM;
-
- pd_drud_HTM.filename = "ptable_drud_HTM";
- pd_drud_HTM.size = POW2TO11 * POW3TO7 * BINOM12ON4;
- pd_drud_HTM.index = index_drud;
- pd_drud_HTM.moveset = moveset_HTM;
-
-
- /* Actual steps */
- eofb_HTM.check = check_eofb_HTM;
- eofb_HTM.ready = check_nothing;
- eofb_HTM.pre_trans = uf;
- eofb_HTM.moveset = moveset_HTM;
-
- eorl_HTM.check = check_eofb_HTM;
- eorl_HTM.ready = check_nothing;
- eorl_HTM.pre_trans = ur;
- eorl_HTM.moveset = moveset_HTM;
-
- eoud_HTM.check = check_eofb_HTM;
- eoud_HTM.ready = check_nothing;
- eoud_HTM.pre_trans = bu;
- eoud_HTM.moveset = moveset_HTM;
-
-
- coud_HTM.check = check_coud_HTM;
- coud_HTM.ready = check_nothing;
- coud_HTM.pre_trans = uf;
- coud_HTM.moveset = moveset_HTM;
-
- corl_HTM.check = check_coud_HTM;
- corl_HTM.ready = check_nothing;
- corl_HTM.pre_trans = rf;
- corl_HTM.moveset = moveset_HTM;
-
- cofb_HTM.check = check_coud_HTM;
- cofb_HTM.ready = check_nothing;
- cofb_HTM.pre_trans = fd;
- cofb_HTM.moveset = moveset_HTM;
-
- coud_URF.check = check_coud_URF;
- coud_URF.ready = check_nothing;
- coud_URF.pre_trans = uf;
- coud_URF.moveset = moveset_URF;
-
- corl_URF.check = check_coud_URF;
- corl_URF.ready = check_nothing;
- corl_URF.pre_trans = rf;
- corl_URF.moveset = moveset_URF;
-
- cofb_URF.check = check_coud_URF;
- cofb_URF.ready = check_nothing;
- cofb_URF.pre_trans = fd;
- cofb_URF.moveset = moveset_URF;
-
- corners_HTM.check = check_corners_HTM;
- corners_HTM.ready = check_nothing;
- corners_HTM.pre_trans = uf;
- corners_HTM.moveset = moveset_HTM;
-
- corners_URF.check = check_corners_URF;
- corners_URF.ready = check_nothing;
- corners_URF.pre_trans = uf;
- corners_URF.moveset = moveset_URF;
-
- edges_HTM.check = check_edges_HTM;
- edges_HTM.ready = check_nothing;
- edges_HTM.pre_trans = uf;
- edges_HTM.moveset = moveset_HTM;
-
- drud_HTM.check = check_drud_HTM;
- drud_HTM.ready = check_nothing;
- drud_HTM.pre_trans = uf;
- drud_HTM.moveset = moveset_HTM;
-
- optimal_HTM.check = check_optimal_HTM;
- optimal_HTM.ready = check_nothing;
- optimal_HTM.pre_trans = uf;
- optimal_HTM.moveset = moveset_HTM;
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- bool b1, b2, b3;
- uint16_t ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(trans_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- memcpy(eparr, ep_mirror, 12 * sizeof(int));
- memcpy(cparr, cp_mirror, 8 * sizeof(int));
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(trans_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_ttable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_ttable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_ttable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_ttable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- trans_algs[uf] = new_alg("");
- trans_algs[ur] = new_alg("y");
- trans_algs[ub] = new_alg("y2");
- trans_algs[ul] = new_alg("y3");
-
- trans_algs[df] = new_alg("z2");
- trans_algs[dr] = new_alg("y z2");
- trans_algs[db] = new_alg("x2");
- trans_algs[dl] = new_alg("y3 z2");
-
- trans_algs[rf] = new_alg("z3");
- trans_algs[rd] = new_alg("z3 y");
- trans_algs[rb] = new_alg("z3 y2");
- trans_algs[ru] = new_alg("z3 y3");
-
- trans_algs[lf] = new_alg("z");
- trans_algs[ld] = new_alg("z y3");
- trans_algs[lb] = new_alg("z y2");
- trans_algs[lu] = new_alg("z y");
-
- trans_algs[fu] = new_alg("x y2");
- trans_algs[fr] = new_alg("x y");
- trans_algs[fd] = new_alg("x");
- trans_algs[fl] = new_alg("x y3");
-
- trans_algs[bu] = new_alg("x3");
- trans_algs[br] = new_alg("x3 y");
- trans_algs[bd] = new_alg("x3 y2");
- trans_algs[bl] = new_alg("x3 y3");
-}
-
-/* Linearization functions implementation ************************************/
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_ep(Cube cube)
-{
- uint64_t a, b, c;
-
- /* TODO: remove this check */
- if (epos_dependent_aux[cube.eposs/FACTORIAL4][cube.epose/FACTORIAL4] ==BINOM8ON4)
- fprintf(stderr, "Impossible\n");
-
- a = cube.eposs;
- b = (cube.epose % FACTORIAL4) +
- epos_dependent_aux[cube.eposs/FACTORIAL4][cube.epose/FACTORIAL4] *
- FACTORIAL4;
- c = cube.eposm % FACTORIAL4;
-
- b *= FACTORIAL4 * BINOM12ON4;
- c *= FACTORIAL4 * BINOM12ON4 * FACTORIAL4 * BINOM8ON4;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-/* Step checking functions implementation ************************************/
-
-static int
-check_nothing(Cube cube)
-{
- return true;
-}
-
-static int
-check_eofb_HTM(Cube cube)
-{
- if (!pd_eofb_HTM.generated)
- generate_ptable(&pd_eofb_HTM);
-
- return PTABLEVAL(pd_eofb_HTM.ptable, cube.eofb);
-}
-
-static int
-check_coud_HTM(Cube cube)
-{
- if (!pd_coud_HTM.generated)
- generate_ptable(&pd_coud_HTM);
-
- return PTABLEVAL(pd_coud_HTM.ptable, cube.coud);
-}
-
-static int
-check_coud_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- int ud = check_coud_HTM(cube);
- int rl = check_coud_HTM(apply_move(z, cube));
- int fb = check_coud_HTM(apply_move(x, cube));
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-check_corners_HTM(Cube cube)
-{
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
-
- return PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
-}
-
-static int
-check_corners_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int ret = 15;
- Cube c;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- c = apply_alg(trans_algs[i], cube);
- ret = MIN(ret, check_corners_HTM(c));
- }
-
- return ret;
-}
-
-static int
-check_edges_HTM(Cube cube)
-{
- int ret = 0;
-
- if (!pd_ep_HTM.generated)
- generate_ptable(&pd_ep_HTM);
-
- ret = MAX(ret, PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)));
- ret = MAX(ret, check_eofb_HTM(cube));
- ret = MAX(ret, check_eofb_HTM(apply_trans(ur, cube)));
- ret = MAX(ret, check_eofb_HTM(apply_trans(fd, cube)));
-
- return ret;
-}
-
-static int
-check_drud_HTM(Cube cube)
-{
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
-
- return PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
-}
-
-static int
-check_optimal_HTM(Cube cube)
-{
- int dr1, dr2, dr3, drmax, cor; /*ep;*/
-
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
- /*
- *if (!pd_ep_HTM.generated)
- * generate_ptable(&pd_ep_HTM);
- */
-
- dr1 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
- dr2 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(rf, cube)));
- dr3 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(fd, cube)));
-
- drmax = MAX(dr1, MAX(dr2, dr3));
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- drmax++;
-
- cor = PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
- /* ep = PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)); */
-
- /*return MAX(drmax, MAX(ep, cor));*/
- if (drmax == 0 && cor == 0)
- return is_solved(cube, false) ? 0 : 1;
- return MAX(drmax, cor);
-}
-
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- Cube moved = {0};
-
- moved.epose = epose_mtable[m][cube.epose];
- moved.eposs = eposs_mtable[m][cube.eposs];
- moved.eposm = eposm_mtable[m][cube.eposm];
- moved.eofb = eofb_mtable[m][cube.eofb];
- moved.eorl = eorl_mtable[m][cube.eorl];
- moved.eoud = eoud_mtable[m][cube.eoud];
- moved.coud = coud_mtable[m][cube.coud];
- moved.cofb = cofb_mtable[m][cube.cofb];
- moved.corl = corl_mtable[m][cube.corl];
- moved.cp = cp_mtable[m][cube.cp];
- moved.cpos = cpos_mtable[m][cube.cpos];
-
- return moved;
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- Cube transformed = {0};
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- uint16_t aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- uint16_t aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- transformed.epose = epose_ttable[t][aux_epos[epose_source[t]]];
- transformed.eposs = eposs_ttable[t][aux_epos[eposs_source[t]]];
- transformed.eposm = eposm_ttable[t][aux_epos[eposm_source[t]]];
- transformed.eofb = eo_ttable[t][aux_eo[eofb_source[t]]];
- transformed.eorl = eo_ttable[t][aux_eo[eorl_source[t]]];
- transformed.eoud = eo_ttable[t][aux_eo[eoud_source[t]]];
- transformed.coud = co_ttable[t][aux_co[coud_source[t]]];
- transformed.corl = co_ttable[t][aux_co[corl_source[t]]];
- transformed.cofb = co_ttable[t][aux_co[cofb_source[t]]];
- transformed.cp = cp_ttable[t][cube.cp];
- transformed.cpos = cpos_ttable[t][cube.cpos];
-
- return transformed;
-}
-
-/* TODO: this has to be changed using pre-computations */
-bool
-block_solved(Cube cube, Block block)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- int i;
- bool ret = true;
-
- for (i = 0; i < 12; i++)
- ret = ret && !(block.edge[i] && (arr->ep[i] != i || arr->eofb[i]));
- for (i = 0; i < 8; i++)
- ret = ret && !(block.corner[i] && (arr->cp[i] != i || arr->coud[i]));
- for (i = 0; i < 6; i++)
- ret = ret && !(block.center[i] && arr->cpos[i] != i);
-
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-Center
-center_at(Cube cube, Center c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cpos);
-
- ret = arr->cpos[c];
- free_cubearray(arr, pf_cpos);
-
- return ret;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-Corner
-corner_at(Cube cube, Corner c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cp);
-
- ret = arr->cp[c];
- free_cubearray(arr, pf_cp);
-
- return ret;
-}
-
-Edge
-edge_at(Cube cube, Edge e)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
- free_cubearray(arr, pf_ep);
-
- return ret;
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- Trans i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(trans_algs[i],cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b;
- uint16_t x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c = apply_trans(step.pre_trans, cube);
- DfsData dd = {
- .m = 0,
- .niss = false,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(c))
- return sols;
-
- moveset_to_list(step.moveset, step.check, dd.sorted_moves);
-
- for (dd.d = MAX(opts->min_moves, step.check(c));
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- solve_dfs(c, step, opts, &dd);
- if (opts->feedback)
- fprintf(stderr,
- "Depth %d completed, found %d solutions\n",
- dd.d, sols->len);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[step.pre_trans], node->alg);
-
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- AlgNode *i;
-
- for (i = alg->last; i != NULL; i = i->prev)
- append_move(ret, i->m, i->inverse);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->first = NULL;
- alg->last = NULL;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- AlgNode *i;
-
- for (i = alg->first; i != NULL; i = i->next)
- append_move(ret, i->m, !i->inverse);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- char fill[4];
- AlgNode *i;
- bool niss = false;
-
- for (i = alg->first; i != NULL; i = i->next) {
- if (!niss && i->inverse)
- strcpy(fill, i == alg->first ? "(" : " (");
- if (niss && !i->inverse)
- strcpy(fill, ") ");
- if (niss == i->inverse)
- strcpy(fill, i == alg->first ? "" : " ");
-
- printf("%s%s", fill, move_string[i->m]);
- niss = i->inverse;
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- memset(a, 0, 16 * sizeof(uint64_t));
-
- if (!pd->generated)
- generate_ptable(pd);
-
- for (i = 0; i < pd->size; i++)
- a[PTABLEVAL(pd->ptable, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-remove_last_move(Alg *alg)
-{
- AlgNode *newlast = alg->last->prev;
- free(alg->last);
- if (newlast != NULL)
- newlast->next = NULL;
- alg->last = newlast;
- alg->len--;
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- AlgNode *i;
-
- for (i = alg->first; i != NULL; i = i->next)
- i->m = moves_ttable[t][i->m];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_trans_aux();
- init_trans();
- init_steps();
-}
-
-
diff --git a/old/2021-06-14-oldalg/cube.h b/old/2021-06-14-oldalg/cube.h
@@ -1,73 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "cubetypes.h"
-
-/* Steps *********************************************************************/
-
-extern Step eofb_HTM;
-extern Step eorl_HTM;
-extern Step eoud_HTM;
-extern Step coud_HTM;
-extern Step corl_HTM;
-extern Step cofb_HTM;
-extern Step coud_URF;
-extern Step corl_URF;
-extern Step cofb_URF;
-extern Step corners_HTM;
-extern Step corners_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Center center_at(Cube cube, Center c);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Corner corner_at(Cube cube, Corner c);
-Edge edge_at(Cube cube, Edge e);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-int piece_orientation(Cube cube, int piece, char *orientation);
-void print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-void remove_last_move(Alg *alg);
-void transform_alg(Trans t, Alg *alg);
-
-void print_ptable(PruneData *pd);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-14-oldalg/cubetypes.h b/old/2021-06-14-oldalg/cubetypes.h
@@ -1,210 +0,0 @@
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct algnode AlgNode;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- AlgNode * first;
- AlgNode * last;
- int len;
-};
-
-struct
-algnode
-{
- Move m;
- bool inverse;
- AlgNode * next;
- AlgNode * prev;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cube
-{
- uint16_t epose;
- uint16_t eposs;
- uint16_t eposm;
- uint16_t eofb;
- uint16_t eorl;
- uint16_t eoud;
- uint16_t cp;
- uint16_t coud;
- uint16_t cofb;
- uint16_t corl;
- uint16_t cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[z3+1];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- uint64_t size;
- uint64_t (*index)(Cube);
- bool (*moveset)(Move);
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- int (*check)(Cube);
- int (*ready)(Cube);
- bool (*moveset)(Move);
- Trans pre_trans;
-};
diff --git a/old/2021-06-14-oldalg/main.c b/old/2021-06-14-oldalg/main.c
@@ -1,56 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 2, nrand = 100000, sum;
-
- Step *stps[20] = {&drud_HTM, &optimal_HTM};
- char sss[30][30] = {"DR on U/D", "Optimal solution"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true
- };
-
- init();
-
-/*
- print_ptable(&pd_drud_HTM);
- print_ptable(&pd_ep_HTM);
- print_ptable(&pd_corners_HTM);
-*/
-
- srand(time(NULL));
- sum = 0;
- for (i = 0; i < nrand; i++)
- sum += optimal_HTM.check(random_cube());
- printf("Average pruning value: %lf\n", ((double)sum) / ((double) nrand));
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- for (i = 0; i < ns; i++) {
- if (stps[i]->check == NULL)
- fprintf(stderr, "Check function for step %d is null\n", i);
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free(algo);
- }
-
- return 0;
-}
diff --git a/old/2021-06-15-before-separating-steps/cube.c b/old/2021-06-15-before-separating-steps/cube.c
@@ -1,2836 +0,0 @@
-#include "cube.h"
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define BASEALGLEN 50
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-#define PTABLESIZE(n) ((n+1) / 2)
-#define PTABLEVAL(tab,ind) (((ind)%2) ? (tab[(ind)/2] / 16) : \
- (tab[(ind)/2] % 16))
-
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static uint16_t array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static Move base_move(Move m);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent(int pos1, int pos2);
-static uint16_t epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(uint16_t epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void generate_ptable(PruneData *pd);
-static void generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void moveset_to_list(bool (*ms)(Move), int (*f)(Cube), Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_set_reached(PruneData *pd, uint64_t ind);
-static void ptable_update(PruneData *pd, uint64_t ind, int m);
-static bool read_ptable_file(PruneData *pd);
-static bool read_ttables_file();
-static bool read_mtables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static void solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_ptable_file(PruneData *pd);
-static bool write_ttables_file();
-static bool write_mtables_file();
-
-static void init_auxtables();
-static void init_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_steps();
-static void init_strings();
-static void init_trans();
-static void init_trans_aux();
-
-static bool moveset_HTM(Move m);
-static bool moveset_URF(Move m);
-
-/* Steps and related functions and data **************************************/
-
-Step eofb_HTM;
-Step eorl_HTM;
-Step eoud_HTM;
-Step coud_HTM;
-Step corl_HTM;
-Step cofb_HTM;
-Step coud_URF;
-Step corl_URF;
-Step cofb_URF;
-Step corners_HTM;
-Step corners_URF;
-Step edges_HTM;
-Step drud_HTM;
-Step optimal_HTM;
-
-PruneData pd_eofb_HTM;
-PruneData pd_coud_HTM;
-PruneData pd_corners_HTM;
-PruneData pd_ep_HTM;
-PruneData pd_drud_HTM;
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_ep(Cube cube);
-static uint64_t index_drud(Cube cube);
-
-static int check_nothing(Cube cube);
-static int check_eofb_HTM(Cube cube);
-static int check_coud_HTM(Cube cube);
-static int check_coud_URF(Cube cube);
-static int check_corners_HTM(Cube cube);
-static int check_corners_URF(Cube cube);
-static int check_edges_HTM(Cube cube);
-static int check_drud_HTM(Cube cube);
-static int check_optimal_HTM(Cube cube);
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-
-static uint16_t epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eo_ttable[NTRANS][POW2TO11];
-static uint16_t cp_ttable[NTRANS][FACTORIAL8];
-static uint16_t co_ttable[NTRANS][POW3TO7];
-static uint16_t cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static uint16_t epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eofb_mtable[NMOVES][POW2TO11];
-static uint16_t eorl_mtable[NMOVES][POW2TO11];
-static uint16_t eoud_mtable[NMOVES][POW2TO11];
-static uint16_t cp_mtable[NMOVES][FACTORIAL8];
-static uint16_t coud_mtable[NMOVES][POW3TO7];
-static uint16_t cofb_mtable[NMOVES][POW3TO7];
-static uint16_t corl_mtable[NMOVES][POW3TO7];
-static uint16_t cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * trans_algs[NROTATIONS];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated) {
- if (alg->len > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might be wrong.\n");
- }
- alg->move = realloc(alg->move, 2 * alg->len * sizeof(Move));
- alg->inv = realloc(alg->inv, 2 * alg->len * sizeof(bool));
- alg->allocated *= 2;
- }
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static uint16_t
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 1)
- ep8[j++] = (edge_slice(ep[i]) == 0) ? 1 : 0;
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static uint16_t
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(uint16_t epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-generate_ptable(PruneData *pd)
-{
- uint64_t j;
- DfsData dd;
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- dd.m = 0;
- dd.last1 = NULLMOVE;
- dd.last2 = NULLMOVE;
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->size; j++)
- ptable_update(pd, j, 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
-
- pd->reached = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->size; dd.d++) {
- memset(pd->reached, 0, PTABLESIZE(pd->size)*sizeof(uint8_t));
- generate_ptable_dfs((Cube){0}, pd, &dd);
- fprintf(stderr, "Depth %d completed, generated %lu/%lu\n",
- dd.d, pd->n, pd->size);
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-static void
-generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- uint64_t ind = pd->index(c);
- int oldval = PTABLEVAL(pd->ptable, ind);
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- if (oldval < dd->m || PTABLEVAL(pd->reached, ind) || pd->n == pd->size)
- return;
-
- ptable_set_reached(pd, ind);
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, ind, dd->m);
- return;
- }
-
- dd->m++;
- dd->last2 = dd->last1;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (possible_next[l2][l1][move]) {
- dd->last1 = move;
- generate_ptable_dfs(apply_move(move, c), pd, dd);
- }
- }
-
- dd->m--;
- dd->last1 = l1;
- dd->last2 = l2;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-moveset_to_list(bool (*ms)(Move m), int (*f)(Cube), Move *r)
-{
- Cube c;
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- c = apply_move(i, (Cube){0});
- if (f != NULL && f(c))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0; /* Truncate */
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_set_reached(PruneData *pd, uint64_t ind)
-{
- uint8_t oldval2 = pd->reached[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = ind % 2 ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = ind % 2 ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return r == PTABLESIZE(pd->size);
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(uint16_t);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Alg *inv;
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Cube ret;
-
- if (r != mirror) {
- ret = apply_alg_generic(trans_algs[r], c, f, true);
- inv = on_inverse(trans_algs[r]);
- ret = apply_alg_generic(inv, ret, f, true);
- free_alg(inv);
- } else {
- ret = move_via_arrays(&ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(&ma, ret, f);
- }
-
- return ret;
-}
-
-static void
-solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move move, l1 = dd->last1, l2 = dd->last2;
- int i, lower_bound = s.check(c);
- bool found_many, prune, niss_make_sense, nissbackup = dd->niss;
-
- if (opts->can_niss && !dd->niss)
- lower_bound = MIN(1, lower_bound);
-
- found_many = dd->sols->len >= opts->max_solutions;
- prune = dd->current_alg->len + lower_bound > dd->d;
- if (found_many || prune)
- return;
-
- if (lower_bound == 0) {
- if (dd->current_alg->len == dd->d)
- append_alg(dd->sols, dd->current_alg);
- return;
- }
-
- dd->last2 = dd->last1;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (possible_next[l2][l1][move]) {
- dd->last1 = move;
- append_move(dd->current_alg, move, dd->niss);
- solve_dfs(apply_move(move, c), s, opts, dd);
- dd->current_alg->len--;
- }
- }
-
- niss_make_sense = !dd->current_alg->len ||
- (s.check(apply_move(l1,(Cube){0})));
- if (opts->can_niss && !dd->niss && niss_make_sense) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
- solve_dfs(inverse_cube(c), s, opts, dd);
- }
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = nissbackup;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return written == PTABLESIZE(pd->size);
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(uint16_t);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- uint64_t ui, uj;
- int i, j, k;
- bool cij, p1, p2;
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj] = epos_dependent(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2);
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- uint16_t ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray){
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_steps()
-{
- /* PruneData */
- pd_eofb_HTM.filename = "ptable_eofb_HTM";
- pd_eofb_HTM.size = POW2TO11;
- pd_eofb_HTM.index = index_eofb;
- pd_eofb_HTM.moveset = moveset_HTM;
-
- pd_coud_HTM.filename = "ptable_coud_HTM";
- pd_coud_HTM.size = POW3TO7;
- pd_coud_HTM.index = index_coud;
- pd_coud_HTM.moveset = moveset_HTM;
-
- pd_corners_HTM.filename = "ptable_corners_HTM";
- pd_corners_HTM.size = POW3TO7 * FACTORIAL8;
- pd_corners_HTM.index = index_corners;
- pd_corners_HTM.moveset = moveset_HTM;
-
- pd_ep_HTM.filename = "ptable_ep_HTM";
- pd_ep_HTM.size = FACTORIAL12;
- pd_ep_HTM.index = index_ep;
- pd_ep_HTM.moveset = moveset_HTM;
-
- pd_drud_HTM.filename = "ptable_drud_HTM";
- pd_drud_HTM.size = POW2TO11 * POW3TO7 * BINOM12ON4;
- pd_drud_HTM.index = index_drud;
- pd_drud_HTM.moveset = moveset_HTM;
-
-
- /* Actual steps */
- eofb_HTM.check = check_eofb_HTM;
- eofb_HTM.ready = check_nothing;
- eofb_HTM.pre_trans = uf;
- eofb_HTM.moveset = moveset_HTM;
-
- eorl_HTM.check = check_eofb_HTM;
- eorl_HTM.ready = check_nothing;
- eorl_HTM.pre_trans = ur;
- eorl_HTM.moveset = moveset_HTM;
-
- eoud_HTM.check = check_eofb_HTM;
- eoud_HTM.ready = check_nothing;
- eoud_HTM.pre_trans = bu;
- eoud_HTM.moveset = moveset_HTM;
-
-
- coud_HTM.check = check_coud_HTM;
- coud_HTM.ready = check_nothing;
- coud_HTM.pre_trans = uf;
- coud_HTM.moveset = moveset_HTM;
-
- corl_HTM.check = check_coud_HTM;
- corl_HTM.ready = check_nothing;
- corl_HTM.pre_trans = rf;
- corl_HTM.moveset = moveset_HTM;
-
- cofb_HTM.check = check_coud_HTM;
- cofb_HTM.ready = check_nothing;
- cofb_HTM.pre_trans = fd;
- cofb_HTM.moveset = moveset_HTM;
-
- coud_URF.check = check_coud_URF;
- coud_URF.ready = check_nothing;
- coud_URF.pre_trans = uf;
- coud_URF.moveset = moveset_URF;
-
- corl_URF.check = check_coud_URF;
- corl_URF.ready = check_nothing;
- corl_URF.pre_trans = rf;
- corl_URF.moveset = moveset_URF;
-
- cofb_URF.check = check_coud_URF;
- cofb_URF.ready = check_nothing;
- cofb_URF.pre_trans = fd;
- cofb_URF.moveset = moveset_URF;
-
- corners_HTM.check = check_corners_HTM;
- corners_HTM.ready = check_nothing;
- corners_HTM.pre_trans = uf;
- corners_HTM.moveset = moveset_HTM;
-
- corners_URF.check = check_corners_URF;
- corners_URF.ready = check_nothing;
- corners_URF.pre_trans = uf;
- corners_URF.moveset = moveset_URF;
-
- edges_HTM.check = check_edges_HTM;
- edges_HTM.ready = check_nothing;
- edges_HTM.pre_trans = uf;
- edges_HTM.moveset = moveset_HTM;
-
- drud_HTM.check = check_drud_HTM;
- drud_HTM.ready = check_nothing;
- drud_HTM.pre_trans = uf;
- drud_HTM.moveset = moveset_HTM;
-
- optimal_HTM.check = check_optimal_HTM;
- optimal_HTM.ready = check_nothing;
- optimal_HTM.pre_trans = uf;
- optimal_HTM.moveset = moveset_HTM;
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- bool b1, b2, b3;
- uint16_t ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(trans_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- memcpy(eparr, ep_mirror, 12 * sizeof(int));
- memcpy(cparr, cp_mirror, 8 * sizeof(int));
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(trans_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_ttable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_ttable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_ttable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_ttable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- trans_algs[uf] = new_alg("");
- trans_algs[ur] = new_alg("y");
- trans_algs[ub] = new_alg("y2");
- trans_algs[ul] = new_alg("y3");
-
- trans_algs[df] = new_alg("z2");
- trans_algs[dr] = new_alg("y z2");
- trans_algs[db] = new_alg("x2");
- trans_algs[dl] = new_alg("y3 z2");
-
- trans_algs[rf] = new_alg("z3");
- trans_algs[rd] = new_alg("z3 y");
- trans_algs[rb] = new_alg("z3 y2");
- trans_algs[ru] = new_alg("z3 y3");
-
- trans_algs[lf] = new_alg("z");
- trans_algs[ld] = new_alg("z y3");
- trans_algs[lb] = new_alg("z y2");
- trans_algs[lu] = new_alg("z y");
-
- trans_algs[fu] = new_alg("x y2");
- trans_algs[fr] = new_alg("x y");
- trans_algs[fd] = new_alg("x");
- trans_algs[fl] = new_alg("x y3");
-
- trans_algs[bu] = new_alg("x3");
- trans_algs[br] = new_alg("x3 y");
- trans_algs[bd] = new_alg("x3 y2");
- trans_algs[bl] = new_alg("x3 y3");
-}
-
-/* Linearization functions implementation ************************************/
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_ep(Cube cube)
-{
- uint64_t a, b, c;
-
- /* TODO: remove this check */
- if (epos_dependent_aux[cube.eposs/FACTORIAL4][cube.epose/FACTORIAL4] ==BINOM8ON4)
- fprintf(stderr, "Impossible\n");
-
- a = cube.eposs;
- b = (cube.epose % FACTORIAL4) +
- epos_dependent_aux[cube.eposs/FACTORIAL4][cube.epose/FACTORIAL4] *
- FACTORIAL4;
- c = cube.eposm % FACTORIAL4;
-
- b *= FACTORIAL4 * BINOM12ON4;
- c *= FACTORIAL4 * BINOM12ON4 * FACTORIAL4 * BINOM8ON4;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-/* Step checking functions implementation ************************************/
-
-static int
-check_nothing(Cube cube)
-{
- return true;
-}
-
-static int
-check_eofb_HTM(Cube cube)
-{
- if (!pd_eofb_HTM.generated)
- generate_ptable(&pd_eofb_HTM);
-
- return PTABLEVAL(pd_eofb_HTM.ptable, cube.eofb);
-}
-
-static int
-check_coud_HTM(Cube cube)
-{
- if (!pd_coud_HTM.generated)
- generate_ptable(&pd_coud_HTM);
-
- return PTABLEVAL(pd_coud_HTM.ptable, cube.coud);
-}
-
-static int
-check_coud_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- int ud = check_coud_HTM(cube);
- int rl = check_coud_HTM(apply_move(z, cube));
- int fb = check_coud_HTM(apply_move(x, cube));
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-check_corners_HTM(Cube cube)
-{
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
-
- return PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
-}
-
-static int
-check_corners_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int ret = 15;
- Cube c;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- c = apply_alg(trans_algs[i], cube);
- ret = MIN(ret, check_corners_HTM(c));
- }
-
- return ret;
-}
-
-static int
-check_edges_HTM(Cube cube)
-{
- int ret = 0;
-
- if (!pd_ep_HTM.generated)
- generate_ptable(&pd_ep_HTM);
-
- ret = MAX(ret, PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)));
- ret = MAX(ret, check_eofb_HTM(cube));
- ret = MAX(ret, check_eofb_HTM(apply_trans(ur, cube)));
- ret = MAX(ret, check_eofb_HTM(apply_trans(fd, cube)));
-
- return ret;
-}
-
-static int
-check_drud_HTM(Cube cube)
-{
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
-
- return PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
-}
-
-static int
-check_optimal_HTM(Cube cube)
-{
- int dr1, dr2, dr3, drmax, cor; /*ep;*/
-
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
- /*
- *if (!pd_ep_HTM.generated)
- * generate_ptable(&pd_ep_HTM);
- */
-
- dr1 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
- dr2 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(rf, cube)));
- dr3 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(fd, cube)));
-
- drmax = MAX(dr1, MAX(dr2, dr3));
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- drmax++;
-
- cor = PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
- /* ep = PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)); */
-
- /*return MAX(drmax, MAX(ep, cor));*/
- if (drmax == 0 && cor == 0)
- return is_solved(cube, false) ? 0 : 1;
- return MAX(drmax, cor);
-}
-
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- Cube moved = {0};
-
- moved.epose = epose_mtable[m][cube.epose];
- moved.eposs = eposs_mtable[m][cube.eposs];
- moved.eposm = eposm_mtable[m][cube.eposm];
- moved.eofb = eofb_mtable[m][cube.eofb];
- moved.eorl = eorl_mtable[m][cube.eorl];
- moved.eoud = eoud_mtable[m][cube.eoud];
- moved.coud = coud_mtable[m][cube.coud];
- moved.cofb = cofb_mtable[m][cube.cofb];
- moved.corl = corl_mtable[m][cube.corl];
- moved.cp = cp_mtable[m][cube.cp];
- moved.cpos = cpos_mtable[m][cube.cpos];
-
- return moved;
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- Cube transformed = {0};
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- uint16_t aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- uint16_t aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- transformed.epose = epose_ttable[t][aux_epos[epose_source[t]]];
- transformed.eposs = eposs_ttable[t][aux_epos[eposs_source[t]]];
- transformed.eposm = eposm_ttable[t][aux_epos[eposm_source[t]]];
- transformed.eofb = eo_ttable[t][aux_eo[eofb_source[t]]];
- transformed.eorl = eo_ttable[t][aux_eo[eorl_source[t]]];
- transformed.eoud = eo_ttable[t][aux_eo[eoud_source[t]]];
- transformed.coud = co_ttable[t][aux_co[coud_source[t]]];
- transformed.corl = co_ttable[t][aux_co[corl_source[t]]];
- transformed.cofb = co_ttable[t][aux_co[cofb_source[t]]];
- transformed.cp = cp_ttable[t][cube.cp];
- transformed.cpos = cpos_ttable[t][cube.cpos];
-
- return transformed;
-}
-
-/* TODO: this has to be changed using pre-computations */
-bool
-block_solved(Cube cube, Block block)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- int i;
- bool ret = true;
-
- for (i = 0; i < 12; i++)
- ret = ret && !(block.edge[i] && (arr->ep[i] != i || arr->eofb[i]));
- for (i = 0; i < 8; i++)
- ret = ret && !(block.corner[i] && (arr->cp[i] != i || arr->coud[i]));
- for (i = 0; i < 6; i++)
- ret = ret && !(block.center[i] && arr->cpos[i] != i);
-
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-Center
-center_at(Cube cube, Center c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cpos);
-
- ret = arr->cpos[c];
- free_cubearray(arr, pf_cpos);
-
- return ret;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-Corner
-corner_at(Cube cube, Corner c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cp);
-
- ret = arr->cp[c];
- free_cubearray(arr, pf_cp);
-
- return ret;
-}
-
-Edge
-edge_at(Cube cube, Edge e)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
- free_cubearray(arr, pf_ep);
-
- return ret;
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- Trans i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(trans_algs[i],cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b;
- uint16_t x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c = apply_trans(step.pre_trans, cube);
- DfsData dd = {
- .m = 0,
- .niss = false,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(c))
- return sols;
-
- moveset_to_list(step.moveset, step.check, dd.sorted_moves);
-
- for (dd.d = MAX(opts->min_moves, step.check(c));
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- solve_dfs(c, step, opts, &dd);
- if (opts->feedback)
- fprintf(stderr,
- "Depth %d completed, found %d solutions\n",
- dd.d, sols->len);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[step.pre_trans], node->alg);
-
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, alg->move[i], alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- memset(a, 0, 16 * sizeof(uint64_t));
-
- if (!pd->generated)
- generate_ptable(pd);
-
- for (i = 0; i < pd->size; i++)
- a[PTABLEVAL(pd->ptable, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_trans_aux();
- init_trans();
- init_steps();
-}
-
-
diff --git a/old/2021-06-15-before-separating-steps/cube.h b/old/2021-06-15-before-separating-steps/cube.h
@@ -1,72 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "cubetypes.h"
-
-/* Steps *********************************************************************/
-
-extern Step eofb_HTM;
-extern Step eorl_HTM;
-extern Step eoud_HTM;
-extern Step coud_HTM;
-extern Step corl_HTM;
-extern Step cofb_HTM;
-extern Step coud_URF;
-extern Step corl_URF;
-extern Step cofb_URF;
-extern Step corners_HTM;
-extern Step corners_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Center center_at(Cube cube, Center c);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Corner corner_at(Cube cube, Corner c);
-Edge edge_at(Cube cube, Edge e);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-int piece_orientation(Cube cube, int piece, char *orientation);
-void print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-void transform_alg(Trans t, Alg *alg);
-
-void print_ptable(PruneData *pd);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-15-before-separating-steps/cubetypes.h b/old/2021-06-15-before-separating-steps/cubetypes.h
@@ -1,201 +0,0 @@
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cube
-{
- uint16_t epose;
- uint16_t eposs;
- uint16_t eposm;
- uint16_t eofb;
- uint16_t eorl;
- uint16_t eoud;
- uint16_t cp;
- uint16_t coud;
- uint16_t cofb;
- uint16_t corl;
- uint16_t cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[z3+1];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- uint64_t size;
- uint64_t (*index)(Cube);
- bool (*moveset)(Move);
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- int (*check)(Cube);
- int (*ready)(Cube);
- bool (*moveset)(Move);
- Trans pre_trans;
-};
diff --git a/old/2021-06-15-before-separating-steps/main.c b/old/2021-06-15-before-separating-steps/main.c
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 2, nrand = 100000, sum1, sum2;
-
- Step *stps[20] = {&drud_HTM, &optimal_HTM};
- char sss[30][30] = {"DR on U/D", "Optimal solution"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true
- };
-
- init();
-
-/*
- print_ptable(&pd_drud_HTM);
- print_ptable(&pd_ep_HTM);
- print_ptable(&pd_corners_HTM);
-*/
-
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- for (i = 0; i < nrand; i++) {
- sum1 += optimal_HTM.check(random_cube());
- sum2 += corners_HTM.check(random_cube());
- }
- printf("Average optimal pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners pruning: %lf\n", ((double)sum2) / ((double) nrand));
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- for (i = 0; i < ns; i++) {
- if (stps[i]->check == NULL)
- fprintf(stderr, "Check function for step %d is null\n", i);
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free(algo);
- }
-
- return 0;
-}
diff --git a/old/2021-06-15-before-separating-steps/steps.h b/old/2021-06-15-before-separating-steps/steps.h
@@ -1,20 +0,0 @@
-extern Step eofb_HTM;
-extern Step eorl_HTM;
-extern Step eoud_HTM;
-extern Step coud_HTM;
-extern Step corl_HTM;
-extern Step cofb_HTM;
-extern Step coud_URF;
-extern Step corl_URF;
-extern Step cofb_URF;
-extern Step corners_HTM;
-extern Step corners_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
diff --git a/old/2021-06-17-cachedata/cube.c b/old/2021-06-17-cachedata/cube.c
@@ -1,2738 +0,0 @@
-#include "cube.h"
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-#define PTABLESIZE(n) ((n+1) / 2)
-
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static bool allowed_next_move(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static uint16_t array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent(int pos1, int pos2);
-static uint16_t epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(uint16_t epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void generate_ctable_dfs(Cube c, CacheData *cd, DfsData *dd);
-static void generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Checker f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-/*static int powint(int a, int b);*/
-static void ptable_set_reached(PruneData *pd, uint64_t ind);
-static void ptable_update(PruneData *pd, uint64_t ind, int m);
-static void push_cachenode(CacheData *cd, Cube c, Alg *alg);
-static void realloc_alg(Alg *alg, int n);
-static bool read_ctable_file(CacheData *cd);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static void solve_cd(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_ctable_file(CacheData *cd);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_ttables_file();
-
-static void init_auxtables();
-static void init_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_trans();
-static void init_trans_aux();
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-
-static uint16_t epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eo_ttable[NTRANS][POW2TO11];
-static uint16_t cp_ttable[NTRANS][FACTORIAL8];
-static uint16_t co_ttable[NTRANS][POW3TO7];
-static uint16_t cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static uint16_t epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eofb_mtable[NMOVES][POW2TO11];
-static uint16_t eorl_mtable[NMOVES][POW2TO11];
-static uint16_t eoud_mtable[NMOVES][POW2TO11];
-static uint16_t cp_mtable[NMOVES][FACTORIAL8];
-static uint16_t coud_mtable[NMOVES][POW3TO7];
-static uint16_t cofb_mtable[NMOVES][POW3TO7];
-static uint16_t corl_mtable[NMOVES][POW3TO7];
-static uint16_t cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * trans_algs[NROTATIONS];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static bool
-allowed_next_move(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static uint16_t
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 1)
- ep8[j++] = (edge_slice(ep[i]) == 0) ? 1 : 0;
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static uint16_t
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(uint16_t epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-generate_ctable_dfs(Cube c, CacheData *cd, DfsData *dd)
-{
- int i;
- bool flag;
- Move move, l1 = dd->last1, l2 = dd->last2;
-
- if (dd->current_alg->len > 0) {
- for (i = 0, flag = true; i < cd->nind; i++) {
- if (cd->index[i](c) != cd->index[i]((Cube){0})) {
- flag = false;
- break;
- }
- }
- if (flag)
- return;
- }
-
- if (dd->current_alg->len == dd->d) {
- push_cachenode(cd, c, dd->current_alg);
- return;
- }
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next_move(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
- append_move(dd->current_alg, move, false);
- generate_ctable_dfs(apply_move(move, c), cd, dd);
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static void
-generate_ptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- uint64_t ind = pd->index(c);
- int oldval = PTABLEVAL(pd->ptable, ind);
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- if (oldval < dd->m || PTABLEVAL(pd->reached, ind) || pd->n == pd->size)
- return;
-
- ptable_set_reached(pd, ind);
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, ind, dd->m);
- return;
- }
-
- dd->m++;
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next_move(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
- generate_ptable_dfs(apply_move(move, c), pd, dd);
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
- dd->last1 = l1;
- dd->last2 = l2;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(bool (*ms)(Move m), int (*f)(Cube), Move *r)
-{
- Cube c;
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- c = apply_move(i, (Cube){0});
- if (f != NULL && f(c))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-/*
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-*/
-
-static void
-ptable_set_reached(PruneData *pd, uint64_t ind)
-{
- uint8_t oldval2 = pd->reached[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = ind % 2 ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = ind % 2 ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-push_cachenode(CacheData *cd, Cube c, Alg *alg)
-{
- CacheNode *node = malloc(sizeof(CacheNode));
- uint64_t ind0 = cd->index[0](c);
- int i;
-
- node->indexval = malloc((cd->nind - 1) * sizeof(uint64_t));
- for (i = 1; i < cd->nind; i++)
- node->indexval[i-1] = cd->index[i](c);
-
- node->sol = inverse_alg(alg);
- realloc_alg(node->sol, cd->len);
- node->next = cd->ctable[ind0];
- cd->ctable[ind0] = node;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n);
- alg->inv = realloc(alg->inv, n);
- alg->allocated = n;
-}
-
-static bool
-read_ctable_file(CacheData *cd)
-{
- return false;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return r == PTABLESIZE(pd->size);
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(uint16_t);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Alg *inv;
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Cube ret;
-
- if (r != mirror) {
- ret = apply_alg_generic(trans_algs[r], c, f, true);
- inv = on_inverse(trans_algs[r]);
- ret = apply_alg_generic(inv, ret, f, true);
- free_alg(inv);
- } else {
- ret = move_via_arrays(&ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(&ma, ret, f);
- }
-
- return ret;
-}
-
-static void
-solve_cd(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- int j, k;
- bool flag;
- uint64_t ind0;
- CacheNode *i;
-
- if (!s.cd->generated)
- generate_ctable(s.cd);
-
- ind0 = s.cd->index[0](c);
- for (i = s.cd->ctable[ind0];
- i != NULL && dd->sols->len < opts->max_solutions;
- i = i->next) {
- for (j = 1, flag = true; j < s.cd->nind; j++) {
- if (s.cd->index[j](c) != i->indexval[j-1]) {
- flag = false;
- break;
- }
- }
- if (flag) {
- for (k = 0; k < s.cd->len; k++)
- append_move(dd->current_alg,
- i->sol->move[k], dd->niss);
- append_alg(dd->sols, dd->current_alg);
- if (opts->feedback) {
- printf("[cached] ");
- print_alg(dd->current_alg, false);
- }
- }
- }
-}
-
-static void
-solve_dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move move, l1 = dd->last1, l2 = dd->last2;
- int i, lower_bound;
- bool nissbackup = dd->niss;
-
- if (dd->sols->len >= opts->max_solutions)
- return;
-
- lower_bound = s.check(c);
- if (opts->can_niss && !dd->niss)
- lower_bound = MIN(1, lower_bound);
-
- if (dd->current_alg->len + lower_bound > dd->d)
- return;
-
- if (lower_bound == 0) {
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
- return;
- }
-
- if (s.cd != NULL && s.cd->len == dd->d - dd->current_alg->len) {
- solve_cd(c, s, opts, dd);
- } else {
- for (i = 0;
- dd->sorted_moves[i] != NULLMOVE &&
- dd->sols->len < opts->max_solutions;
- i++) {
- move = dd->sorted_moves[i];
- if (allowed_next_move(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
- append_move(dd->current_alg, move, dd->niss);
- solve_dfs(apply_move(move, c), s, opts, dd);
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
- }
-
- if (opts->can_niss && !dd->niss) {
- if (dd->current_alg->len == 0 ||
- (s.check(apply_move(inverse_move(l1), (Cube){0})))) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
- solve_dfs(inverse_cube(c), s, opts, dd);
- }
- }
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = nissbackup;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_ctable_file(CacheData *cd)
-{
- return false;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), PTABLESIZE(pd->size), f);
- fclose(f);
-
- return written == PTABLESIZE(pd->size);
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(uint16_t);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- uint64_t ui, uj;
- int i, j, k;
- bool cij, p1, p2;
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj] = epos_dependent(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- uint16_t ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- bool b1, b2, b3;
- uint16_t ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(trans_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(edge_at(cube, FR));
- eposs_source[i] = edge_slice(edge_at(cube, UR));
- eposm_source[i] = edge_slice(edge_at(cube, UF));
- eofb_source[i] = center_at(cube, F_center)/2;
- eorl_source[i] = center_at(cube, R_center)/2;
- eoud_source[i] = center_at(cube, U_center)/2;
- coud_source[i] = center_at(cube, U_center)/2;
- cofb_source[i] = center_at(cube, F_center)/2;
- corl_source[i] = center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- memcpy(eparr, ep_mirror, 12 * sizeof(int));
- memcpy(cparr, cp_mirror, 8 * sizeof(int));
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(trans_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_ttable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_ttable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_ttable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_ttable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- trans_algs[uf] = new_alg("");
- trans_algs[ur] = new_alg("y");
- trans_algs[ub] = new_alg("y2");
- trans_algs[ul] = new_alg("y3");
-
- trans_algs[df] = new_alg("z2");
- trans_algs[dr] = new_alg("y z2");
- trans_algs[db] = new_alg("x2");
- trans_algs[dl] = new_alg("y3 z2");
-
- trans_algs[rf] = new_alg("z3");
- trans_algs[rd] = new_alg("z3 y");
- trans_algs[rb] = new_alg("z3 y2");
- trans_algs[ru] = new_alg("z3 y3");
-
- trans_algs[lf] = new_alg("z");
- trans_algs[ld] = new_alg("z y3");
- trans_algs[lb] = new_alg("z y2");
- trans_algs[lu] = new_alg("z y");
-
- trans_algs[fu] = new_alg("x y2");
- trans_algs[fr] = new_alg("x y");
- trans_algs[fd] = new_alg("x");
- trans_algs[fl] = new_alg("x y3");
-
- trans_algs[bu] = new_alg("x3");
- trans_algs[br] = new_alg("x3 y");
- trans_algs[bd] = new_alg("x3 y2");
- trans_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- uint16_t aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- uint16_t aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-/* TODO: this has to be changed using pre-computations */
-bool
-block_solved(Cube cube, Block block)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- int i;
- bool ret = true;
-
- for (i = 0; i < 12; i++)
- ret = ret && !(block.edge[i] && (arr->ep[i] != i || arr->eofb[i]));
- for (i = 0; i < 8; i++)
- ret = ret && !(block.corner[i] && (arr->cp[i] != i || arr->coud[i]));
- for (i = 0; i < 6; i++)
- ret = ret && !(block.center[i] && arr->cpos[i] != i);
-
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-Center
-center_at(Cube cube, Center c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cpos);
-
- ret = arr->cpos[c];
- free_cubearray(arr, pf_cpos);
-
- return ret;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-Corner
-corner_at(Cube cube, Corner c)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_cp);
-
- ret = arr->cp[c];
- free_cubearray(arr, pf_cp);
-
- return ret;
-}
-
-Edge
-edge_at(Cube cube, Edge e)
-{
- int ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
- free_cubearray(arr, pf_ep);
-
- return ret;
-}
-
-uint64_t
-epos_dependent_cube(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-generate_ctable(CacheData *cd)
-{
- uint64_t i;
- DfsData dd = {
- .d = cd->len,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .current_alg = new_alg("")
- };
-
- if (cd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- cd->ctable = malloc(cd->maxind0 * sizeof(CacheNode *));
- for (i = 0; i < cd->maxind0; i++)
- cd->ctable[i] = NULL;
-
- if (read_ctable_file(cd)) {
- cd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", cd->filename);
-
- moveset_to_list(cd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- generate_ctable_dfs((Cube){0}, cd, &dd);
-
- if (!write_ctable_file(cd))
- fprintf(stderr, "Error writing ctable file\n");
-
- cd->generated = true;
-}
-
-void
-generate_ptable(PruneData *pd)
-{
- uint64_t j;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->size; j++)
- ptable_update(pd, j, 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- pd->reached = malloc(PTABLESIZE(pd->size) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->size; dd.d++) {
- memset(pd->reached, 0, PTABLESIZE(pd->size)*sizeof(uint8_t));
- generate_ptable_dfs((Cube){0}, pd, &dd);
- fprintf(stderr, "Depth %d completed, generated %lu/%lu\n",
- dd.d, pd->n, pd->size);
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- Trans i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(trans_algs[i],cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b;
- uint16_t x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c = apply_trans(opts->pre_trans, cube);
- DfsData dd = {
- .m = 0,
- .niss = false,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(c)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.check, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = MAX(opts->min_moves, step.check(c));
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- solve_dfs(c, step, opts, &dd);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[opts->pre_trans], node->alg);
-
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, alg->move[i], alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_cachedata(CacheData *cd, bool printalgs)
-{
- CacheNode *j;
- uint64_t i, s, maxa = 0, maxs = 0, n = 0, empty = 0;
-
- if (!cd->generated)
- generate_ctable(cd);
-
- for (i = 0; i < cd->maxind0; i++) {
- if (cd->ctable[i] == NULL) {
- empty++;
- continue;
- }
-
- for (j = cd->ctable[i], s = 0;
- j != NULL; j = j->next, n++, s++)
- if (printalgs)
- print_alg(j->sol, false);
-
- if (s > maxs) {
- maxs = s;
- maxa = i;
- }
- }
-
- printf("Cache data %s\n", cd->filename);
- printf("Length: %d\n", cd->len);
- printf("Main table cells: %lu (of which %lu empty)\n", i, empty);
- printf("%lu solutions cached ", n);
- printf("(most crowded cell: %lu with %lu)\n", maxa, maxs);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- generate_ptable(pd);
-
- for (i = 0; i < pd->size; i++)
- a[PTABLEVAL(pd->ptable, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-
-Alg *
-trans_alg(Trans i)
-{
- return trans_algs[i];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_trans_aux();
- init_trans();
-}
-
diff --git a/old/2021-06-17-cachedata/cube.h b/old/2021-06-17-cachedata/cube.h
@@ -1,79 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-#define PTABLESIZE(n) ((n+1) / 2)
-#define PTABLEVAL(t,i) (((i)%2) ? (t[(i)/2] / 16) : (t[(i)/2] % 16))
-
-/* Type definitions **********************************************************/
-
-#include "cubetypes.h"
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Center center_at(Cube cube, Center c);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Corner corner_at(Cube cube, Corner c);
-Edge edge_at(Cube cube, Edge e);
-uint64_t epos_dependent_cube(Cube cube);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-int piece_orientation(Cube cube, int piece, char *orientation);
-void print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * trans_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void generate_ctable(CacheData *cd);
-void generate_ptable(PruneData *pd);
-void print_cachedata(CacheData *cd, bool printalgs);
-void print_ptable(PruneData *pd);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-17-cachedata/cubetypes.h b/old/2021-06-17-cachedata/cubetypes.h
@@ -1,232 +0,0 @@
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct cachedata CacheData;
-typedef struct cachenode CacheNode;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-typedef int (*Checker)(Cube);
-typedef uint64_t (*Indexer)(Cube);
-typedef bool (*Moveset)(Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cachedata
-{
- char * filename;
- CacheNode ** ctable;
- bool generated;
- uint64_t maxind0;
- int len;
- int nind;
- Indexer index[20]; /* Should be enough */
- Checker check;
- Moveset moveset;
-};
-
-struct
-cachenode
-{
- uint64_t * indexval;
- Alg * sol;
- CacheNode * next;
-};
-
-struct
-cube
-{
- uint16_t epose;
- uint16_t eposs;
- uint16_t eposm;
- uint16_t eofb;
- uint16_t eorl;
- uint16_t eoud;
- uint16_t cp;
- uint16_t coud;
- uint16_t cofb;
- uint16_t corl;
- uint16_t cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- uint64_t size;
- Indexer index;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
- Trans pre_trans;
-};
-
-struct
-step
-{
- Checker check;
- Checker ready;
- Moveset moveset;
- CacheData * cd;
-};
diff --git a/old/2021-06-17-cachedata/main.c b/old/2021-06-17-cachedata/main.c
@@ -1,63 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 3; /*, nrand = 100000, sum1, sum2;*/
-
- Step *stps[20] = {&eofb_HTM, &corners_URF, &optimal_HTM};
- char sss[30][30] = {"EO on F/B", "Corners URF", "Optimal solution"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- .pre_trans = uf
- };
-
- init();
-
-/*
- print_ptable(&pd_corners_HTM);
-
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- for (i = 0; i < nrand; i++) {
- sum1 += optimal_HTM.check(random_cube());
- sum2 += corners_HTM.check(random_cube());
- }
- printf("Average optimal pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners pruning: %lf\n", ((double)sum2) / ((double) nrand));
-*/
-
- print_cachedata(&cd_optimal_HTM_6, false);
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- for (i = 0; i < ns; i++) {
- if (stps[i]->check == NULL)
- fprintf(stderr, "Check function for step %d is null\n", i);
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-06-17-cachedata/steps.c b/old/2021-06-17-cachedata/steps.c
@@ -1,327 +0,0 @@
-#include "steps.h"
-
-/* Check functions ***********************************************************/
-
-static int check_nothing(Cube cube);
-static int check_eofb_HTM(Cube cube);
-static int check_coud_HTM(Cube cube);
-static int check_coud_URF(Cube cube);
-static int check_corners_HTM(Cube cube);
-static int check_corners_URF(Cube cube);
-static int check_edges_HTM(Cube cube);
-static int check_drud_HTM(Cube cube);
-static int check_optimal_HTM(Cube cube);
-
-
-/* Index functions ***********************************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_ep(Cube cube);
-static uint64_t index_drud(Cube cube);
-
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .check = check_eofb_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .check = check_coud_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .check = check_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .check = check_corners_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM
-};
-
-Step
-corners_URF = {
- .check = check_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-edges_HTM = {
- .check = check_edges_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM
-};
-
-Step
-drud_HTM = {
- .check = check_drud_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .check = check_optimal_HTM,
- .ready = check_nothing,
- .moveset = moveset_HTM,
- .cd = &cd_optimal_HTM_6
-};
-
-
-/* Cache solutions ***********************************************************/
-
-CacheData
-cd_optimal_HTM_6 = {
- .filename = "cd_optimal_HTM_6",
- .maxind0 = POW3TO7 * FACTORIAL8,
- .len = 6,
- .nind = 3,
- .index = { index_corners, index_eofb, index_ep },
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .size = POW2TO11,
- .index = index_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .size = POW3TO7,
- .index = index_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .size = POW3TO7 * FACTORIAL8,
- .index = index_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_ep_HTM = {
- .filename = "ptable_ep_HTM",
- .size = FACTORIAL12,
- .index = index_ep,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .size = POW2TO11 * POW3TO7 * BINOM12ON4,
- .index = index_drud,
- .moveset = moveset_HTM
-};
-
-
-/* Check functions implementation ********************************************/
-
-static int
-check_nothing(Cube cube)
-{
- /* At least we check that it is admissible */
- return is_admissible(cube);
-}
-
-static int
-check_eofb_HTM(Cube cube)
-{
- if (!pd_eofb_HTM.generated)
- generate_ptable(&pd_eofb_HTM);
-
- return PTABLEVAL(pd_eofb_HTM.ptable, cube.eofb);
-}
-
-static int
-check_coud_HTM(Cube cube)
-{
- if (!pd_coud_HTM.generated)
- generate_ptable(&pd_coud_HTM);
-
- return PTABLEVAL(pd_coud_HTM.ptable, cube.coud);
-}
-
-static int
-check_coud_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- int ud = check_coud_HTM(cube);
- int rl = check_coud_HTM(apply_move(z, cube));
- int fb = check_coud_HTM(apply_move(x, cube));
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-check_corners_HTM(Cube cube)
-{
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
-
- return PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
-}
-
-static int
-check_corners_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++)
- ret = MIN(ret,check_corners_HTM(apply_alg(trans_alg(i),cube)));
-
- return ret;
-}
-
-static int
-check_edges_HTM(Cube cube)
-{
- int ret = 0;
-
- if (!pd_ep_HTM.generated)
- generate_ptable(&pd_ep_HTM);
-
- ret = MAX(ret, PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)));
- ret = MAX(ret, check_eofb_HTM(cube));
- ret = MAX(ret, check_eofb_HTM(apply_trans(ur, cube)));
- ret = MAX(ret, check_eofb_HTM(apply_trans(fd, cube)));
-
- return ret;
-}
-
-static int
-check_drud_HTM(Cube cube)
-{
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
-
- return PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
-}
-
-static int
-check_optimal_HTM(Cube cube)
-{
- int dr1, dr2, dr3, drmax, cor; /*ep;*/
-
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
- /*
- *if (!pd_ep_HTM.generated)
- * generate_ptable(&pd_ep_HTM);
- */
-
- dr1 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
- dr2 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(rf, cube)));
- dr3 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(fd, cube)));
-
- drmax = MAX(dr1, MAX(dr2, dr3));
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- drmax++;
-
- cor = PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
- /* ep = PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)); */
-
- /*return MAX(drmax, MAX(ep, cor));*/
- if (drmax == 0 && cor == 0)
- return is_solved(cube, false) ? 0 : 1;
- return MAX(drmax, cor);
-}
-
-
-/* Index functions implementation ********************************************/
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_ep(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eposs;
- b = (cube.epose % FACTORIAL4) + epos_dependent_cube(cube)*FACTORIAL4;
- c = cube.eposm % FACTORIAL4;
-
- b *= FACTORIAL4 * BINOM12ON4;
- c *= FACTORIAL4 * BINOM12ON4 * FACTORIAL4 * BINOM8ON4;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
diff --git a/old/2021-06-17-cachedata/steps.h b/old/2021-06-17-cachedata/steps.h
@@ -1,34 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-/* Steps *********************************************************************/
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step corners_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-/* Cache solutions ***********************************************************/
-
-extern CacheData cd_optimal_HTM_6;
-
-/* Pruning tables ************************************************************/
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
-
-/* Movesets ******************************************************************/
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-#endif
diff --git a/old/2021-06-23-realizing-bad-tables/HERE b/old/2021-06-23-realizing-bad-tables/HERE
@@ -1 +0,0 @@
-Here you can also find some tables data that I have removed, like ep and tripleeo
diff --git a/old/2021-06-23-realizing-bad-tables/cube.c b/old/2021-06-23-realizing-bad-tables/cube.c
@@ -1,2844 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Checker f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static bool ptable_has_reached(PruneData *pd, uint64_t ind);
-static void ptable_set_reached(PruneData *pd, uint64_t ind);
-static void ptable_update(PruneData *pd, uint64_t ind, int m);
-static void realloc_alg(Alg *alg, int n);
-static bool read_algset_file(AlgSet *as);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_algset_file(AlgSet *as);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_ttables_file();
-
-static void init_auxtables();
-static void init_cphtr_cosets();
-static void init_cphtr_cosets_bfs(int i, int c);
-static void init_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_trans();
-static void init_trans_aux();
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_cosets[FACTORIAL8];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * trans_algs[NROTATIONS];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; (m=moves[i]) != NULLMOVE && dd->sols->len < maxnsol; i++) {
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
-
- if (dd->current_alg->len == 0 ||
- (s.check(apply_move(inverse_move(l1), (Cube){0}), 1))) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.check(c, dd->d - dd->current_alg->len);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- uint64_t ind = pd->index(c);
- int oldval = ptableval(pd, ind);
-
- if (oldval < dd->m || ptable_has_reached(pd, ind) || pd->n == pd->size)
- return;
-
- ptable_set_reached(pd, ind);
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, ind, dd->m);
- return;
- }
-
- genptable_dfs_branch(c, pd, dd);
-}
-
-static void
-genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd)
-{
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- dd->m++;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
-
- genptable_dfs(apply_move(move, c), pd, dd);
-
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Checker f, Move *r)
-{
- Cube c;
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- c = apply_move(i, (Cube){0});
- if (f != NULL && f(c, 1))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static bool
-ptable_has_reached(PruneData *pd, uint64_t ind)
-{
- return (ind % 2) ? pd->reached[ind/2] / 16 : pd->reached[ind/2] % 16;
-}
-
-static void
-ptable_set_reached(PruneData *pd, uint64_t ind)
-{
- uint8_t oldval2 = pd->reached[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = (ind % 2) ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_algset_file(AlgSet *as)
-{
- return false;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Alg *inv;
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Cube ret;
-
- if (r != mirror) {
- ret = apply_alg_generic(trans_algs[r], c, f, true);
- inv = on_inverse(trans_algs[r]);
- ret = apply_alg_generic(inv, ret, f, true);
- free_alg(inv);
- } else {
- ret = move_via_arrays(&ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(&ma, ret, f);
- }
-
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_algset_file(AlgSet *as)
-{
- return false;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the cosets for cphtr.
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0;
-
- for (i = 0; i < FACTORIAL8; i++)
- cphtr_cosets[i] = -1;
-
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_cosets[i] == -1)
- init_cphtr_cosets_bfs(i, c++);
-}
-
-static void
-init_cphtr_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_cosets[jj] == -1) {
- cphtr_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- unsigned int ui;
- bool b1, b2, b3;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(trans_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- memcpy(eparr, ep_mirror, 12 * sizeof(int));
- memcpy(cparr, cp_mirror, 8 * sizeof(int));
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(trans_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_ttable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_ttable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_ttable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_ttable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- trans_algs[uf] = new_alg("");
- trans_algs[ur] = new_alg("y");
- trans_algs[ub] = new_alg("y2");
- trans_algs[ul] = new_alg("y3");
-
- trans_algs[df] = new_alg("z2");
- trans_algs[dr] = new_alg("y z2");
- trans_algs[db] = new_alg("x2");
- trans_algs[dl] = new_alg("y3 z2");
-
- trans_algs[rf] = new_alg("z3");
- trans_algs[rd] = new_alg("z3 y");
- trans_algs[rb] = new_alg("z3 y2");
- trans_algs[ru] = new_alg("z3 y3");
-
- trans_algs[lf] = new_alg("z");
- trans_algs[ld] = new_alg("z y3");
- trans_algs[lb] = new_alg("z y2");
- trans_algs[lu] = new_alg("z y");
-
- trans_algs[fu] = new_alg("x y2");
- trans_algs[fr] = new_alg("x y");
- trans_algs[fd] = new_alg("x");
- trans_algs[fl] = new_alg("x y3");
-
- trans_algs[bu] = new_alg("x3");
- trans_algs[br] = new_alg("x3 y");
- trans_algs[bd] = new_alg("x3 y2");
- trans_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_cosets[cube.cp];
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genalgset(AlgSet *as)
-{
- uint64_t i;
-
- if (as->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- as->table = malloc(as->size * sizeof(AlgList *));
-
- if (read_algset_file(as)) {
- as->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", as->filename);
-
- for (i = 0; i < as->size; i++) {
- as->table[i] = solve(as->antindex(i), as->step, &as->opts);
- fprintf(stderr, "Generated %lu / %lu cases\n", i, as->size);
- }
-
- if (!write_algset_file(as))
- fprintf(stderr, "Error writing algset file\n");
-
- as->generated = true;
-}
-
-void
-genptable(PruneData *pd)
-{
- uint64_t j;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->size; j++)
- ptable_update(pd, j, 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- pd->reached = malloc(ptablesize(pd) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->size; dd.d++) {
- memset(pd->reached, 0, ptablesize(pd)*sizeof(uint8_t));
- genptable_dfs((Cube){0}, pd, &dd);
- fprintf(stderr, "Depth %d completed, generated %lu/%lu\n",
- dd.d, pd->n, pd->size);
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- Trans i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(trans_algs[i],cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c = apply_trans(opts->pre_trans, cube);
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && step.ready(c, 1) != 0) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.check, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(c, step, opts, &dd);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[opts->pre_trans], node->alg);
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, alg->move[i], alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->size; i++)
- a[ptableval(pd, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->size + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, uint64_t ind)
-{
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-
-Alg *
-trans_alg(Trans i)
-{
- return trans_algs[i];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
-}
-
diff --git a/old/2021-06-23-realizing-bad-tables/cube.h b/old/2021-06-23-realizing-bad-tables/cube.h
@@ -1,88 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-
-/* Type definitions **********************************************************/
-
-#include "cubetypes.h"
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t cphtr(Cube cube);
-uint64_t epos_dependent(Cube cube);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * trans_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void genalgset(AlgSet *as);
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, uint64_t ind);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-23-realizing-bad-tables/cubetypes.h b/old/2021-06-23-realizing-bad-tables/cubetypes.h
@@ -1,224 +0,0 @@
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct algset AlgSet;
-typedef struct block Block;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef int (*Checker) (Cube, int);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- uint64_t size;
- Indexer index;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
- Trans pre_trans;
-};
-
-struct
-step
-{
- Checker check;
- Checker ready;
- Moveset moveset;
-};
-
-/* TODO: I put it here because it needs the definition of Step, sort it out */
-struct
-algset
-{
- char * filename;
- AlgList ** table;
- bool generated;
- uint64_t size;
- Indexer index;
- AntiIndexer antindex;
- Step step;
- SolveOptions opts;
-};
diff --git a/old/2021-06-23-realizing-bad-tables/main.c b/old/2021-06-23-realizing-bad-tables/main.c
@@ -1,70 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 3;
-/* int nrand = 10000, sum1, sum2, sum3;*/
-
- Step *stps[20] = {&corners_HTM, &eofb_HTM, &optimal_HTM};
- char sss[30][30] = {"Corners", "EO on F/B", "Optimal solution"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- .pre_trans = uf
- };
-
- init();
-
- print_ptable(&pd_corners_HTM);
-
-/*
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- sum3 = 0;
- for (i = 0; i < nrand; i++) {
- cube = random_cube();
- sum1 += corners_HTM.check(cube, 20);
- sum2 += cornershtr_HTM.check(cube, 20);
- sum3 += optimal_HTM.check(cube, 20);
- }
- printf("Average corners pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners htr pruning: %lf\n", ((double)sum2) / ((double) nrand));
- printf("Average optimal pruning: %lf\n", ((double)sum3) / ((double) nrand));
-*/
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- print_cube(cube);
- printf("Index: %lu\n", pd_cornershtr_HTM.index(cube));
-
- for (i = 0; i < ns; i++) {
- if (stps[i]->check == NULL)
- fprintf(stderr, "Check function for step %d is null\n", i);
- printf("Check: %d\n", stps[i]->check(cube, 20));
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free_alg(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-06-23-realizing-bad-tables/steps.c b/old/2021-06-23-realizing-bad-tables/steps.c
@@ -1,486 +0,0 @@
-#include "steps.h"
-
-/* Check functions ***********************************************************/
-
-static int check_nothing(Cube cube, int target);
-static int check_centers(Cube cube, int target);
-static int check_eofb_HTM(Cube cube, int target);
-static int check_coud_HTM(Cube cube, int target);
-static int check_coud_URF(Cube cube, int target);
-static int check_corners_HTM(Cube cube, int target);
-static int check_cornershtr_HTM(Cube cube, int target);
-static int check_corners_URF(Cube cube, int target);
-static int check_cornershtr_URF(Cube cube, int target);
-static int check_ep_HTM(Cube cube, int target);
-static int check_edges_HTM(Cube cube, int target);
-static int check_drud_HTM(Cube cube, int target);
-static int check_optimal_HTM(Cube cube, int target);
-static int check_corners6eo_HTM(Cube cube, int target);
-static int check_tripleeo_HTM(Cube cube, int target);
-
-
-/* Index functions ***********************************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_ep(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_corners6eo(Cube cube);
-static uint64_t index_tripleeo(Cube cube);
-
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .check = check_eofb_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .check = check_coud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .check = check_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .check = check_corners_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_HTM = {
- .check = check_cornershtr_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_URF = {
- .check = check_cornershtr_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_URF = {
- .check = check_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-edges_HTM = {
- .check = check_edges_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-drud_HTM = {
- .check = check_drud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .check = check_optimal_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-tripleeo_HTM = {
- .check = check_tripleeo_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-
-/* Blocks ********************************************************************/
-
-Block
-block_223dl = {
- .edge = { [DF] = 1, [DL] = 1, [DB] = 1, [FL] = 1, [BL] = 1 },
- .corner = { [DFL] = 1, [DBL] = 1 },
- .center = { [D_center] = 1, [L_center] = 1 }
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .size = POW2TO11,
- .index = index_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .size = POW3TO7,
- .index = index_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "ptable_cornershtr_HTM",
- .size = POW3TO7 * BINOM8ON4 * 6, /*TODO: check */
- .index = index_cornershtr,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .size = POW3TO7 * FACTORIAL8,
- .index = index_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_ep_HTM = {
- .filename = "ptable_ep_HTM",
- .size = FACTORIAL12,
- .index = index_ep,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .size = POW2TO11 * POW3TO7 * BINOM12ON4,
- .index = index_drud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners6eo_HTM = {
- .filename = "ptable_corners6eo_HTM",
- .size = POW2TO6 * POW3TO7 * FACTORIAL8,
- .index = index_corners6eo,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_tripleeo_HTM = {
- .filename = "ptable_tripleeo_HTM",
- .size = BINOM12ON4 * BINOM8ON4 * POW2TO11,
- .index = index_tripleeo,
- .moveset = moveset_HTM
-};
-
-
-/* Alg sets ******************************************************************/
-
-/* TODO: remove this (I am only keeping it as an example for future algesets)
-AlgSet
-as_ephtr_HTM = {
- .filename = "algset_ephtr_HTM",
- .size = FACTORIAL4 * FACTORIAL4 * FACTORIAL4,
- .index = index_ephtr,
- .antindex = index_to_cube_ephtr,
- .step = (Step) {
- .check = check_optimal_HTM,
- .ready = check_htr_solved_corners_HTM,
- .moveset = moveset_HTM
- },
- .opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .max_solutions = 1,
- .optimal_only = true,
- .can_niss = false,
- .feedback = true,
- .pre_trans = uf
- }
-};
-*/
-
-
-/* Check functions implementation ********************************************/
-
-static int
-check_nothing(Cube cube, int target)
-{
- return 0;
-}
-
-static int
-check_centers(Cube cube, int target)
-{
- return (cube.cpos == 0) ? 0 : 1;
-}
-
-static int
-check_eofb_HTM(Cube cube, int target)
-{
- if (!pd_eofb_HTM.generated)
- genptable(&pd_eofb_HTM);
-
- return ptableval(&pd_eofb_HTM, cube.eofb);
-}
-
-static int
-check_coud_HTM(Cube cube, int target)
-{
- if (!pd_coud_HTM.generated)
- genptable(&pd_coud_HTM);
-
- return ptableval(&pd_coud_HTM, cube.coud);
-}
-
-static int
-check_coud_URF(Cube cube, int target)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- int ud = check_coud_HTM(cube, target);
- int rl = check_coud_HTM(apply_move(z, cube), target);
- int fb = check_coud_HTM(apply_move(x, cube), target);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-check_corners_HTM(Cube cube, int target)
-{
- if (!pd_corners_HTM.generated)
- genptable(&pd_corners_HTM);
-
- return ptableval(&pd_corners_HTM, index_corners(cube));
-}
-
-static int
-check_cornershtr_HTM(Cube cube, int target)
-{
- if (!pd_cornershtr_HTM.generated)
- genptable(&pd_cornershtr_HTM);
-
- return ptableval(&pd_cornershtr_HTM, index_cornershtr(cube));
-}
-
-static int
-check_cornershtr_URF(Cube cube, int target)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- c = check_cornershtr_HTM(apply_alg(trans_alg(i),cube), target);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-check_corners_URF(Cube cube, int target)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++)
- ret = MIN(ret, check_corners_HTM(
- apply_alg(trans_alg(i), cube), target));
-
- return ret;
-}
-
-static int
-check_ep_HTM(Cube cube, int target)
-{
- if (!pd_ep_HTM.generated)
- genptable(&pd_ep_HTM);
-
- return ptableval(&pd_ep_HTM, index_ep(cube));
-}
-
-static int
-check_edges_HTM(Cube cube, int target)
-{
- return MAX(check_ep_HTM(cube, target),
- check_tripleeo_HTM(cube, target));
-}
-
-static int
-check_drud_HTM(Cube cube, int target)
-{
- if (!pd_drud_HTM.generated)
- genptable(&pd_drud_HTM);
-
- return ptableval(&pd_drud_HTM, index_drud(cube));
-}
-
-static int
-check_optimal_HTM(Cube cube, int target)
-{
- int dr1, dr2, dr3, cor, ret;
- Cube cube2, cube3;
-
- dr1 = check_drud_HTM(cube, target);
- /*cor = check_corners6eo_HTM(cube, target);*/
- cor = check_corners_HTM(cube, target);
- ret = MAX(dr1, cor);
-
- if (ret > target)
- return ret;
-
- cube2 = apply_trans(rf, cube);
- dr2 = check_drud_HTM(cube2, target);
- /*cor = check_corners6eo_HTM(cube2, target);
- ret = MAX(ret, MAX(dr2, cor));*/
- ret = MAX(ret, dr2);
-
- if (ret > target)
- return ret;
-
- cube3 = apply_trans(bd, cube);
- dr3 = check_drud_HTM(cube3, target);
- /*cor = check_corners6eo_HTM(cube3, target);*/
-
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- /*ret = MAX(ret, MAX(dr3, cor));*/
- ret = MAX(ret, dr3);
-
- if (ret == 0)
- return (!cube.epose && !cube.eposs && !cube.eposm) ? 0 : 6;
-
- return ret;
-}
-
-static int
-check_corners6eo_HTM(Cube cube, int target)
-{
- if (!pd_corners6eo_HTM.generated)
- genptable(&pd_corners6eo_HTM);
-
- return ptableval(&pd_corners6eo_HTM, index_corners6eo(cube));
-}
-
-static int
-check_tripleeo_HTM(Cube cube, int target)
-{
- if (!pd_tripleeo_HTM.generated)
- genptable(&pd_tripleeo_HTM);
-
- return ptableval(&pd_tripleeo_HTM, index_tripleeo(cube));
-}
-
-
-/* Index functions implementation ********************************************/
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_ep(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.epose;
- b = (cube.eposs % FACTORIAL4) + epos_dependent(cube)*FACTORIAL4;
- c = cube.eposm % FACTORIAL4;
-
- b *= FACTORIAL4 * BINOM12ON4;
- c *= FACTORIAL4 * BINOM12ON4 * FACTORIAL4 * BINOM8ON4;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_corners6eo(Cube cube)
-{
- return (cube.coud*FACTORIAL8 + cube.cp)*POW2TO6 + (cube.eofb%POW2TO6);
-}
-
-static uint64_t
-index_tripleeo(Cube cube)
-{
- uint64_t ee, es;
-
- ee = cube.epose / FACTORIAL4;
- es = epos_dependent(cube);
-
- return (ee * BINOM8ON4 + es) * POW2TO11 + cube.eofb;
-}
-
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
diff --git a/old/2021-06-23-realizing-bad-tables/steps.h b/old/2021-06-23-realizing-bad-tables/steps.h
@@ -1,42 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-/* Steps *********************************************************************/
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step cornershtr_HTM;
-extern Step corners_URF;
-extern Step cornershtr_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-extern Step tripleeo_HTM;
-
-/* Blocks ********************************************************************/
-
-extern Block block_223dl;
-
-/* Pruning tables ************************************************************/
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
-extern PruneData pd_tripleeo_HTM;
-
-/* Alg sets ******************************************************************/
-
-
-/* Movesets ******************************************************************/
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-#endif
diff --git a/old/2021-06-23-uint16t/cube.c b/old/2021-06-23-uint16t/cube.c
@@ -1,2762 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static uint16_t array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent(int pos1, int pos2);
-static uint16_t epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(uint16_t epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Checker f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static bool ptable_has_reached(PruneData *pd, uint64_t ind);
-static void ptable_set_reached(PruneData *pd, uint64_t ind);
-static void ptable_update(PruneData *pd, uint64_t ind, int m);
-static void realloc_alg(Alg *alg, int n);
-static bool read_algset_file(AlgSet *as);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_algset_file(AlgSet *as);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_ttables_file();
-
-static void init_auxtables();
-static void init_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_trans();
-static void init_trans_aux();
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static uint16_t epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static uint16_t eo_ttable[NTRANS][POW2TO11];
-static uint16_t cp_ttable[NTRANS][FACTORIAL8];
-static uint16_t co_ttable[NTRANS][POW3TO7];
-static uint16_t cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static uint16_t epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static uint16_t eofb_mtable[NMOVES][POW2TO11];
-static uint16_t eorl_mtable[NMOVES][POW2TO11];
-static uint16_t eoud_mtable[NMOVES][POW2TO11];
-static uint16_t cp_mtable[NMOVES][FACTORIAL8];
-static uint16_t coud_mtable[NMOVES][POW3TO7];
-static uint16_t cofb_mtable[NMOVES][POW3TO7];
-static uint16_t corl_mtable[NMOVES][POW3TO7];
-static uint16_t cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * trans_algs[NROTATIONS];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static uint16_t
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; (m=moves[i]) != NULLMOVE && dd->sols->len < maxnsol; i++) {
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
-
- if (dd->current_alg->len == 0 ||
- (s.check(apply_move(inverse_move(l1), (Cube){0}), 1))) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.check(c, dd->d - dd->current_alg->len);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static uint16_t
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(uint16_t epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- uint64_t ind = pd->index(c);
- int oldval = ptableval(pd, ind);
-
- if (oldval < dd->m || ptable_has_reached(pd, ind) || pd->n == pd->size)
- return;
-
- ptable_set_reached(pd, ind);
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, ind, dd->m);
- return;
- }
-
- genptable_dfs_branch(c, pd, dd);
-}
-
-static void
-genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd)
-{
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- dd->m++;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
-
- genptable_dfs(apply_move(move, c), pd, dd);
-
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Checker f, Move *r)
-{
- Cube c;
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- c = apply_move(i, (Cube){0});
- if (f != NULL && f(c, 1))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static bool
-ptable_has_reached(PruneData *pd, uint64_t ind)
-{
- return ind % 2 ? pd->reached[ind/2] / 16 : pd->reached[ind/2] % 16;
-}
-
-static void
-ptable_set_reached(PruneData *pd, uint64_t ind)
-{
- uint8_t oldval2 = pd->reached[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = ind % 2 ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = ind % 2 ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = ind % 2 ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_algset_file(AlgSet *as)
-{
- return false;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(uint16_t);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- Alg *inv;
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Cube ret;
-
- if (r != mirror) {
- ret = apply_alg_generic(trans_algs[r], c, f, true);
- inv = on_inverse(trans_algs[r]);
- ret = apply_alg_generic(inv, ret, f, true);
- free_alg(inv);
- } else {
- ret = move_via_arrays(&ma, (Cube){0}, f);
- ret = compose_filtered(c, ret, f);
- ret = move_via_arrays(&ma, ret, f);
- }
-
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_algset_file(AlgSet *as)
-{
- return false;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(uint16_t);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(uint16_t);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj] = epos_dependent(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[mirror] = mirror;
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- uint16_t ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_trans() {
- Cube aux, cube, c[3];
- CubeArray epcp;
- int eparr[12], eoarr[12];
- int cparr[8], coarr[8];
- int i;
- bool b1, b2, b3;
- uint16_t ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- if (i == mirror)
- cube = (Cube){0};
- else
- cube = apply_alg(trans_algs[i], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- if (m == mirror) {
- memcpy(eparr, ep_mirror, 12 * sizeof(int));
- memcpy(cparr, cp_mirror, 8 * sizeof(int));
- } else {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(trans_algs[m], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m == mirror)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- if (m == mirror) {
- b1 = (mi >= U && mi <= Bw3);
- b2 = (mi >= S && mi <= E3);
- b3 = (mi >= x && mi <= z3);
- if (b1 || b2 || b3)
- moves_ttable[m][mi] =
- inverse_move_aux[mi];
- else
- moves_ttable[m][mi] = mi;
-
- if ((mi-1)/3==(R-1)/3 || (mi-1)/3==(Rw-1)/3)
- moves_ttable[m][mi] += 3;
- if ((mi-1)/3==(L-1)/3 || (mi-1)/3==(L2-1)/3)
- moves_ttable[m][mi] -= 3;
- } else {
- aux = apply_trans(m, apply_move(mi,(Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(
- inverse_move_aux[move], aux);
- if (is_solved(cube, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- trans_algs[uf] = new_alg("");
- trans_algs[ur] = new_alg("y");
- trans_algs[ub] = new_alg("y2");
- trans_algs[ul] = new_alg("y3");
-
- trans_algs[df] = new_alg("z2");
- trans_algs[dr] = new_alg("y z2");
- trans_algs[db] = new_alg("x2");
- trans_algs[dl] = new_alg("y3 z2");
-
- trans_algs[rf] = new_alg("z3");
- trans_algs[rd] = new_alg("z3 y");
- trans_algs[rb] = new_alg("z3 y2");
- trans_algs[ru] = new_alg("z3 y3");
-
- trans_algs[lf] = new_alg("z");
- trans_algs[ld] = new_alg("z y3");
- trans_algs[lb] = new_alg("z y2");
- trans_algs[lu] = new_alg("z y");
-
- trans_algs[fu] = new_alg("x y2");
- trans_algs[fr] = new_alg("x y");
- trans_algs[fd] = new_alg("x");
- trans_algs[fl] = new_alg("x y3");
-
- trans_algs[bu] = new_alg("x3");
- trans_algs[br] = new_alg("x3 y");
- trans_algs[bd] = new_alg("x3 y2");
- trans_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- uint16_t aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- uint16_t aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- uint16_t aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-uint64_t
-epos_dependent_cube(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genalgset(AlgSet *as)
-{
- uint64_t i;
-
- if (as->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- as->table = malloc(as->size * sizeof(AlgList *));
-
- if (read_algset_file(as)) {
- as->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", as->filename);
-
- for (i = 0; i < as->size; i++) {
- as->table[i] = solve(as->antindex(i), as->step, &as->opts);
- fprintf(stderr, "Generated %lu / %lu cases\n", i, as->size);
- }
-
- if (!write_algset_file(as))
- fprintf(stderr, "Error writing algset file\n");
-
- as->generated = true;
-}
-
-void
-genptable(PruneData *pd)
-{
- uint64_t j;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->size; j++)
- ptable_update(pd, j, 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- pd->reached = malloc(ptablesize(pd) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->size; dd.d++) {
- memset(pd->reached, 0, ptablesize(pd)*sizeof(uint8_t));
- genptable_dfs((Cube){0}, pd, &dd);
- fprintf(stderr, "Depth %d completed, generated %lu/%lu\n",
- dd.d, pd->n, pd->size);
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- Trans i;
-
- if (reorient)
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(trans_algs[i],cube), false))
- return true;
-
- return equal(cube, (Cube){0});
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b;
- uint16_t x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c = apply_trans(opts->pre_trans, cube);
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && step.ready(c, 1) != 0) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.check, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(c, step, opts, &dd);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans_aux[opts->pre_trans], node->alg);
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, alg->move[i], alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->size; i++)
- a[ptableval(pd, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->size + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, uint64_t ind)
-{
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-
-Alg *
-trans_alg(Trans i)
-{
- return trans_algs[i];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_trans_aux();
- init_trans();
-}
-
diff --git a/old/2021-06-23-uint16t/cube.h b/old/2021-06-23-uint16t/cube.h
@@ -1,87 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-/* Constants and macros *****************************************************/
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS (mirror+1)
-#define NROTATIONS (NTRANS-1)
-
-/* Type definitions **********************************************************/
-
-#include "cubetypes.h"
-
-/* Public functions **********************************************************/
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t epos_dependent_cube(Cube cube);
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * trans_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void genalgset(AlgSet *as);
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, uint64_t ind);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-23-uint16t/cubetypes.h b/old/2021-06-23-uint16t/cubetypes.h
@@ -1,224 +0,0 @@
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct algset AlgSet;
-typedef struct block Block;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef int (*Checker) (Cube, int);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- mirror, /* R|L */
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-cube
-{
- uint16_t epose;
- uint16_t eposs;
- uint16_t eposm;
- uint16_t eofb;
- uint16_t eorl;
- uint16_t eoud;
- uint16_t cp;
- uint16_t coud;
- uint16_t cofb;
- uint16_t corl;
- uint16_t cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- uint64_t size;
- Indexer index;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
- Trans pre_trans;
-};
-
-struct
-step
-{
- Checker check;
- Checker ready;
- Moveset moveset;
-};
-
-/* TODO: I put it here because it needs the definition of Step, sort it out */
-struct
-algset
-{
- char * filename;
- AlgList ** table;
- bool generated;
- uint64_t size;
- Indexer index;
- AntiIndexer antindex;
- Step step;
- SolveOptions opts;
-};
diff --git a/old/2021-06-30-noreached/cube.c b/old/2021-06-30-noreached/cube.c
@@ -1,3394 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static Cube admissible_eos_from_eofbepos(Cube cube);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd);
-static void gensym(SymData *sd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-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_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_symdata();
-static void init_trans();
-static void init_trans_aux();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Estimator f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static void realloc_alg(Alg *alg, int n);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_symdata_file(SymData *sd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_symdata_file(SymData *sd);
-static bool write_ttables_file();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * rotation_algs[NROTATIONS];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-static Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 2;
-static SymData * all_sd[2] = { &sd_coud_16, &sd_eofbepos_16 };
-
-/* Coordinates and their implementation **************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-static uint64_t index_eofbepos_sym16(Cube cube);
-static uint64_t index_drud_sym16(Cube cube);
-static uint64_t index_khuge(Cube cube);
-
-static Cube antindex_eofb(uint64_t ind);
-static Cube antindex_eofbepos(uint64_t ind);
-static Cube antindex_coud(uint64_t ind);
-static Cube antindex_corners(uint64_t ind);
-static Cube antindex_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-static Cube antindex_eofbepos_sym16(uint64_t ind);
-static Cube antindex_drud_sym16(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430
-};
-
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-
-/* TODO: rename */
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- return admissible_ee_aux[ind];
-}
-
-/* TODO: rename */
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-static Cube
-antindex_drud(uint64_t ind)
-{
- Cube c = {0};
-
- c.eofb = ind % POW2TO11;
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.epose = (ind % (POW2TO11 * POW3TO7)) * FACTORIAL4;
-
- return c;
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_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 = sd_eofbepos_16.rep[ind/POW3TO7];
- c.coud = ind % POW3TO7;
- c.cofb = c.coud;
- c.corl = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-
-/* Checkers ******************************************************************/
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Local functions implementation ********************************************/
-
-/* TODO: this should be an anti index (maybe?) */
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s.estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- int oldval = ptableval(pd, c);
-
- if (oldval < dd->m || pd->n == pd->coord->max ||
- (dd->m != 0 && pd->coord->check(c)) )
- return;
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, c, dd->m);
- return;
- }
-
- genptable_dfs_branch(c, pd, dd);
-}
-
-static void
-genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd)
-{
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- dd->m++;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
-
- genptable_dfs(apply_move(move, c), pd, dd);
-
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Estimator f, Move *r)
-{
- CubeTarget ct = { .target = 1 };
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- ct.cube = apply_move(i, (Cube){0});
- if (f != NULL && f(ct))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_algs[r % NROTATIONS]);
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_algs[r % NROTATIONS], ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[uf_mirror] = uf_mirror;
- inverse_trans_aux[ur_mirror] = ur_mirror;
- inverse_trans_aux[ul_mirror] = ul_mirror;
- inverse_trans_aux[ub_mirror] = ub_mirror;
-
- inverse_trans_aux[df_mirror] = df_mirror;
- inverse_trans_aux[dr_mirror] = dl_mirror;
- inverse_trans_aux[dl_mirror] = dr_mirror;
- inverse_trans_aux[db_mirror] = db_mirror;
-
- inverse_trans_aux[rf_mirror] = rf_mirror;
- inverse_trans_aux[rd_mirror] = br_mirror;
- inverse_trans_aux[rb_mirror] = lb_mirror;
- inverse_trans_aux[ru_mirror] = fl_mirror;
-
- inverse_trans_aux[lf_mirror] = lf_mirror;
- inverse_trans_aux[ld_mirror] = bl_mirror;
- inverse_trans_aux[lb_mirror] = rb_mirror;
- inverse_trans_aux[lu_mirror] = fr_mirror;
-
- inverse_trans_aux[fu_mirror] = fu_mirror;
- inverse_trans_aux[fr_mirror] = lu_mirror;
- inverse_trans_aux[fd_mirror] = bu_mirror;
- inverse_trans_aux[fl_mirror] = ru_mirror;
-
- inverse_trans_aux[bu_mirror] = fd_mirror;
- inverse_trans_aux[br_mirror] = rd_mirror;
- inverse_trans_aux[bd_mirror] = bd_mirror;
- inverse_trans_aux[bl_mirror] = ld_mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-static void
-init_trans() {
- Cube aux, cube, mirr, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_algs[i % NROTATIONS], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m % NROTATIONS], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move_aux[move], aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube, false) ||
- is_solved(mirr, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- rotation_algs[uf] = new_alg("");
- rotation_algs[ur] = new_alg("y");
- rotation_algs[ub] = new_alg("y2");
- rotation_algs[ul] = new_alg("y3");
-
- rotation_algs[df] = new_alg("z2");
- rotation_algs[dr] = new_alg("y z2");
- rotation_algs[db] = new_alg("x2");
- rotation_algs[dl] = new_alg("y3 z2");
-
- rotation_algs[rf] = new_alg("z3");
- rotation_algs[rd] = new_alg("z3 y");
- rotation_algs[rb] = new_alg("z3 y2");
- rotation_algs[ru] = new_alg("z3 y3");
-
- rotation_algs[lf] = new_alg("z");
- rotation_algs[ld] = new_alg("z y3");
- rotation_algs[lb] = new_alg("z y2");
- rotation_algs[lu] = new_alg("z y");
-
- rotation_algs[fu] = new_alg("x y2");
- rotation_algs[fr] = new_alg("x y");
- rotation_algs[fd] = new_alg("x");
- rotation_algs[fl] = new_alg("x y3");
-
- rotation_algs[bu] = new_alg("x3");
- rotation_algs[br] = new_alg("x3 y");
- rotation_algs[bd] = new_alg("x3 y2");
- rotation_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genptable(PruneData *pd)
-{
- Cube cube;
- uint64_t j, oldn = 0;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update(pd, pd->coord->cube(j), 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->coord->max; dd.d++) {
- for (j = 0; j < pd->coord->max; j++) {
- cube = pd->coord->cube(j);
- if (pd->coord->check(cube))
- genptable_dfs(cube, pd, &dd);
- }
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- dd.d, pd->n-oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-/* TODO: clean pre_trans or put it back */
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- /*AlgListNode *node;*/
- AlgList *sols = new_alglist();
- /*Cube c = apply_trans(opts->pre_trans, cube);*/
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(cube)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.estimate, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(cube, step, opts, &dd);
- }
-
-/*
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(opts->pre_trans), node->alg);
-*/
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval(pd, pd->coord->cube(i))]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- uint64_t ind = pd->coord->index(cube);
-
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-
-Alg *
-rotation_alg(Trans i)
-{
- return rotation_algs[i % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
- init_symdata();
-}
-
diff --git a/old/2021-06-30-noreached/cube.h b/old/2021-06-30-noreached/cube.h
@@ -1,90 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "macros.h"
-#include "cubetypes.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_drud;
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_khuge;
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t cphtr(Cube cube); /* TODO: rename (something with cosets) */
-Cube anti_cphtr(uint64_t ind); /*TODO also this */
-uint64_t epos_dependent(Cube cube); /* TODO: rename and turn into an indexer */
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * rotation_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, Cube cube);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-30-noreached/cubetypes.h b/old/2021-06-30-noreached/cubetypes.h
@@ -1,250 +0,0 @@
-#ifndef CUBETYPES_H
-#define CUBETYPES_H
-
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct coordinate Coordinate;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct cubetarget CubeTarget;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-typedef struct symdata SymData;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef bool (*Checker) (Cube);
-typedef int (*Estimator) (CubeTarget);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
- rf_mirror, rd_mirror, rb_mirror, ru_mirror,
- lf_mirror, ld_mirror, lb_mirror, lu_mirror,
- fu_mirror, fr_mirror, fd_mirror, fl_mirror,
- bu_mirror, br_mirror, bd_mirror, bl_mirror,
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-coordinate
-{
- Indexer index;
- AntiIndexer cube;
- Checker check;
- uint64_t max;
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-cubetarget
-{
- Cube cube;
- int target;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- bool generated;
- uint64_t n;
- Coordinate * coord;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- Estimator estimate;
- Checker ready;
- Moveset moveset;
-};
-
-struct
-symdata
-{
- char * filename;
- bool generated;
- Coordinate * coord;
- Coordinate * sym_coord;
- int ntrans;
- Trans * trans;
- uint64_t * class;
- Cube * rep;
- Trans * transtorep;
-};
-
-#endif
diff --git a/old/2021-06-30-noreached/macros.h b/old/2021-06-30-noreached/macros.h
@@ -1,23 +0,0 @@
-#ifndef MACROS_H
-#define MACROS_H
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS 48
-#define NROTATIONS 24
-
-#endif
diff --git a/old/2021-06-30-noreached/main.c b/old/2021-06-30-noreached/main.c
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 2;
-/* Move m;*/
-/* int nrand = 10000, sum1, sum2, sum3;*/
-
- Step *stps[20] = {&drud_HTM, &optimal_HTM};
- char sss[30][30] = {"DR on UD", "Optimal solve"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- };
-
- init();
-
-/*
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- sum3 = 0;
- for (i = 0; i < nrand; i++) {
- cube = random_cube();
- sum1 += drud_HTM.check(cube, 20);
- sum2 += optimal_HTM.check(cube, 20);
- sum3 += cornershtreofb_HTM.check(cube, 20);
- }
- printf("Average drud pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners htr pruning: %lf\n", ((double)sum2) / ((double) nrand));
- printf("Average corners htr + eofb pruning: %lf\n", ((double)sum3) / ((double) nrand));
-*/
-
-/*
- for (m = U; m <= B3; m++) {
- printf("Class eofbepos after %d: ", m);
- printf("%lu\n", coord_khuge.index(apply_move(m,(Cube){0})));
- }
-*/
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- print_alg(inverse_alg(algo), false);
-/*
- printf("After rb_mirror:\n");
- cube = apply_trans(rb_mirror, cube);
- print_cube(cube);
- printf("Going back:\n");
- cube = apply_trans(inverse_trans(rb_mirror), cube);
-*/
-
- print_cube(cube);
-
- for (i = 0; i < ns; i++) {
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free_alg(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-06-30-noreached/steps.c b/old/2021-06-30-noreached/steps.c
@@ -1,307 +0,0 @@
-#include "steps.h"
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int estimate_eofb_HTM(CubeTarget ct);
-static int estimate_coud_HTM(CubeTarget ct);
-static int estimate_coud_URF(CubeTarget ct);
-static int estimate_corners_HTM(CubeTarget ct);
-static int estimate_cornershtr_HTM(CubeTarget ct);
-static int estimate_corners_URF(CubeTarget ct);
-static int estimate_cornershtr_URF(CubeTarget ct);
-static int estimate_drud_HTM(CubeTarget ct);
-static int estimate_optimal_HTM(CubeTarget ct);
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .estimate = estimate_coud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .estimate = estimate_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .estimate = estimate_corners_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_HTM = {
- .estimate = estimate_cornershtr_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_URF = {
- .estimate = estimate_cornershtr_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_URF = {
- .estimate = estimate_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-drud_HTM = {
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .estimate = estimate_optimal_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .coord = &coord_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .coord = &coord_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "ptable_cornershtr_withcosets_HTM",
- .coord = &coord_cornershtr,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .coord = &coord_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .coord = &coord_drud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_sym16_HTM = {
- .filename = "ptable_drud_sym16_HTM",
- .coord = &coord_drud_sym16,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_khuge_HTM = {
- .filename = "ptable_khuge_HTM",
- .coord = &coord_khuge,
- .moveset = moveset_HTM
-};
-
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int
-estimate_eofb_HTM(CubeTarget ct)
-{
- if (!pd_eofb_HTM.generated)
- genptable(&pd_eofb_HTM);
-
- return ptableval(&pd_eofb_HTM, ct.cube);
-}
-
-static int
-estimate_coud_HTM(CubeTarget ct)
-{
- if (!pd_coud_HTM.generated)
- genptable(&pd_coud_HTM);
-
- return ptableval(&pd_coud_HTM, ct.cube);
-}
-
-static int
-estimate_coud_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
- CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
-
- int ud = estimate_coud_HTM(ct);
- int rl = estimate_coud_HTM(ct2);
- int fb = estimate_coud_HTM(ct3);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-estimate_corners_HTM(CubeTarget ct)
-{
- if (!pd_corners_HTM.generated)
- genptable(&pd_corners_HTM);
-
- return ptableval(&pd_corners_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_HTM(CubeTarget ct)
-{
- if (!pd_cornershtr_HTM.generated)
- genptable(&pd_cornershtr_HTM);
-
- return ptableval(&pd_cornershtr_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_cornershtr_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_corners_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_corners_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_drud_HTM(CubeTarget ct)
-{
-/*
- if (!pd_drud_HTM.generated)
- genptable(&pd_drud_HTM);
-
- return ptableval(&pd_drud_HTM, ct.cube);
-*/
-
- if (!pd_drud_sym16_HTM.generated)
- genptable(&pd_drud_sym16_HTM);
-
- return ptableval(&pd_drud_sym16_HTM, ct.cube);
-}
-
-/* TODO: if lucky, remove this */
-/*
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t1 = { .rot = rf, .mirror = false };
- static Trans t2 = { .rot = bd, .mirror = false };
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- dr1 = estimate_drud_HTM(ct);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t1, cube);
- dr2 = estimate_drud_HTM(ct);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t2, cube);
- dr3 = estimate_drud_HTM(ct);
-
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- ret = MAX(ret, dr3);
-
- if (ret == 0)
- return check_ep(cube) ? 0 : 6;
-
- return ret;
-}
-*/
-
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t2 = rf, t3 = bd;
-
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- if (!pd_khuge_HTM.generated)
- genptable(&pd_khuge_HTM);
-
- dr1 = ptableval(&pd_khuge_HTM, cube);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t2, ct.cube);
- dr2 = ptableval(&pd_khuge_HTM, cube);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t3, ct.cube);
- dr3 = ptableval(&pd_khuge_HTM, cube);
-
- return MAX(ret, dr3);
-}
diff --git a/old/2021-06-30-noreached/steps.h b/old/2021-06-30-noreached/steps.h
@@ -1,24 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step cornershtr_HTM;
-extern Step corners_URF;
-extern Step cornershtr_URF;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_cornershtreofb_HTM;
-extern PruneData pd_drud_HTM;
-extern PruneData pd_khuge_HTM;
-
-#endif
diff --git a/old/2021-06-30-reached/cube.c b/old/2021-06-30-reached/cube.c
@@ -1,3419 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static Cube admissible_eos_from_eofbepos(Cube cube);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd);
-static void gensym(SymData *sd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-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_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_symdata();
-static void init_trans();
-static void init_trans_aux();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Estimator f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static bool ptable_has_reached(PruneData *pd, Cube cube);
-static void ptable_set_reached(PruneData *pd, Cube cube);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static void realloc_alg(Alg *alg, int n);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_symdata_file(SymData *sd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_symdata_file(SymData *sd);
-static bool write_ttables_file();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * rotation_algs[NROTATIONS];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-static Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 2;
-static SymData * all_sd[2] = { &sd_coud_16, &sd_eofbepos_16 };
-
-/* Coordinates and their implementation **************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-static uint64_t index_eofbepos_sym16(Cube cube);
-static uint64_t index_drud_sym16(Cube cube);
-static uint64_t index_khuge(Cube cube);
-
-static Cube antindex_eofb(uint64_t ind);
-static Cube antindex_eofbepos(uint64_t ind);
-static Cube antindex_coud(uint64_t ind);
-static Cube antindex_corners(uint64_t ind);
-static Cube antindex_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-static Cube antindex_eofbepos_sym16(uint64_t ind);
-static Cube antindex_drud_sym16(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430
-};
-
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-
-/* TODO: rename */
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- return admissible_ee_aux[ind];
-}
-
-/* TODO: rename */
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-static Cube
-antindex_drud(uint64_t ind)
-{
- Cube c = {0};
-
- c.eofb = ind % POW2TO11;
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.epose = (ind % (POW2TO11 * POW3TO7)) * FACTORIAL4;
-
- return c;
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_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 = sd_eofbepos_16.rep[ind/POW3TO7];
- c.coud = ind % POW3TO7;
- c.cofb = c.coud;
- c.corl = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-
-/* Checkers ******************************************************************/
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Local functions implementation ********************************************/
-
-/* TODO: this should be an anti index (maybe?) */
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s.estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- int oldval = ptableval(pd, c);
-
- if (oldval < dd->m || ptable_has_reached(pd, c) ||
- pd->n == pd->coord->max || (dd->m != 0 && pd->coord->check(c)) )
- return;
-
- /*ptable_set_reached(pd, c);*/
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, c, dd->m);
- return;
- }
-
- genptable_dfs_branch(c, pd, dd);
-}
-
-static void
-genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd)
-{
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- dd->m++;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
-
- genptable_dfs(apply_move(move, c), pd, dd);
-
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Estimator f, Move *r)
-{
- CubeTarget ct = { .target = 1 };
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- ct.cube = apply_move(i, (Cube){0});
- if (f != NULL && f(ct))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static bool
-ptable_has_reached(PruneData *pd, Cube cube)
-{
- uint64_t ind = pd->coord->index(cube);
-
- return (ind % 2) ? pd->reached[ind/2] / 16 : pd->reached[ind/2] % 16;
-}
-
-static void
-ptable_set_reached(PruneData *pd, Cube cube)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->reached[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->reached[ind/2] = (ind % 2) ? 16 + other : 16*other + 1;
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_algs[r % NROTATIONS]);
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_algs[r % NROTATIONS], ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[uf_mirror] = uf_mirror;
- inverse_trans_aux[ur_mirror] = ur_mirror;
- inverse_trans_aux[ul_mirror] = ul_mirror;
- inverse_trans_aux[ub_mirror] = ub_mirror;
-
- inverse_trans_aux[df_mirror] = df_mirror;
- inverse_trans_aux[dr_mirror] = dl_mirror;
- inverse_trans_aux[dl_mirror] = dr_mirror;
- inverse_trans_aux[db_mirror] = db_mirror;
-
- inverse_trans_aux[rf_mirror] = rf_mirror;
- inverse_trans_aux[rd_mirror] = br_mirror;
- inverse_trans_aux[rb_mirror] = lb_mirror;
- inverse_trans_aux[ru_mirror] = fl_mirror;
-
- inverse_trans_aux[lf_mirror] = lf_mirror;
- inverse_trans_aux[ld_mirror] = bl_mirror;
- inverse_trans_aux[lb_mirror] = rb_mirror;
- inverse_trans_aux[lu_mirror] = fr_mirror;
-
- inverse_trans_aux[fu_mirror] = fu_mirror;
- inverse_trans_aux[fr_mirror] = lu_mirror;
- inverse_trans_aux[fd_mirror] = bu_mirror;
- inverse_trans_aux[fl_mirror] = ru_mirror;
-
- inverse_trans_aux[bu_mirror] = fd_mirror;
- inverse_trans_aux[br_mirror] = rd_mirror;
- inverse_trans_aux[bd_mirror] = bd_mirror;
- inverse_trans_aux[bl_mirror] = ld_mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-static void
-init_trans() {
- Cube aux, cube, mirr, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_algs[i % NROTATIONS], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m % NROTATIONS], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move_aux[move], aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube, false) ||
- is_solved(mirr, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- rotation_algs[uf] = new_alg("");
- rotation_algs[ur] = new_alg("y");
- rotation_algs[ub] = new_alg("y2");
- rotation_algs[ul] = new_alg("y3");
-
- rotation_algs[df] = new_alg("z2");
- rotation_algs[dr] = new_alg("y z2");
- rotation_algs[db] = new_alg("x2");
- rotation_algs[dl] = new_alg("y3 z2");
-
- rotation_algs[rf] = new_alg("z3");
- rotation_algs[rd] = new_alg("z3 y");
- rotation_algs[rb] = new_alg("z3 y2");
- rotation_algs[ru] = new_alg("z3 y3");
-
- rotation_algs[lf] = new_alg("z");
- rotation_algs[ld] = new_alg("z y3");
- rotation_algs[lb] = new_alg("z y2");
- rotation_algs[lu] = new_alg("z y");
-
- rotation_algs[fu] = new_alg("x y2");
- rotation_algs[fr] = new_alg("x y");
- rotation_algs[fd] = new_alg("x");
- rotation_algs[fl] = new_alg("x y3");
-
- rotation_algs[bu] = new_alg("x3");
- rotation_algs[br] = new_alg("x3 y");
- rotation_algs[bd] = new_alg("x3 y2");
- rotation_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genptable(PruneData *pd)
-{
- Cube cube;
- uint64_t j, oldn = 0;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update(pd, pd->coord->cube(j), 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- pd->reached = malloc(ptablesize(pd) * sizeof(uint8_t));
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->coord->max; dd.d++) {
- memset(pd->reached, 0, ptablesize(pd)*sizeof(uint8_t));
- for (j = 0; j < pd->coord->max; j++) {
- cube = pd->coord->cube(j);
- if (pd->coord->check(cube))
- genptable_dfs(cube, pd, &dd);
- }
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- dd.d, pd->n-oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
- free(pd->reached);
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-/* TODO: clean pre_trans or put it back */
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- /*AlgListNode *node;*/
- AlgList *sols = new_alglist();
- /*Cube c = apply_trans(opts->pre_trans, cube);*/
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(cube)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.estimate, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(cube, step, opts, &dd);
- }
-
-/*
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(opts->pre_trans), node->alg);
-*/
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval(pd, pd->coord->cube(i))]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- uint64_t ind = pd->coord->index(cube);
-
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-
-Alg *
-rotation_alg(Trans i)
-{
- return rotation_algs[i % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
- init_symdata();
-}
-
diff --git a/old/2021-06-30-reached/cube.h b/old/2021-06-30-reached/cube.h
@@ -1,90 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "macros.h"
-#include "cubetypes.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_drud;
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_khuge;
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t cphtr(Cube cube); /* TODO: rename (something with cosets) */
-Cube anti_cphtr(uint64_t ind); /*TODO also this */
-uint64_t epos_dependent(Cube cube); /* TODO: rename and turn into an indexer */
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * rotation_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, Cube cube);
-
-void init();
-
-#endif
-
diff --git a/old/2021-06-30-reached/cubetypes.h b/old/2021-06-30-reached/cubetypes.h
@@ -1,251 +0,0 @@
-#ifndef CUBETYPES_H
-#define CUBETYPES_H
-
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct coordinate Coordinate;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct cubetarget CubeTarget;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-typedef struct symdata SymData;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef bool (*Checker) (Cube);
-typedef int (*Estimator) (CubeTarget);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
- rf_mirror, rd_mirror, rb_mirror, ru_mirror,
- lf_mirror, ld_mirror, lb_mirror, lu_mirror,
- fu_mirror, fr_mirror, fd_mirror, fl_mirror,
- bu_mirror, br_mirror, bd_mirror, bl_mirror,
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-coordinate
-{
- Indexer index;
- AntiIndexer cube;
- Checker check;
- uint64_t max;
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-cubetarget
-{
- Cube cube;
- int target;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- uint8_t * reached;
- bool generated;
- uint64_t n;
- Coordinate * coord;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- Estimator estimate;
- Checker ready;
- Moveset moveset;
-};
-
-struct
-symdata
-{
- char * filename;
- bool generated;
- Coordinate * coord;
- Coordinate * sym_coord;
- int ntrans;
- Trans * trans;
- uint64_t * class;
- Cube * rep;
- Trans * transtorep;
-};
-
-#endif
diff --git a/old/2021-06-30-reached/macros.h b/old/2021-06-30-reached/macros.h
@@ -1,23 +0,0 @@
-#ifndef MACROS_H
-#define MACROS_H
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS 48
-#define NROTATIONS 24
-
-#endif
diff --git a/old/2021-06-30-reached/main.c b/old/2021-06-30-reached/main.c
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 2;
-/* Move m;*/
-/* int nrand = 10000, sum1, sum2, sum3;*/
-
- Step *stps[20] = {&drud_HTM, &optimal_HTM};
- char sss[30][30] = {"DR on UD", "Optimal solve"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- };
-
- init();
-
-/*
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- sum3 = 0;
- for (i = 0; i < nrand; i++) {
- cube = random_cube();
- sum1 += drud_HTM.check(cube, 20);
- sum2 += optimal_HTM.check(cube, 20);
- sum3 += cornershtreofb_HTM.check(cube, 20);
- }
- printf("Average drud pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners htr pruning: %lf\n", ((double)sum2) / ((double) nrand));
- printf("Average corners htr + eofb pruning: %lf\n", ((double)sum3) / ((double) nrand));
-*/
-
-/*
- for (m = U; m <= B3; m++) {
- printf("Class eofbepos after %d: ", m);
- printf("%lu\n", coord_khuge.index(apply_move(m,(Cube){0})));
- }
-*/
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- print_alg(inverse_alg(algo), false);
-/*
- printf("After rb_mirror:\n");
- cube = apply_trans(rb_mirror, cube);
- print_cube(cube);
- printf("Going back:\n");
- cube = apply_trans(inverse_trans(rb_mirror), cube);
-*/
-
- print_cube(cube);
-
- for (i = 0; i < ns; i++) {
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free_alg(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-06-30-reached/steps.c b/old/2021-06-30-reached/steps.c
@@ -1,307 +0,0 @@
-#include "steps.h"
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int estimate_eofb_HTM(CubeTarget ct);
-static int estimate_coud_HTM(CubeTarget ct);
-static int estimate_coud_URF(CubeTarget ct);
-static int estimate_corners_HTM(CubeTarget ct);
-static int estimate_cornershtr_HTM(CubeTarget ct);
-static int estimate_corners_URF(CubeTarget ct);
-static int estimate_cornershtr_URF(CubeTarget ct);
-static int estimate_drud_HTM(CubeTarget ct);
-static int estimate_optimal_HTM(CubeTarget ct);
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .estimate = estimate_coud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .estimate = estimate_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .estimate = estimate_corners_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_HTM = {
- .estimate = estimate_cornershtr_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_URF = {
- .estimate = estimate_cornershtr_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_URF = {
- .estimate = estimate_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-drud_HTM = {
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .estimate = estimate_optimal_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .coord = &coord_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .coord = &coord_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "ptable_cornershtr_withcosets_HTM",
- .coord = &coord_cornershtr,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .coord = &coord_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .coord = &coord_drud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_sym16_HTM = {
- .filename = "pd_drud_sym16_HTM",
- .coord = &coord_drud_sym16,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_khuge_HTM = {
- .filename = "pd_khuge_HTM",
- .coord = &coord_khuge,
- .moveset = moveset_HTM
-};
-
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int
-estimate_eofb_HTM(CubeTarget ct)
-{
- if (!pd_eofb_HTM.generated)
- genptable(&pd_eofb_HTM);
-
- return ptableval(&pd_eofb_HTM, ct.cube);
-}
-
-static int
-estimate_coud_HTM(CubeTarget ct)
-{
- if (!pd_coud_HTM.generated)
- genptable(&pd_coud_HTM);
-
- return ptableval(&pd_coud_HTM, ct.cube);
-}
-
-static int
-estimate_coud_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
- CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
-
- int ud = estimate_coud_HTM(ct);
- int rl = estimate_coud_HTM(ct2);
- int fb = estimate_coud_HTM(ct3);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-estimate_corners_HTM(CubeTarget ct)
-{
- if (!pd_corners_HTM.generated)
- genptable(&pd_corners_HTM);
-
- return ptableval(&pd_corners_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_HTM(CubeTarget ct)
-{
- if (!pd_cornershtr_HTM.generated)
- genptable(&pd_cornershtr_HTM);
-
- return ptableval(&pd_cornershtr_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_cornershtr_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_corners_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_corners_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_drud_HTM(CubeTarget ct)
-{
-/*
- if (!pd_drud_HTM.generated)
- genptable(&pd_drud_HTM);
-
- return ptableval(&pd_drud_HTM, ct.cube);
-*/
-
- if (!pd_drud_sym16_HTM.generated)
- genptable(&pd_drud_sym16_HTM);
-
- return ptableval(&pd_drud_sym16_HTM, ct.cube);
-}
-
-/* TODO: if lucky, remove this */
-/*
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t1 = { .rot = rf, .mirror = false };
- static Trans t2 = { .rot = bd, .mirror = false };
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- dr1 = estimate_drud_HTM(ct);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t1, cube);
- dr2 = estimate_drud_HTM(ct);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t2, cube);
- dr3 = estimate_drud_HTM(ct);
-
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- ret = MAX(ret, dr3);
-
- if (ret == 0)
- return check_ep(cube) ? 0 : 6;
-
- return ret;
-}
-*/
-
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t2 = rf, t3 = bd;
-
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- if (!pd_khuge_HTM.generated)
- genptable(&pd_khuge_HTM);
-
- dr1 = ptableval(&pd_khuge_HTM, cube);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t2, ct.cube);
- dr2 = ptableval(&pd_khuge_HTM, cube);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t3, ct.cube);
- dr3 = ptableval(&pd_khuge_HTM, cube);
-
- return MAX(ret, dr3);
-}
diff --git a/old/2021-06-30-reached/steps.h b/old/2021-06-30-reached/steps.h
@@ -1,24 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step cornershtr_HTM;
-extern Step corners_URF;
-extern Step cornershtr_URF;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_cornershtreofb_HTM;
-extern PruneData pd_drud_HTM;
-extern PruneData pd_khuge_HTM;
-
-#endif
diff --git a/old/2021-07-02-genptable-dfs/cube.c b/old/2021-07-02-genptable-dfs/cube.c
@@ -1,3394 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static Cube admissible_eos_from_eofbepos(Cube cube);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd);
-static void genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd);
-static void gensym(SymData *sd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-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_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_symdata();
-static void init_trans();
-static void init_trans_aux();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Estimator f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static void realloc_alg(Alg *alg, int n);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_symdata_file(SymData *sd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_symdata_file(SymData *sd);
-static bool write_ttables_file();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * rotation_algs[NROTATIONS];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-static Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 2;
-static SymData * all_sd[2] = { &sd_coud_16, &sd_eofbepos_16 };
-
-/* Coordinates and their implementation **************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-static uint64_t index_eofbepos_sym16(Cube cube);
-static uint64_t index_drud_sym16(Cube cube);
-static uint64_t index_khuge(Cube cube);
-
-static Cube antindex_eofb(uint64_t ind);
-static Cube antindex_eofbepos(uint64_t ind);
-static Cube antindex_coud(uint64_t ind);
-static Cube antindex_corners(uint64_t ind);
-static Cube antindex_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-static Cube antindex_eofbepos_sym16(uint64_t ind);
-static Cube antindex_drud_sym16(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430
-};
-
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-
-/* TODO: rename */
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- return admissible_ee_aux[ind];
-}
-
-/* TODO: rename */
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-static Cube
-antindex_drud(uint64_t ind)
-{
- Cube c = {0};
-
- c.eofb = ind % POW2TO11;
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.epose = (ind % (POW2TO11 * POW3TO7)) * FACTORIAL4;
-
- return c;
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_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 = sd_eofbepos_16.rep[ind/POW3TO7];
- c.coud = ind % POW3TO7;
- c.cofb = c.coud;
- c.corl = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-
-/* Checkers ******************************************************************/
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Local functions implementation ********************************************/
-
-/* TODO: this should be an anti index (maybe?) */
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s.estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_dfs(Cube c, PruneData *pd, DfsData *dd)
-{
- int oldval = ptableval(pd, c);
-
- if (oldval < dd->m || pd->n == pd->coord->max ||
- (dd->m != 0 && pd->coord->check(c)) )
- return;
-
- if (dd->m == dd->d) {
- if (dd->m < oldval)
- ptable_update(pd, c, dd->m);
- return;
- }
-
- genptable_dfs_branch(c, pd, dd);
-}
-
-static void
-genptable_dfs_branch(Cube c, PruneData *pd, DfsData *dd)
-{
- Move i, move, l1 = dd->last1, l2 = dd->last2;
-
- dd->m++;
-
- for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) {
- move = dd->sorted_moves[i];
- if (allowed_next(move, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = move;
-
- genptable_dfs(apply_move(move, c), pd, dd);
-
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-
- dd->m--;
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Estimator f, Move *r)
-{
- CubeTarget ct = { .target = 1 };
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- ct.cube = apply_move(i, (Cube){0});
- if (f != NULL && f(ct))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_algs[r % NROTATIONS]);
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_algs[r % NROTATIONS], ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[uf_mirror] = uf_mirror;
- inverse_trans_aux[ur_mirror] = ur_mirror;
- inverse_trans_aux[ul_mirror] = ul_mirror;
- inverse_trans_aux[ub_mirror] = ub_mirror;
-
- inverse_trans_aux[df_mirror] = df_mirror;
- inverse_trans_aux[dr_mirror] = dl_mirror;
- inverse_trans_aux[dl_mirror] = dr_mirror;
- inverse_trans_aux[db_mirror] = db_mirror;
-
- inverse_trans_aux[rf_mirror] = rf_mirror;
- inverse_trans_aux[rd_mirror] = br_mirror;
- inverse_trans_aux[rb_mirror] = lb_mirror;
- inverse_trans_aux[ru_mirror] = fl_mirror;
-
- inverse_trans_aux[lf_mirror] = lf_mirror;
- inverse_trans_aux[ld_mirror] = bl_mirror;
- inverse_trans_aux[lb_mirror] = rb_mirror;
- inverse_trans_aux[lu_mirror] = fr_mirror;
-
- inverse_trans_aux[fu_mirror] = fu_mirror;
- inverse_trans_aux[fr_mirror] = lu_mirror;
- inverse_trans_aux[fd_mirror] = bu_mirror;
- inverse_trans_aux[fl_mirror] = ru_mirror;
-
- inverse_trans_aux[bu_mirror] = fd_mirror;
- inverse_trans_aux[br_mirror] = rd_mirror;
- inverse_trans_aux[bd_mirror] = bd_mirror;
- inverse_trans_aux[bl_mirror] = ld_mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-static void
-init_trans() {
- Cube aux, cube, mirr, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_algs[i % NROTATIONS], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m % NROTATIONS], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move_aux[move], aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube, false) ||
- is_solved(mirr, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- rotation_algs[uf] = new_alg("");
- rotation_algs[ur] = new_alg("y");
- rotation_algs[ub] = new_alg("y2");
- rotation_algs[ul] = new_alg("y3");
-
- rotation_algs[df] = new_alg("z2");
- rotation_algs[dr] = new_alg("y z2");
- rotation_algs[db] = new_alg("x2");
- rotation_algs[dl] = new_alg("y3 z2");
-
- rotation_algs[rf] = new_alg("z3");
- rotation_algs[rd] = new_alg("z3 y");
- rotation_algs[rb] = new_alg("z3 y2");
- rotation_algs[ru] = new_alg("z3 y3");
-
- rotation_algs[lf] = new_alg("z");
- rotation_algs[ld] = new_alg("z y3");
- rotation_algs[lb] = new_alg("z y2");
- rotation_algs[lu] = new_alg("z y");
-
- rotation_algs[fu] = new_alg("x y2");
- rotation_algs[fr] = new_alg("x y");
- rotation_algs[fd] = new_alg("x");
- rotation_algs[fl] = new_alg("x y3");
-
- rotation_algs[bu] = new_alg("x3");
- rotation_algs[br] = new_alg("x3 y");
- rotation_algs[bd] = new_alg("x3 y2");
- rotation_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genptable(PruneData *pd)
-{
- Cube cube;
- uint64_t j, oldn = 0;
- DfsData dd = {
- .m = 0,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE
- };
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update(pd, pd->coord->cube(j), 15);
-
- moveset_to_list(pd->moveset, NULL, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = 0, pd->n = 0; dd.d < 15 && pd->n < pd->coord->max; dd.d++) {
- for (j = 0; j < pd->coord->max; j++) {
- cube = pd->coord->cube(j);
- if (pd->coord->check(cube))
- genptable_dfs(cube, pd, &dd);
- }
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- dd.d, pd->n-oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-/* TODO: clean pre_trans or put it back */
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- /*AlgListNode *node;*/
- AlgList *sols = new_alglist();
- /*Cube c = apply_trans(opts->pre_trans, cube);*/
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(cube)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.estimate, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(cube, step, opts, &dd);
- }
-
-/*
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(opts->pre_trans), node->alg);
-*/
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval(pd, pd->coord->cube(i))]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- uint64_t ind = pd->coord->index(cube);
-
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-
-Alg *
-rotation_alg(Trans i)
-{
- return rotation_algs[i % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
- init_symdata();
-}
-
diff --git a/old/2021-07-02-genptable-dfs/cube.h b/old/2021-07-02-genptable-dfs/cube.h
@@ -1,90 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "macros.h"
-#include "cubetypes.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_drud;
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_khuge;
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t cphtr(Cube cube); /* TODO: rename (something with cosets) */
-Cube anti_cphtr(uint64_t ind); /*TODO also this */
-uint64_t epos_dependent(Cube cube); /* TODO: rename and turn into an indexer */
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * rotation_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, Cube cube);
-
-void init();
-
-#endif
-
diff --git a/old/2021-07-02-genptable-dfs/cubetypes.h b/old/2021-07-02-genptable-dfs/cubetypes.h
@@ -1,250 +0,0 @@
-#ifndef CUBETYPES_H
-#define CUBETYPES_H
-
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct coordinate Coordinate;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct cubetarget CubeTarget;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-typedef struct symdata SymData;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef bool (*Checker) (Cube);
-typedef int (*Estimator) (CubeTarget);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
- rf_mirror, rd_mirror, rb_mirror, ru_mirror,
- lf_mirror, ld_mirror, lb_mirror, lu_mirror,
- fu_mirror, fr_mirror, fd_mirror, fl_mirror,
- bu_mirror, br_mirror, bd_mirror, bl_mirror,
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-coordinate
-{
- Indexer index;
- AntiIndexer cube;
- Checker check;
- uint64_t max;
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-cubetarget
-{
- Cube cube;
- int target;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- bool generated;
- uint64_t n;
- Coordinate * coord;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- Estimator estimate;
- Checker ready;
- Moveset moveset;
-};
-
-struct
-symdata
-{
- char * filename;
- bool generated;
- Coordinate * coord;
- Coordinate * sym_coord;
- int ntrans;
- Trans * trans;
- uint64_t * class;
- Cube * rep;
- Trans * transtorep;
-};
-
-#endif
diff --git a/old/2021-07-02-genptable-dfs/macros.h b/old/2021-07-02-genptable-dfs/macros.h
@@ -1,23 +0,0 @@
-#ifndef MACROS_H
-#define MACROS_H
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS 48
-#define NROTATIONS 24
-
-#endif
diff --git a/old/2021-07-02-genptable-dfs/main.c b/old/2021-07-02-genptable-dfs/main.c
@@ -1,80 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 2;
-/* Move m;*/
-/* int nrand = 10000, sum1, sum2, sum3;*/
-
- Step *stps[20] = {&drud_HTM, &optimal_HTM};
- char sss[30][30] = {"DR on UD", "Optimal solve"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- };
-
- init();
-
-/*
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- sum3 = 0;
- for (i = 0; i < nrand; i++) {
- cube = random_cube();
- sum1 += drud_HTM.check(cube, 20);
- sum2 += optimal_HTM.check(cube, 20);
- sum3 += cornershtreofb_HTM.check(cube, 20);
- }
- printf("Average drud pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners htr pruning: %lf\n", ((double)sum2) / ((double) nrand));
- printf("Average corners htr + eofb pruning: %lf\n", ((double)sum3) / ((double) nrand));
-*/
-
-/*
- for (m = U; m <= B3; m++) {
- printf("Class eofbepos after %d: ", m);
- printf("%lu\n", coord_khuge.index(apply_move(m,(Cube){0})));
- }
-*/
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- print_alg(inverse_alg(algo), false);
-/*
- printf("After rb_mirror:\n");
- cube = apply_trans(rb_mirror, cube);
- print_cube(cube);
- printf("Going back:\n");
- cube = apply_trans(inverse_trans(rb_mirror), cube);
-*/
-
- print_cube(cube);
-
- for (i = 0; i < ns; i++) {
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free_alg(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-07-02-genptable-dfs/steps.c b/old/2021-07-02-genptable-dfs/steps.c
@@ -1,307 +0,0 @@
-#include "steps.h"
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int estimate_eofb_HTM(CubeTarget ct);
-static int estimate_coud_HTM(CubeTarget ct);
-static int estimate_coud_URF(CubeTarget ct);
-static int estimate_corners_HTM(CubeTarget ct);
-static int estimate_cornershtr_HTM(CubeTarget ct);
-static int estimate_corners_URF(CubeTarget ct);
-static int estimate_cornershtr_URF(CubeTarget ct);
-static int estimate_drud_HTM(CubeTarget ct);
-static int estimate_optimal_HTM(CubeTarget ct);
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .estimate = estimate_coud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .estimate = estimate_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .estimate = estimate_corners_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_HTM = {
- .estimate = estimate_cornershtr_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_URF = {
- .estimate = estimate_cornershtr_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_URF = {
- .estimate = estimate_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-drud_HTM = {
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .estimate = estimate_optimal_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .coord = &coord_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .coord = &coord_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "ptable_cornershtr_withcosets_HTM",
- .coord = &coord_cornershtr,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .coord = &coord_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .coord = &coord_drud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_sym16_HTM = {
- .filename = "ptable_drud_sym16_HTM",
- .coord = &coord_drud_sym16,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_khuge_HTM = {
- .filename = "ptable_khuge_HTM",
- .coord = &coord_khuge,
- .moveset = moveset_HTM
-};
-
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int
-estimate_eofb_HTM(CubeTarget ct)
-{
- if (!pd_eofb_HTM.generated)
- genptable(&pd_eofb_HTM);
-
- return ptableval(&pd_eofb_HTM, ct.cube);
-}
-
-static int
-estimate_coud_HTM(CubeTarget ct)
-{
- if (!pd_coud_HTM.generated)
- genptable(&pd_coud_HTM);
-
- return ptableval(&pd_coud_HTM, ct.cube);
-}
-
-static int
-estimate_coud_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
- CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
-
- int ud = estimate_coud_HTM(ct);
- int rl = estimate_coud_HTM(ct2);
- int fb = estimate_coud_HTM(ct3);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-estimate_corners_HTM(CubeTarget ct)
-{
- if (!pd_corners_HTM.generated)
- genptable(&pd_corners_HTM);
-
- return ptableval(&pd_corners_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_HTM(CubeTarget ct)
-{
- if (!pd_cornershtr_HTM.generated)
- genptable(&pd_cornershtr_HTM);
-
- return ptableval(&pd_cornershtr_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_cornershtr_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_corners_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_corners_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_drud_HTM(CubeTarget ct)
-{
-/*
- if (!pd_drud_HTM.generated)
- genptable(&pd_drud_HTM);
-
- return ptableval(&pd_drud_HTM, ct.cube);
-*/
-
- if (!pd_drud_sym16_HTM.generated)
- genptable(&pd_drud_sym16_HTM);
-
- return ptableval(&pd_drud_sym16_HTM, ct.cube);
-}
-
-/* TODO: if lucky, remove this */
-/*
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t1 = { .rot = rf, .mirror = false };
- static Trans t2 = { .rot = bd, .mirror = false };
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- dr1 = estimate_drud_HTM(ct);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t1, cube);
- dr2 = estimate_drud_HTM(ct);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- ct.cube = apply_trans(t2, cube);
- dr3 = estimate_drud_HTM(ct);
-
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- ret = MAX(ret, dr3);
-
- if (ret == 0)
- return check_ep(cube) ? 0 : 6;
-
- return ret;
-}
-*/
-
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- static Trans t2 = rf, t3 = bd;
-
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- if (!pd_khuge_HTM.generated)
- genptable(&pd_khuge_HTM);
-
- dr1 = ptableval(&pd_khuge_HTM, cube);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t2, ct.cube);
- dr2 = ptableval(&pd_khuge_HTM, cube);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(t3, ct.cube);
- dr3 = ptableval(&pd_khuge_HTM, cube);
-
- return MAX(ret, dr3);
-}
diff --git a/old/2021-07-02-genptable-dfs/steps.h b/old/2021-07-02-genptable-dfs/steps.h
@@ -1,24 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step cornershtr_HTM;
-extern Step corners_URF;
-extern Step cornershtr_URF;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_cornershtreofb_HTM;
-extern PruneData pd_drud_HTM;
-extern PruneData pd_khuge_HTM;
-
-#endif
diff --git a/old/2021-07-15-almostbeforerefactor/README b/old/2021-07-15-almostbeforerefactor/README
@@ -1,3 +0,0 @@
-I started refactorig (splitting code into more files) before realizing I had no backup of
-the fast version that works.
-Take some stuff from alg.h back into cube.h, remove alg.* ad it should be ok.
diff --git a/old/2021-07-15-almostbeforerefactor/alg.c b/old/2021-07-15-almostbeforerefactor/alg.c
@@ -1,3388 +0,0 @@
-#include "alg.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static Cube admissible_eos_from_eofbepos(Cube cube);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_bfs(PruneData *pd, int d, Move *ms);
-static void genptable_branch(PruneData *pd, uint64_t i, int d, Move *m);
-static void gensym(SymData *sd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-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_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_symdata();
-static void init_trans();
-static void init_trans_aux();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Estimator f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static int ptableval_index(PruneData *pd, uint64_t ind);
-static void realloc_alg(Alg *alg, int n);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_symdata_file(SymData *sd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_symdata_file(SymData *sd);
-static bool write_ttables_file();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * rotation_algs[NROTATIONS];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-Trans
-trans_group_trivial[1] = { uf };
-
-Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 2;
-static SymData * all_sd[2] = { &sd_coud_16, &sd_eofbepos_16 };
-
-/* Coordinates and their implementation **************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-static uint64_t index_eofbepos_sym16(Cube cube);
-static uint64_t index_drud_sym16(Cube cube);
-static uint64_t index_khuge(Cube cube);
-
-static Cube antindex_eofb(uint64_t ind);
-static Cube antindex_eofbepos(uint64_t ind);
-static Cube antindex_coud(uint64_t ind);
-static Cube antindex_corners(uint64_t ind);
-static Cube antindex_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-static Cube antindex_eofbepos_sym16(uint64_t ind);
-static Cube antindex_drud_sym16(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430
-};
-
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-
-/* TODO: rename */
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- return admissible_ee_aux[ind];
-}
-
-/* TODO: rename */
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-/* DONE: temporary fix, make it better */
-static Cube
-antindex_drud(uint64_t ind)
-{
- uint64_t epos, eofb;
- Cube c;
-
- eofb = ind % POW2TO11;
- epos = ind / (POW2TO11 * POW3TO7);
- c = admissible_ee_aux[eofb + POW2TO11 * epos];
-
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.corl = c.coud;
- c.cofb = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_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 = sd_eofbepos_16.rep[ind/POW3TO7];
- c.coud = ind % POW3TO7;
- c.cofb = c.coud;
- c.corl = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-
-/* Checkers ******************************************************************/
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Local functions implementation ********************************************/
-
-/* TODO: this should be an anti index (maybe?) */
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s.estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_bfs(PruneData *pd, int d, Move *ms)
-{
- uint64_t i;
-
- for (i = 0; i < pd->coord->max; i++)
- if (ptableval_index(pd, i) == d)
- genptable_branch(pd, i, d, ms);
-}
-
-static void
-genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms)
-{
- int i, j;
- Cube cc, c;
-
-
- for (i = 0; i < pd->ntrans; i++) {
- c = apply_trans(pd->trans[i], pd->coord->cube(ind));
- for (j = 0; ms[j] != NULLMOVE; j++) {
- cc = apply_move(ms[j], c);
- if (ptableval(pd, cc) > d+1)
- ptable_update(pd, cc, d+1);
- }
- }
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Estimator f, Move *r)
-{
- CubeTarget ct = { .target = 1 };
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- ct.cube = apply_move(i, (Cube){0});
- if (f != NULL && f(ct))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static int
-ptableval_index(PruneData *pd, uint64_t ind)
-{
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_algs[r % NROTATIONS]);
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_algs[r % NROTATIONS], ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[uf_mirror] = uf_mirror;
- inverse_trans_aux[ur_mirror] = ur_mirror;
- inverse_trans_aux[ul_mirror] = ul_mirror;
- inverse_trans_aux[ub_mirror] = ub_mirror;
-
- inverse_trans_aux[df_mirror] = df_mirror;
- inverse_trans_aux[dr_mirror] = dl_mirror;
- inverse_trans_aux[dl_mirror] = dr_mirror;
- inverse_trans_aux[db_mirror] = db_mirror;
-
- inverse_trans_aux[rf_mirror] = rf_mirror;
- inverse_trans_aux[rd_mirror] = br_mirror;
- inverse_trans_aux[rb_mirror] = lb_mirror;
- inverse_trans_aux[ru_mirror] = fl_mirror;
-
- inverse_trans_aux[lf_mirror] = lf_mirror;
- inverse_trans_aux[ld_mirror] = bl_mirror;
- inverse_trans_aux[lb_mirror] = rb_mirror;
- inverse_trans_aux[lu_mirror] = fr_mirror;
-
- inverse_trans_aux[fu_mirror] = fu_mirror;
- inverse_trans_aux[fr_mirror] = lu_mirror;
- inverse_trans_aux[fd_mirror] = bu_mirror;
- inverse_trans_aux[fl_mirror] = ru_mirror;
-
- inverse_trans_aux[bu_mirror] = fd_mirror;
- inverse_trans_aux[br_mirror] = rd_mirror;
- inverse_trans_aux[bd_mirror] = bd_mirror;
- inverse_trans_aux[bl_mirror] = ld_mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-static void
-init_trans() {
- Cube aux, cube, mirr, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_algs[i % NROTATIONS], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m % NROTATIONS], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move_aux[move], aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube, false) ||
- is_solved(mirr, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- rotation_algs[uf] = new_alg("");
- rotation_algs[ur] = new_alg("y");
- rotation_algs[ub] = new_alg("y2");
- rotation_algs[ul] = new_alg("y3");
-
- rotation_algs[df] = new_alg("z2");
- rotation_algs[dr] = new_alg("y z2");
- rotation_algs[db] = new_alg("x2");
- rotation_algs[dl] = new_alg("y3 z2");
-
- rotation_algs[rf] = new_alg("z3");
- rotation_algs[rd] = new_alg("z3 y");
- rotation_algs[rb] = new_alg("z3 y2");
- rotation_algs[ru] = new_alg("z3 y3");
-
- rotation_algs[lf] = new_alg("z");
- rotation_algs[ld] = new_alg("z y3");
- rotation_algs[lb] = new_alg("z y2");
- rotation_algs[lu] = new_alg("z y");
-
- rotation_algs[fu] = new_alg("x y2");
- rotation_algs[fr] = new_alg("x y");
- rotation_algs[fd] = new_alg("x");
- rotation_algs[fl] = new_alg("x y3");
-
- rotation_algs[bu] = new_alg("x3");
- rotation_algs[br] = new_alg("x3 y");
- rotation_algs[bd] = new_alg("x3 y2");
- rotation_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genptable(PruneData *pd)
-{
- Move ms[NMOVES];
- int d;
- uint64_t j, oldn = 0;
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- moveset_to_list(pd->moveset, NULL, ms);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update(pd, pd->coord->cube(j), 15);
-
- /*TODO: change, set to 0 for every solved state (might be more than 1)*/
- ptable_update(pd, (Cube){0}, 0);
- pd->n = 1;
-
- for (d = 0; d < 15 && pd->n < pd->coord->max; d++) {
- genptable_bfs(pd, d, ms);
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- d, pd->n - oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-/* TODO: clean pre_trans or put it back */
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- /*AlgListNode *node;*/
- AlgList *sols = new_alglist();
- /*Cube c = apply_trans(opts->pre_trans, cube);*/
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(cube)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.estimate, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(cube, step, opts, &dd);
- }
-
-/*
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(opts->pre_trans), node->alg);
-*/
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval(pd, pd->coord->cube(i))]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- return ptableval_index(pd, pd->coord->index(cube));
-}
-
-Alg *
-rotation_alg(Trans i)
-{
- return rotation_algs[i % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
- init_symdata();
-}
-
diff --git a/old/2021-07-15-almostbeforerefactor/alg.h b/old/2021-07-15-almostbeforerefactor/alg.h
@@ -1,27 +0,0 @@
-#ifndef ALG_H
-#define ALG_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "macros.h"
-#include "cubetypes.h"
-
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Move inverse_move(Move m);
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-Alg * new_alg(char *str);
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-Alg * rotation_alg(Trans i);
-void transform_alg(Trans t, Alg *alg);
-
-#endif
-
diff --git a/old/2021-07-15-almostbeforerefactor/cube.c b/old/2021-07-15-almostbeforerefactor/cube.c
@@ -1,3391 +0,0 @@
-#include "cube.h"
-
-/* TODO: remove! */
-#include "steps.h"
-
-/* Local functions **********************************************************/
-
-static Cube admissible_ep(Cube cube, PieceFilter f);
-static Cube admissible_eos_from_eofbepos(Cube cube);
-static bool allowed_next(Move move, DfsData *dd);
-static void append_alg(AlgList *l, Alg *alg);
-static void append_move(Alg *alg, Move m, bool inverse);
-static Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-static void apply_permutation(int *perm, int *set, int n);
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static Cube arrays_to_cube(CubeArray *arr, PieceFilter f);
-static int binomial(int n, int k);
-static Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-static void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-static void dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_check_solved(SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd);
-static int digit_array_to_int(int *a, int n, int b);
-static int edge_slice(Edge e); /* E=0, S=1, M=2 */
-static int epos_dependent_pos(int pos1, int pos2);
-static int epos_from_arrays(int *epos, int *ep);
-static void epos_to_partial_ep(int epos, int *ep, int *ss);
-static int factorial(int n);
-static void free_alglistnode(AlgListNode *aln);
-static void free_cubearray(CubeArray *arr, PieceFilter f);
-static void genptable_bfs(PruneData *pd, int d, Move *ms);
-static void genptable_branch(PruneData *pd, uint64_t i, int d, Move *m);
-static void gensym(SymData *sd);
-static void index_to_perm(int p, int n, int *r);
-static void index_to_subset(int s, int n, int k, int *r);
-static void init_auxtables();
-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_environment();
-static void init_moves();
-static void init_moves_aux();
-static void init_strings();
-static void init_symdata();
-static void init_trans();
-static void init_trans_aux();
-static void int_to_digit_array(int a, int b, int n, int *r);
-static void int_to_sum_zero_array(int x, int b, int n, int *a);
-static int invert_digits(int a, int b, int n);
-static bool is_perm(int *a, int n);
-static bool is_subset(int *a, int n, int k);
-static Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-static void movelist_to_position(Move *movelist, int *position);
-static void moveset_to_list(Moveset ms, Estimator f, Move *r);
-static AlgList * new_alglist();
-static CubeArray * new_cubearray(Cube cube, PieceFilter f);
-static int perm_sign(int *a, int n);
-static int perm_to_index(int *a, int n);
-static int powint(int a, int b);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static int ptableval_index(PruneData *pd, uint64_t ind);
-static void realloc_alg(Alg *alg, int n);
-static bool read_mtables_file();
-static bool read_ptable_file(PruneData *pd);
-static bool read_symdata_file(SymData *sd);
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static int subset_to_index(int *a, int n, int k);
-static void sum_arrays_mod(int *src, int *dst, int n, int m);
-static void swap(int *a, int *b);
-static bool write_mtables_file();
-static bool write_ptable_file(PruneData *pd);
-static bool write_symdata_file(SymData *sd);
-static bool write_ttables_file();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static char * tabledir;
-
-static PieceFilter pf_all;
-static PieceFilter pf_4val;
-static PieceFilter pf_epcp;
-static PieceFilter pf_cpos;
-static PieceFilter pf_cp;
-static PieceFilter pf_ep;
-static PieceFilter pf_e;
-static PieceFilter pf_s;
-static PieceFilter pf_m;
-static PieceFilter pf_eo;
-static PieceFilter pf_co;
-
-static int epe_solved[4];
-static int eps_solved[4];
-static int epm_solved[4];
-
-static char move_string[NMOVES][7];
-static char edge_string[12][7];
-static char corner_string[8][7];
-static char center_string[6][7];
-
-static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
-static bool commute[NMOVES][NMOVES];
-static bool possible_next[NMOVES][NMOVES][NMOVES];
-static Move inverse_move_aux[NMOVES];
-static Trans inverse_trans_aux[NTRANS];
-static int epos_dependent_aux[BINOM12ON4][BINOM12ON4];
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static Center what_center_at_aux[FACTORIAL6][6];
-static Corner what_corner_at_aux[FACTORIAL8][8];
-static int what_orientation_last_corner_aux[POW3TO7];
-static int what_orientation_last_edge_aux[POW2TO11];
-static Center where_is_center_aux[FACTORIAL6][6];
-static Corner where_is_corner_aux[FACTORIAL8][8];
-static Edge where_is_edge_aux[3][FACTORIAL12/FACTORIAL8][12];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-static uint64_t me[12];
-
-static int edge_cycle[NMOVES][12];
-static int corner_cycle[NMOVES][8];
-static int center_cycle[NMOVES][6];
-static int eofb_flipped[NMOVES][12];
-static int eorl_flipped[NMOVES][12];
-static int eoud_flipped[NMOVES][12];
-static int coud_flipped[NMOVES][8];
-static int corl_flipped[NMOVES][8];
-static int cofb_flipped[NMOVES][8];
-static Alg * equiv_alg[NMOVES];
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-static int ep_mirror[12];
-static int cp_mirror[8];
-static int cpos_mirror[6];
-static Alg * rotation_algs[NROTATIONS];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-Trans
-trans_group_trivial[1] = { uf };
-
-Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 2;
-static SymData * all_sd[2] = { &sd_coud_16, &sd_eofbepos_16 };
-
-/* Coordinates and their implementation **************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-static uint64_t index_eofbepos_sym16(Cube cube);
-static uint64_t index_drud_sym16(Cube cube);
-static uint64_t index_khuge(Cube cube);
-
-static Cube antindex_eofb(uint64_t ind);
-static Cube antindex_eofbepos(uint64_t ind);
-static Cube antindex_coud(uint64_t ind);
-static Cube antindex_corners(uint64_t ind);
-static Cube antindex_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-static Cube antindex_eofbepos_sym16(uint64_t ind);
-static Cube antindex_drud_sym16(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430
-};
-
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-
-/* TODO: rename */
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- return admissible_ee_aux[ind];
-}
-
-/* TODO: rename */
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-/* TODO: admissible co for other orientations */
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-/* DONE: temporary fix, make it better */
-static Cube
-antindex_drud(uint64_t ind)
-{
- uint64_t epos, eofb;
- Cube c;
-
- eofb = ind % POW2TO11;
- epos = ind / (POW2TO11 * POW3TO7);
- c = admissible_ee_aux[eofb + POW2TO11 * epos];
-
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.corl = c.coud;
- c.cofb = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_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 = sd_eofbepos_16.rep[ind/POW3TO7];
- c.coud = ind % POW3TO7;
- c.cofb = c.coud;
- c.corl = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-
-/* Checkers ******************************************************************/
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-
-/* Local functions implementation ********************************************/
-
-/* TODO: this should be an anti index (maybe?) */
-static Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
- if (!possible_next[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-static void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-static Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-static void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-static int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-static Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-static void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-/*
-static int
-cphtr_cp(int cp)
-{
- int i, a[8];
-
- index_to_perm(cp, 8, a);
-
- for (i = 0; i < 8; i++)
- if (a[i] == UFR || a[i] == UBL || a[i] == DFL || a[i] == DBR)
- a[i] = 0;
- else
- a[i] = 1;
-
- swap(&a[1], &a[5]);
- swap(&a[3], &a[7]);
-
- return subset_to_index(a, 8, 4);
-}
-*/
-
-static void
-dfs(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s.estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s.estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-static int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-static int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-static void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-static int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-static void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-static void
-genptable_bfs(PruneData *pd, int d, Move *ms)
-{
- uint64_t i;
-
- for (i = 0; i < pd->coord->max; i++)
- if (ptableval_index(pd, i) == d)
- genptable_branch(pd, i, d, ms);
-}
-
-static void
-genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms)
-{
- int i, j;
- Cube cc, c;
-
-
- for (i = 0; i < pd->ntrans; i++) {
- c = apply_trans(pd->trans[i], pd->coord->cube(ind));
- for (j = 0; ms[j] != NULLMOVE; j++) {
- cc = apply_move(ms[j], c);
- if (ptableval(pd, cc) > d+1)
- ptable_update(pd, cc, d+1);
- }
- }
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-static void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-static void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-static void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-static int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-static bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-static bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-static Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-static void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-static void
-moveset_to_list(Moveset ms, Estimator f, Move *r)
-{
- CubeTarget ct = { .target = 1 };
- int b[NMOVES];
- int na = 0, nb = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++) {
- if (ms(i)) {
- ct.cube = apply_move(i, (Cube){0});
- if (f != NULL && f(ct))
- r[na++] = i;
- else
- b[nb++] = i;
- }
- }
-
- memcpy(r + na, b, nb * sizeof(Move));
- r[na+nb] = NULLMOVE;
-}
-
-static AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-static CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-static int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-static int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-static int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-static int
-ptableval_index(PruneData *pd, uint64_t ind)
-{
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
-static bool
-read_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-read_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fread(co_ttable[m], b, me[7], f) == me[7];
- r = r && fread(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fread(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_algs[r % NROTATIONS]);
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_algs[r % NROTATIONS], ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-static void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-static void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-static bool
-write_mtables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_ttables_file()
-{
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(co_ttable[m], b, me[7], f) == me[7];
- r = r && fwrite(cpos_ttable[m], b, me[10], f) == me[10];
- r = r && fwrite(moves_ttable[m], b, me[11], f) == me[11];
- }
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-static void
-init_auxtables()
-{
- Cube c1, c2;
- CubeArray *arr;
- uint64_t ui, uj;
- int i, j, k, auxarr[12];
- bool cij, p1, p2;
-
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++) {
- what_center_at_aux[ui][i] = arr->cpos[i];
- where_is_center_aux[ui][arr->cpos[i]] = i;
- }
- free_cubearray(arr, pf_cpos);
- }
-
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++) {
- what_corner_at_aux[ui][i] = arr->cp[i];
- where_is_corner_aux[ui][arr->cp[i]] = i;
- }
- free_cubearray(arr, pf_cp);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- where_is_edge_aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- where_is_edge_aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- where_is_edge_aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- what_orientation_last_corner_aux[ui] = auxarr[7];
- }
-
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- what_orientation_last_edge_aux[ui] = auxarr[11];
- }
-
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- epos_dependent_aux[ui][uj]=epos_dependent_pos(ui, uj);
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- possible_next[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- for (i = 0; i < NMOVES; i++)
- inverse_move_aux[i] = i ? i + 2 - 2*((i-1)%3) : NULLMOVE;
-
- /* Is there a more elegant way? */
- inverse_trans_aux[uf] = uf;
- inverse_trans_aux[ur] = ul;
- inverse_trans_aux[ul] = ur;
- inverse_trans_aux[ub] = ub;
-
- inverse_trans_aux[df] = df;
- inverse_trans_aux[dr] = dr;
- inverse_trans_aux[dl] = dl;
- inverse_trans_aux[db] = db;
-
- inverse_trans_aux[rf] = lf;
- inverse_trans_aux[rd] = bl;
- inverse_trans_aux[rb] = rb;
- inverse_trans_aux[ru] = fr;
-
- inverse_trans_aux[lf] = rf;
- inverse_trans_aux[ld] = br;
- inverse_trans_aux[lb] = lb;
- inverse_trans_aux[lu] = fl;
-
- inverse_trans_aux[fu] = fu;
- inverse_trans_aux[fr] = ru;
- inverse_trans_aux[fd] = bu;
- inverse_trans_aux[fl] = lu;
-
- inverse_trans_aux[bu] = fd;
- inverse_trans_aux[br] = ld;
- inverse_trans_aux[bd] = bd;
- inverse_trans_aux[bl] = rd;
-
- inverse_trans_aux[uf_mirror] = uf_mirror;
- inverse_trans_aux[ur_mirror] = ur_mirror;
- inverse_trans_aux[ul_mirror] = ul_mirror;
- inverse_trans_aux[ub_mirror] = ub_mirror;
-
- inverse_trans_aux[df_mirror] = df_mirror;
- inverse_trans_aux[dr_mirror] = dl_mirror;
- inverse_trans_aux[dl_mirror] = dr_mirror;
- inverse_trans_aux[db_mirror] = db_mirror;
-
- inverse_trans_aux[rf_mirror] = rf_mirror;
- inverse_trans_aux[rd_mirror] = br_mirror;
- inverse_trans_aux[rb_mirror] = lb_mirror;
- inverse_trans_aux[ru_mirror] = fl_mirror;
-
- inverse_trans_aux[lf_mirror] = lf_mirror;
- inverse_trans_aux[ld_mirror] = bl_mirror;
- inverse_trans_aux[lb_mirror] = rb_mirror;
- inverse_trans_aux[lu_mirror] = fr_mirror;
-
- inverse_trans_aux[fu_mirror] = fu_mirror;
- inverse_trans_aux[fr_mirror] = lu_mirror;
- inverse_trans_aux[fd_mirror] = bu_mirror;
- inverse_trans_aux[fl_mirror] = ru_mirror;
-
- inverse_trans_aux[bu_mirror] = fd_mirror;
- inverse_trans_aux[br_mirror] = rd_mirror;
- inverse_trans_aux[bd_mirror] = bd_mirror;
- inverse_trans_aux[bl_mirror] = ld_mirror;
-}
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- jj = cp_mtable[moves[k]][next[j]];
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_environment()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-}
-
-static void
-init_moves() {
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-}
-
-static void
-init_moves_aux()
-{
- /* Some standard PieceFilters */
- pf_all.epose = true;
- pf_all.eposs = true;
- pf_all.eposm = true;
- pf_all.eofb = true;
- pf_all.eorl = true;
- pf_all.eoud = true;
- pf_all.cp = true;
- pf_all.cofb = true;
- pf_all.corl = true;
- pf_all.coud = true;
- pf_all.cpos = true;
-
- pf_4val.epose = true;
- pf_4val.eposs = true;
- pf_4val.eposm = true;
- pf_4val.eofb = true;
- pf_4val.coud = true;
- pf_4val.cp = true;
-
- pf_epcp.epose = true;
- pf_epcp.eposs = true;
- pf_epcp.eposm = true;
- pf_epcp.cp = true;
-
- pf_cpos.cpos = true;
-
- pf_cp.cp = true;
-
- pf_ep.epose = true;
- pf_ep.eposs = true;
- pf_ep.eposm = true;
-
- pf_e.epose = true;
- pf_s.eposs = true;
- pf_m.eposm = true;
-
- pf_eo.eofb = true;
- pf_eo.eorl = true;
- pf_eo.eoud = true;
-
- pf_co.cofb = true;
- pf_co.corl = true;
- pf_co.coud = true;
-
- /* Used to convert to and from CubeArray */
- epe_solved[0] = FR;
- epe_solved[1] = FL;
- epe_solved[2] = BL;
- epe_solved[3] = BR;
-
- eps_solved[0] = UL;
- eps_solved[1] = UR;
- eps_solved[2] = DL;
- eps_solved[3] = DR;
-
- epm_solved[0] = UF;
- epm_solved[1] = UB;
- epm_solved[2] = DF;
- epm_solved[3] = DB;
-
- /* Table sizes, used for reading and writing files */
- me[0] = FACTORIAL12/FACTORIAL8;
- me[1] = FACTORIAL12/FACTORIAL8;
- me[2] = FACTORIAL12/FACTORIAL8;
- me[3] = POW2TO11;
- me[4] = POW2TO11;
- me[5] = POW2TO11;
- me[6] = FACTORIAL8;
- me[7] = POW3TO7;
- me[8] = POW3TO7;
- me[9] = POW3TO7;
- me[10] = FACTORIAL6;
- me[11] = NMOVES;
-
- /* Cycles *********************/
- edge_cycle[U][UF] = UR;
- edge_cycle[U][UL] = UF;
- edge_cycle[U][UB] = UL;
- edge_cycle[U][UR] = UB;
- edge_cycle[U][DF] = DF;
- edge_cycle[U][DL] = DL;
- edge_cycle[U][DB] = DB;
- edge_cycle[U][DR] = DR;
- edge_cycle[U][FR] = FR;
- edge_cycle[U][FL] = FL;
- edge_cycle[U][BL] = BL;
- edge_cycle[U][BR] = BR;
-
- edge_cycle[x][UF] = DF;
- edge_cycle[x][UL] = FL;
- edge_cycle[x][UB] = UF;
- edge_cycle[x][UR] = FR;
- edge_cycle[x][DF] = DB;
- edge_cycle[x][DL] = BL;
- edge_cycle[x][DB] = UB;
- edge_cycle[x][DR] = BR;
- edge_cycle[x][FR] = DR;
- edge_cycle[x][FL] = DL;
- edge_cycle[x][BL] = UL;
- edge_cycle[x][BR] = UR;
-
- edge_cycle[y][UF] = UR;
- edge_cycle[y][UL] = UF;
- edge_cycle[y][UB] = UL;
- edge_cycle[y][UR] = UB;
- edge_cycle[y][DF] = DR;
- edge_cycle[y][DL] = DF;
- edge_cycle[y][DB] = DL;
- edge_cycle[y][DR] = DB;
- edge_cycle[y][FR] = BR;
- edge_cycle[y][FL] = FR;
- edge_cycle[y][BL] = FL;
- edge_cycle[y][BR] = BL;
-
- corner_cycle[U][UFR] = UBR;
- corner_cycle[U][UFL] = UFR;
- corner_cycle[U][UBL] = UFL;
- corner_cycle[U][UBR] = UBL;
- corner_cycle[U][DFR] = DFR;
- corner_cycle[U][DFL] = DFL;
- corner_cycle[U][DBL] = DBL;
- corner_cycle[U][DBR] = DBR;
-
- corner_cycle[x][UFR] = DFR;
- corner_cycle[x][UFL] = DFL;
- corner_cycle[x][UBL] = UFL;
- corner_cycle[x][UBR] = UFR;
- corner_cycle[x][DFR] = DBR;
- corner_cycle[x][DFL] = DBL;
- corner_cycle[x][DBL] = UBL;
- corner_cycle[x][DBR] = UBR;
-
- corner_cycle[y][UFR] = UBR;
- corner_cycle[y][UFL] = UFR;
- corner_cycle[y][UBL] = UFL;
- corner_cycle[y][UBR] = UBL;
- corner_cycle[y][DFR] = DBR;
- corner_cycle[y][DFL] = DFR;
- corner_cycle[y][DBL] = DFL;
- corner_cycle[y][DBR] = DBL;
-
- center_cycle[U][U_center] = U_center;
- center_cycle[U][D_center] = D_center;
- center_cycle[U][R_center] = R_center;
- center_cycle[U][L_center] = L_center;
- center_cycle[U][F_center] = F_center;
- center_cycle[U][B_center] = B_center;
-
- center_cycle[x][U_center] = F_center;
- center_cycle[x][D_center] = B_center;
- center_cycle[x][R_center] = R_center;
- center_cycle[x][L_center] = L_center;
- center_cycle[x][F_center] = D_center;
- center_cycle[x][B_center] = U_center;
-
- center_cycle[y][U_center] = U_center;
- center_cycle[y][D_center] = D_center;
- center_cycle[y][R_center] = B_center;
- center_cycle[y][L_center] = F_center;
- center_cycle[y][F_center] = R_center;
- center_cycle[y][B_center] = L_center;
-
- /* Flipped pieces *************/
- eofb_flipped[x][UF] = 1;
- eofb_flipped[x][UB] = 1;
- eofb_flipped[x][DF] = 1;
- eofb_flipped[x][DB] = 1;
-
- eofb_flipped[y][FR] = 1;
- eofb_flipped[y][FL] = 1;
- eofb_flipped[y][BL] = 1;
- eofb_flipped[y][BR] = 1;
-
- eorl_flipped[x][UF] = 1;
- eorl_flipped[x][UL] = 1;
- eorl_flipped[x][UB] = 1;
- eorl_flipped[x][UR] = 1;
- eorl_flipped[x][DF] = 1;
- eorl_flipped[x][DL] = 1;
- eorl_flipped[x][DB] = 1;
- eorl_flipped[x][DR] = 1;
- eorl_flipped[x][FR] = 1;
- eorl_flipped[x][FL] = 1;
- eorl_flipped[x][BL] = 1;
- eorl_flipped[x][BR] = 1;
-
- eorl_flipped[y][FR] = 1;
- eorl_flipped[y][FL] = 1;
- eorl_flipped[y][BL] = 1;
- eorl_flipped[y][BR] = 1;
-
- eoud_flipped[U][UF] = 1;
- eoud_flipped[U][UL] = 1;
- eoud_flipped[U][UB] = 1;
- eoud_flipped[U][UR] = 1;
-
- eoud_flipped[x][UF] = 1;
- eoud_flipped[x][UB] = 1;
- eoud_flipped[x][DF] = 1;
- eoud_flipped[x][DB] = 1;
-
- eoud_flipped[y][UF] = 1;
- eoud_flipped[y][UL] = 1;
- eoud_flipped[y][UB] = 1;
- eoud_flipped[y][UR] = 1;
- eoud_flipped[y][DF] = 1;
- eoud_flipped[y][DL] = 1;
- eoud_flipped[y][DB] = 1;
- eoud_flipped[y][DR] = 1;
- eoud_flipped[y][FR] = 1;
- eoud_flipped[y][FL] = 1;
- eoud_flipped[y][BL] = 1;
- eoud_flipped[y][BR] = 1;
-
- coud_flipped[x][UFR] = 2;
- coud_flipped[x][UFL] = 1;
- coud_flipped[x][UBR] = 1;
- coud_flipped[x][UBL] = 2;
- coud_flipped[x][DFR] = 1;
- coud_flipped[x][DFL] = 2;
- coud_flipped[x][DBR] = 2;
- coud_flipped[x][DBL] = 1;
-
- corl_flipped[U][UFR] = 1;
- corl_flipped[U][UFL] = 2;
- corl_flipped[U][UBL] = 1;
- corl_flipped[U][UBR] = 2;
-
- corl_flipped[y][UFR] = 1;
- corl_flipped[y][UFL] = 2;
- corl_flipped[y][UBL] = 1;
- corl_flipped[y][UBR] = 2;
- corl_flipped[y][DFR] = 2;
- corl_flipped[y][DFL] = 1;
- corl_flipped[y][DBL] = 2;
- corl_flipped[y][DBR] = 1;
-
- cofb_flipped[U][UFR] = 2;
- cofb_flipped[U][UFL] = 1;
- cofb_flipped[U][UBL] = 2;
- cofb_flipped[U][UBR] = 1;
-
- cofb_flipped[x][UFR] = 1;
- cofb_flipped[x][UFL] = 2;
- cofb_flipped[x][UBL] = 1;
- cofb_flipped[x][UBR] = 2;
- cofb_flipped[x][DFR] = 2;
- cofb_flipped[x][DFL] = 1;
- cofb_flipped[x][DBL] = 2;
- cofb_flipped[x][DBR] = 1;
-
- cofb_flipped[y][UFR] = 2;
- cofb_flipped[y][UFL] = 1;
- cofb_flipped[y][UBL] = 2;
- cofb_flipped[y][UBR] = 1;
- cofb_flipped[y][DFR] = 1;
- cofb_flipped[y][DFL] = 2;
- cofb_flipped[y][DBL] = 1;
- cofb_flipped[y][DBR] = 2;
-
- /* Equivalent moves ***********/
- equiv_alg[NULLMOVE] = new_alg("");
-
- equiv_alg[U] = new_alg(" U ");
- equiv_alg[U2] = new_alg(" UU ");
- equiv_alg[U3] = new_alg(" UUU ");
- equiv_alg[D] = new_alg(" xx U xx ");
- equiv_alg[D2] = new_alg(" xx UU xx ");
- equiv_alg[D3] = new_alg(" xx UUU xx ");
- equiv_alg[R] = new_alg(" yx U xxxyyy ");
- equiv_alg[R2] = new_alg(" yx UU xxxyyy ");
- equiv_alg[R3] = new_alg(" yx UUU xxxyyy ");
- equiv_alg[L] = new_alg(" yyyx U xxxy ");
- equiv_alg[L2] = new_alg(" yyyx UU xxxy ");
- equiv_alg[L3] = new_alg(" yyyx UUU xxxy ");
- equiv_alg[F] = new_alg(" x U xxx ");
- equiv_alg[F2] = new_alg(" x UU xxx ");
- equiv_alg[F3] = new_alg(" x UUU xxx ");
- equiv_alg[B] = new_alg(" xxx U x ");
- equiv_alg[B2] = new_alg(" xxx UU x ");
- equiv_alg[B3] = new_alg(" xxx UUU x ");
-
- equiv_alg[Uw] = new_alg(" xx U xx y ");
- equiv_alg[Uw2] = new_alg(" xx UU xx yy ");
- equiv_alg[Uw3] = new_alg(" xx UUU xx yyy ");
- equiv_alg[Dw] = new_alg(" U yyy ");
- equiv_alg[Dw2] = new_alg(" UU yy ");
- equiv_alg[Dw3] = new_alg(" UUU y ");
- equiv_alg[Rw] = new_alg(" yyyx U xxxy x ");
- equiv_alg[Rw2] = new_alg(" yyyx UU xxxy xx ");
- equiv_alg[Rw3] = new_alg(" yyyx UUU xxxy xxx ");
- equiv_alg[Lw] = new_alg(" yx U xxxyyy xxx ");
- equiv_alg[Lw2] = new_alg(" yx UU xxxyyy xx ");
- equiv_alg[Lw3] = new_alg(" yx UUU xxxyyy x ");
- equiv_alg[Fw] = new_alg(" xxx U x yxxxyyy ");
- equiv_alg[Fw2] = new_alg(" xxx UU x yxxyyy ");
- equiv_alg[Fw3] = new_alg(" xxx UUU x yxyyy ");
- equiv_alg[Bw] = new_alg(" x U xxx yxyyy ");
- equiv_alg[Bw2] = new_alg(" x UU xxx yxxyyy ");
- equiv_alg[Bw3] = new_alg(" x UUU xxx yxxxyyy ");
-
- equiv_alg[M] = new_alg(" yx U xx UUU yxyyy ");
- equiv_alg[M2] = new_alg(" yx UU xx UU xxxy ");
- equiv_alg[M3] = new_alg(" yx UUU xx U yxxxy ");
- equiv_alg[S] = new_alg(" x UUU xx U yyyx ");
- equiv_alg[S2] = new_alg(" x UU xx UU yyx ");
- equiv_alg[S3] = new_alg(" x U xx UUU yx ");
- equiv_alg[E] = new_alg(" U xx UUU xxyyy ");
- equiv_alg[E2] = new_alg(" UU xx UU xxyy ");
- equiv_alg[E3] = new_alg(" UUU xx U xxy ");
-
- equiv_alg[x] = new_alg(" x ");
- equiv_alg[x2] = new_alg(" xx ");
- equiv_alg[x3] = new_alg(" xxx ");
- equiv_alg[y] = new_alg(" y ");
- equiv_alg[y2] = new_alg(" yy ");
- equiv_alg[y3] = new_alg(" yyy ");
- equiv_alg[z] = new_alg(" yyy x y ");
- equiv_alg[z2] = new_alg(" yy xx ");
- equiv_alg[z3] = new_alg(" y x yyy ");
-}
-
-static void
-init_strings()
-{
- strcpy(move_string [NULLMOVE], "-" );
- strcpy(move_string [U], "U" );
- strcpy(move_string [U2], "U2" );
- strcpy(move_string [U3], "U\'" );
- strcpy(move_string [D], "D" );
- strcpy(move_string [D2], "D2" );
- strcpy(move_string [D3], "D\'" );
- strcpy(move_string [R], "R" );
- strcpy(move_string [R2], "R2" );
- strcpy(move_string [R3], "R\'" );
- strcpy(move_string [L], "L" );
- strcpy(move_string [L2], "L2" );
- strcpy(move_string [L3], "L\'" );
- strcpy(move_string [F], "F" );
- strcpy(move_string [F2], "F2" );
- strcpy(move_string [F3], "F\'" );
- strcpy(move_string [B], "B" );
- strcpy(move_string [B2], "B2" );
- strcpy(move_string [B3], "B\'" );
- strcpy(move_string [Uw], "Uw" );
- strcpy(move_string [Uw2], "Uw2" );
- strcpy(move_string [Uw3], "Uw\'" );
- strcpy(move_string [Dw], "Dw" );
- strcpy(move_string [Dw2], "Dw2" );
- strcpy(move_string [Dw3], "Dw\'" );
- strcpy(move_string [Rw], "Rw" );
- strcpy(move_string [Rw2], "Rw2" );
- strcpy(move_string [Rw3], "Rw\'" );
- strcpy(move_string [Lw], "Lw" );
- strcpy(move_string [Lw2], "Lw2" );
- strcpy(move_string [Lw3], "Lw\'" );
- strcpy(move_string [Fw], "Fw" );
- strcpy(move_string [Fw2], "Fw2" );
- strcpy(move_string [Fw3], "Fw\'" );
- strcpy(move_string [Bw], "Bw" );
- strcpy(move_string [Bw2], "Bw2" );
- strcpy(move_string [Bw3], "Bw\'" );
- strcpy(move_string [M], "M" );
- strcpy(move_string [M2], "M2" );
- strcpy(move_string [M3], "M\'" );
- strcpy(move_string [S], "S" );
- strcpy(move_string [S2], "S2" );
- strcpy(move_string [S3], "S\'" );
- strcpy(move_string [E], "E" );
- strcpy(move_string [E2], "E2" );
- strcpy(move_string [E3], "E\'" );
- strcpy(move_string [x], "x" );
- strcpy(move_string [x2], "x2" );
- strcpy(move_string [x3], "x\'" );
- strcpy(move_string [y], "y" );
- strcpy(move_string [y2], "y2" );
- strcpy(move_string [y3], "y\'" );
- strcpy(move_string [z], "z" );
- strcpy(move_string [z2], "z2" );
- strcpy(move_string [z3], "z\'" );
-
- strcpy(edge_string [UF], "UF" );
- strcpy(edge_string [UL], "UL" );
- strcpy(edge_string [UB], "UB" );
- strcpy(edge_string [UR], "UR" );
- strcpy(edge_string [DF], "DF" );
- strcpy(edge_string [DL], "DL" );
- strcpy(edge_string [DB], "DB" );
- strcpy(edge_string [DR], "DR" );
- strcpy(edge_string [FR], "FR" );
- strcpy(edge_string [FL], "FL" );
- strcpy(edge_string [BL], "BL" );
- strcpy(edge_string [BR], "BR" );
-
- strcpy(corner_string [UFR], "UFR" );
- strcpy(corner_string [UFL], "UFL" );
- strcpy(corner_string [UBL], "UBL" );
- strcpy(corner_string [UBR], "UBR" );
- strcpy(corner_string [DFR], "DFR" );
- strcpy(corner_string [DFL], "DFL" );
- strcpy(corner_string [DBL], "DBL" );
- strcpy(corner_string [DBR], "DBR" );
-
- strcpy(center_string [U_center], "U" );
- strcpy(center_string [D_center], "D" );
- strcpy(center_string [R_center], "R" );
- strcpy(center_string [L_center], "L" );
- strcpy(center_string [F_center], "F" );
- strcpy(center_string [B_center], "B" );
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-static void
-init_trans() {
- Cube aux, cube, mirr, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_algs[i % NROTATIONS], (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_algs[m % NROTATIONS], (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move_aux[move], aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube, false) ||
- is_solved(mirr, false))
- moves_ttable[m][mi] = move;
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static void
-init_trans_aux()
-{
- ep_mirror[UF] = UF;
- ep_mirror[UL] = UR;
- ep_mirror[UB] = UB;
- ep_mirror[UR] = UL;
- ep_mirror[DF] = DF;
- ep_mirror[DL] = DR;
- ep_mirror[DB] = DB;
- ep_mirror[DR] = DL;
- ep_mirror[FR] = FL;
- ep_mirror[FL] = FR;
- ep_mirror[BR] = BL;
- ep_mirror[BL] = BR;
-
- cp_mirror[UFR] = UFL;
- cp_mirror[UFL] = UFR;
- cp_mirror[UBL] = UBR;
- cp_mirror[UBR] = UBL;
- cp_mirror[DFR] = DFL;
- cp_mirror[DFL] = DFR;
- cp_mirror[DBL] = DBR;
- cp_mirror[DBR] = DBL;
-
- cpos_mirror[U_center] = U_center;
- cpos_mirror[D_center] = D_center;
- cpos_mirror[R_center] = L_center;
- cpos_mirror[L_center] = R_center;
- cpos_mirror[F_center] = F_center;
- cpos_mirror[B_center] = B_center;
-
- /* Is there a more elegant way? */
- rotation_algs[uf] = new_alg("");
- rotation_algs[ur] = new_alg("y");
- rotation_algs[ub] = new_alg("y2");
- rotation_algs[ul] = new_alg("y3");
-
- rotation_algs[df] = new_alg("z2");
- rotation_algs[dr] = new_alg("y z2");
- rotation_algs[db] = new_alg("x2");
- rotation_algs[dl] = new_alg("y3 z2");
-
- rotation_algs[rf] = new_alg("z3");
- rotation_algs[rd] = new_alg("z3 y");
- rotation_algs[rb] = new_alg("z3 y2");
- rotation_algs[ru] = new_alg("z3 y3");
-
- rotation_algs[lf] = new_alg("z");
- rotation_algs[ld] = new_alg("z y3");
- rotation_algs[lb] = new_alg("z y2");
- rotation_algs[lu] = new_alg("z y");
-
- rotation_algs[fu] = new_alg("x y2");
- rotation_algs[fr] = new_alg("x y");
- rotation_algs[fd] = new_alg("x");
- rotation_algs[fl] = new_alg("x y3");
-
- rotation_algs[bu] = new_alg("x3");
- rotation_algs[br] = new_alg("x3 y");
- rotation_algs[bd] = new_alg("x3 y2");
- rotation_algs[bl] = new_alg("x3 y3");
-}
-
-
-/* Public functions implementation *******************************************/
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- return epos_dependent_aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-void
-genptable(PruneData *pd)
-{
- Move ms[NMOVES];
- int d;
- uint64_t j, oldn = 0;
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe crash gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- moveset_to_list(pd->moveset, NULL, ms);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update(pd, pd->coord->cube(j), 15);
-
- /*TODO: change, set to 0 for every solved state (might be more than 1)*/
- ptable_update(pd, (Cube){0}, 0);
- pd->n = 1;
-
- for (d = 0; d < 15 && pd->n < pd->coord->max; d++) {
- genptable_bfs(pd, d, ms);
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- d, pd->n - oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-
- pd->generated = true;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return inverse_move_aux[m];
-}
-
-Trans
-inverse_trans(Trans t)
-{
- return inverse_trans_aux[t];
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube, bool reorient)
-{
- int i;
-
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
-/*
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[arr->ep[i]]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %c ", arr->eofb[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[arr->cp[i]]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %c ", arr->coud[i] + '0');
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[arr->cpos[i]]);
- printf("\n");
-
- free_cubearray(arr, pf_all);
-*/
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-/* TODO: clean pre_trans or put it back */
-AlgList *
-solve(Cube cube, Step step, SolveOptions *opts)
-{
- /*AlgListNode *node;*/
- AlgList *sols = new_alglist();
- /*Cube c = apply_trans(opts->pre_trans, cube);*/
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step.ready != NULL && !step.ready(cube)) {
- fprintf(stderr, "Cube not ready for solving step\n");
- return sols;
- }
-
- moveset_to_list(step.moveset, step.estimate, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves && !(sols->len && opts->optimal_only);
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(cube, step, opts, &dd);
- }
-
-/*
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(opts->pre_trans), node->alg);
-*/
-
- free_alg(dd.current_alg);
- return sols;
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string[j][0]) {
- m = j;
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1]=='\'' || str[i+1]=='3') {
- m += 2;
- i++;
- }
- append_move(alg, m, niss);
- break;
- }
- }
- }
-
- return alg;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string[alg->move[i]]);
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval(pd, pd->coord->cube(i))]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- return ptableval_index(pd, pd->coord->index(cube));
-}
-
-Alg *
-rotation_alg(Trans i)
-{
- return rotation_algs[i % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- return what_center_at_aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- return what_corner_at_aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return what_orientation_last_corner_aux[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return what_orientation_last_edge_aux[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- return where_is_center_aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- return where_is_corner_aux[cube.cp][c];
-}
-
-
-void
-init()
-{
- /* Order is important! */
- init_environment();
- init_strings();
- init_moves_aux();
- init_moves();
- init_auxtables();
- init_cphtr_cosets();
- init_trans_aux();
- init_trans();
- init_symdata();
-}
-
diff --git a/old/2021-07-15-almostbeforerefactor/cube.h b/old/2021-07-15-almostbeforerefactor/cube.h
@@ -1,79 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "macros.h"
-#include "cubetypes.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_drud;
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_khuge;
-
-extern Trans trans_group_udfix[16];
-extern Trans trans_group_trivial[1];
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_move(Move m, Cube cube);
-Cube apply_trans(Trans t, Cube cube);
-bool block_solved(Cube cube, Block);
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-uint64_t cphtr(Cube cube); /* TODO: rename (something with cosets) */
-Cube anti_cphtr(uint64_t ind); /*TODO also this */
-uint64_t epos_dependent(Cube cube); /* TODO: rename and turn into an indexer */
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-Move inverse_move(Move m);
-Trans inverse_trans(Trans t);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube, bool reorient);
-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 print_cube(Cube cube);
-Cube random_cube();
-AlgList * solve(Cube cube, Step step, SolveOptions *opts);
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, Cube cube);
-
-void init();
-
-#endif
-
diff --git a/old/2021-07-15-almostbeforerefactor/cubetypes.h b/old/2021-07-15-almostbeforerefactor/cubetypes.h
@@ -1,252 +0,0 @@
-#ifndef CUBETYPES_H
-#define CUBETYPES_H
-
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct coordinate Coordinate;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct cubetarget CubeTarget;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-typedef struct symdata SymData;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef bool (*Checker) (Cube);
-typedef int (*Estimator) (CubeTarget);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
- rf_mirror, rd_mirror, rb_mirror, ru_mirror,
- lf_mirror, ld_mirror, lb_mirror, lu_mirror,
- fu_mirror, fr_mirror, fd_mirror, fl_mirror,
- bu_mirror, br_mirror, bd_mirror, bl_mirror,
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-coordinate
-{
- Indexer index;
- AntiIndexer cube;
- Checker check;
- uint64_t max;
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-cubetarget
-{
- Cube cube;
- int target;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- bool generated;
- uint64_t n;
- Coordinate * coord;
- Moveset moveset;
- int ntrans;
- Trans * trans;
-};
-
-struct
-solveoptions
-{
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback;
-};
-
-struct
-step
-{
- Estimator estimate;
- Checker ready;
- Moveset moveset;
-};
-
-struct
-symdata
-{
- char * filename;
- bool generated;
- Coordinate * coord;
- Coordinate * sym_coord;
- int ntrans;
- Trans * trans;
- uint64_t * class;
- Cube * rep;
- Trans * transtorep;
-};
-
-#endif
diff --git a/old/2021-07-15-almostbeforerefactor/macros.h b/old/2021-07-15-almostbeforerefactor/macros.h
@@ -1,23 +0,0 @@
-#ifndef MACROS_H
-#define MACROS_H
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-#define NMOVES (z3+1)
-#define NTRANS 48
-#define NROTATIONS 24
-
-#endif
diff --git a/old/2021-07-15-almostbeforerefactor/main.c b/old/2021-07-15-almostbeforerefactor/main.c
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include "cube.h"
-#include "steps.h"
-
-int main() {
- Alg *algo;
- AlgList *sols;
- Cube cube;
- SolveOptions opts;
- char line[1000];
- int i, ns = 1;
-/* Move m;*/
-/* int nrand = 10000, sum1, sum2;*/
-
- Step *stps[20] = {&optimal_HTM};
- char sss[30][30] = {"Optimal solve"};
-
- opts = (SolveOptions) {
- .min_moves = 0,
- .max_moves = 20,
- .optimal_only = true,
- .max_solutions = 1,
- .can_niss = false,
- .feedback = true,
- };
-
- init();
-
-/*
- srand(time(NULL));
- sum1 = 0;
- sum2 = 0;
- for (i = 0; i < nrand; i++) {
- cube = random_cube();
- sum1 += drud_HTM.estimate((CubeTarget){.cube = cube, .target = 20});
- sum2 += optimal_HTM.estimate((CubeTarget){.cube = cube, .target = 20});
- }
- printf("Average drud pruning: %lf\n", ((double)sum1) / ((double) nrand));
- printf("Average corners htr pruning: %lf\n", ((double)sum2) / ((double) nrand));
-*/
-
-
- printf("Welcome to nissy 2.0! Insert a scramble:\n");
-
- if (fgets(line, 1000, stdin) != NULL) {
- algo = new_alg(line);
- cube = apply_alg(algo, (Cube){0});
-
- for (i = 0; i < ns; i++) {
- sols = solve(cube, *stps[i], &opts);
- printf("%s: %d solutions found:\n", sss[i], sols->len);
- print_alglist(sols, true);
- free_alglist(sols);
- }
- free_alg(algo);
- }
-
- return 0;
-}
-
diff --git a/old/2021-07-15-almostbeforerefactor/nissy b/old/2021-07-15-almostbeforerefactor/nissy
Binary files differ.
diff --git a/old/2021-07-15-almostbeforerefactor/steps.c b/old/2021-07-15-almostbeforerefactor/steps.c
@@ -1,284 +0,0 @@
-#include "steps.h"
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int estimate_eofb_HTM(CubeTarget ct);
-static int estimate_coud_HTM(CubeTarget ct);
-static int estimate_coud_URF(CubeTarget ct);
-static int estimate_corners_HTM(CubeTarget ct);
-static int estimate_cornershtr_HTM(CubeTarget ct);
-static int estimate_corners_URF(CubeTarget ct);
-static int estimate_cornershtr_URF(CubeTarget ct);
-static int estimate_drud_HTM(CubeTarget ct);
-static int estimate_optimal_HTM(CubeTarget ct);
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .estimate = estimate_coud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .estimate = estimate_coud_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .estimate = estimate_corners_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_HTM = {
- .estimate = estimate_cornershtr_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-cornershtr_URF = {
- .estimate = estimate_cornershtr_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-corners_URF = {
- .estimate = estimate_corners_URF,
- .ready = check_nothing,
- .moveset = moveset_URF
-};
-
-Step
-drud_HTM = {
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .estimate = estimate_optimal_HTM,
- .ready = check_centers,
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .coord = &coord_eofb,
- .moveset = moveset_HTM,
- .ntrans = 1,
- .trans = trans_group_trivial
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .coord = &coord_coud,
- .moveset = moveset_HTM,
- .ntrans = 1,
- .trans = trans_group_trivial
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "ptable_cornershtr_withcosets_HTM",
- .coord = &coord_cornershtr,
- .moveset = moveset_HTM,
- .ntrans = 1,
- .trans = trans_group_trivial
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .coord = &coord_corners,
- .moveset = moveset_HTM,
- .ntrans = 1,
- .trans = trans_group_trivial
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .coord = &coord_drud,
- .moveset = moveset_HTM,
- .ntrans = 1,
- .trans = trans_group_trivial
-};
-
-PruneData
-pd_drud_sym16_HTM = {
- .filename = "ptable_drud_sym16_HTM",
- .coord = &coord_drud_sym16,
- .moveset = moveset_HTM,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-PruneData
-pd_khuge_HTM = {
- .filename = "ptable_khuge_HTM",
- .coord = &coord_khuge,
- .moveset = moveset_HTM,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int
-estimate_eofb_HTM(CubeTarget ct)
-{
- if (!pd_eofb_HTM.generated)
- genptable(&pd_eofb_HTM);
-
- return ptableval(&pd_eofb_HTM, ct.cube);
-}
-
-static int
-estimate_coud_HTM(CubeTarget ct)
-{
- if (!pd_coud_HTM.generated)
- genptable(&pd_coud_HTM);
-
- return ptableval(&pd_coud_HTM, ct.cube);
-}
-
-static int
-estimate_coud_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
- CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
-
- int ud = estimate_coud_HTM(ct);
- int rl = estimate_coud_HTM(ct2);
- int fb = estimate_coud_HTM(ct3);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-estimate_corners_HTM(CubeTarget ct)
-{
- if (!pd_corners_HTM.generated)
- genptable(&pd_corners_HTM);
-
- return ptableval(&pd_corners_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_HTM(CubeTarget ct)
-{
- if (!pd_cornershtr_HTM.generated)
- genptable(&pd_cornershtr_HTM);
-
- return ptableval(&pd_cornershtr_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_cornershtr_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_corners_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_corners_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_drud_HTM(CubeTarget ct)
-{
-/*
- if (!pd_drud_HTM.generated)
- genptable(&pd_drud_HTM);
-
- return ptableval(&pd_drud_HTM, ct.cube);
-*/
-
- if (!pd_drud_sym16_HTM.generated)
- genptable(&pd_drud_sym16_HTM);
-
- return ptableval(&pd_drud_sym16_HTM, ct.cube);
-}
-
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- if (!pd_khuge_HTM.generated)
- genptable(&pd_khuge_HTM);
-
- dr1 = ptableval(&pd_khuge_HTM, cube);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(rf, ct.cube);
- dr2 = ptableval(&pd_khuge_HTM, cube);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(fd, ct.cube);
- dr3 = ptableval(&pd_khuge_HTM, cube);
-
- /* Michiel de Bondt's trick */
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- return MAX(ret, dr3);
-}
diff --git a/old/2021-07-15-almostbeforerefactor/steps.h b/old/2021-07-15-almostbeforerefactor/steps.h
@@ -1,24 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-extern Step eofb_HTM;
-extern Step coud_HTM;
-extern Step coud_URF;
-extern Step corners_HTM;
-extern Step cornershtr_HTM;
-extern Step corners_URF;
-extern Step cornershtr_URF;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_cornershtreofb_HTM;
-extern PruneData pd_drud_HTM;
-extern PruneData pd_khuge_HTM;
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/alg.c b/old/2021-11-10-beforeremovingchecker/alg.c
@@ -1,366 +0,0 @@
-#include "alg.h"
-
-/* Local functions ***********************************************************/
-
-static void free_alglistnode(AlgListNode *aln);
-static void realloc_alg(Alg *alg, int n);
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
-bool
-moveset_eofb(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == D || b == R || b == L ||
- ((b == F || b == B) && m == b+1);
-}
-
-bool
-moveset_drud(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == D ||
- ((b == R || b == L || b == F || b == B) && m == b + 1);
-}
-
-bool
-moveset_htr(Move m)
-{
- Move b = base_move(m);
-
- return moveset_HTM(m) && m == b + 1;
-}
-
-
-/* Functions *****************************************************************/
-
-void
-append_alg(AlgList *l, Alg *alg)
-{
- AlgListNode *node = malloc(sizeof(AlgListNode));
- int i;
-
- node->alg = new_alg("");
- for (i = 0; i < alg->len; i++)
- append_move(node->alg, alg->move[i], alg->inv[i]);
- node->next = NULL;
-
- if (++l->len == 1)
- l->first = node;
- else
- l->last->next = node;
- l->last = node;
-}
-
-void
-append_move(Alg *alg, Move m, bool inverse)
-{
- if (alg->len == alg->allocated)
- realloc_alg(alg, 2*alg->len);
-
- alg->move[alg->len] = m;
- alg->inv [alg->len] = inverse;
- alg->len++;
-}
-
-Move
-base_move(Move m)
-{
- if (m == NULLMOVE)
- return NULLMOVE;
- else
- return m - (m-1)%3;
-}
-
-void
-compose_alg(Alg *alg1, Alg *alg2)
-{
- int i;
-
- for (i = 0; i < alg2->len; i++)
- append_move(alg1, alg2->move[i], alg2->inv[i]);
-}
-
-void
-free_alg(Alg *alg)
-{
- free(alg->move);
- free(alg->inv);
- free(alg);
-}
-
-void
-free_alglist(AlgList *l)
-{
- AlgListNode *aux, *i = l->first;
-
- while (i != NULL) {
- aux = i->next;
- free_alglistnode(i);
- i = aux;
- }
- free(l);
-}
-
-static void
-free_alglistnode(AlgListNode *aln)
-{
- free_alg(aln->alg);
- free(aln);
-}
-
-Alg *
-inverse_alg(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = alg->len-1; i >= 0; i--)
- append_move(ret, inverse_move(alg->move[i]), alg->inv[i]);
-
- return ret;
-}
-
-Move
-inverse_move(Move m)
-{
- return m == NULLMOVE ? NULLMOVE : m + 2 - 2*((m-1) % 3);
-}
-
-char *
-move_string(Move m)
-{
- static char move_string_aux[NMOVES][7] = {
- [NULLMOVE] = "-",
- [U] = "U", [U2] = "U2", [U3] = "U\'",
- [D] = "D", [D2] = "D2", [D3] = "D\'",
- [R] = "R", [R2] = "R2", [R3] = "R\'",
- [L] = "L", [L2] = "L2", [L3] = "L\'",
- [F] = "F", [F2] = "F2", [F3] = "F\'",
- [B] = "B", [B2] = "B2", [B3] = "B\'",
- [Uw] = "Uw", [Uw2] = "Uw2", [Uw3] = "Uw\'",
- [Dw] = "Dw", [Dw2] = "Dw2", [Dw3] = "Dw\'",
- [Rw] = "Rw", [Rw2] = "Rw2", [Rw3] = "Rw\'",
- [Lw] = "Lw", [Lw2] = "Lw2", [Lw3] = "Lw\'",
- [Fw] = "Fw", [Fw2] = "Fw2", [Fw3] = "Fw\'",
- [Bw] = "Bw", [Bw2] = "Bw2", [Bw3] = "Bw\'",
- [M] = "M", [M2] = "M2", [M3] = "M\'",
- [E] = "E", [E2] = "E2", [E3] = "E\'",
- [S] = "S", [S2] = "S2", [S3] = "S\'",
- [x] = "x", [x2] = "x2", [x3] = "x\'",
- [y] = "y", [y2] = "y2", [y3] = "y\'",
- [z] = "z", [z2] = "z2", [z3] = "z\'",
- };
-
- return move_string_aux[m];
-}
-
-void
-movelist_to_position(Move *movelist, int *position)
-{
- Move m;
-
- for (m = 0; m < NMOVES && movelist[m] != NULLMOVE; m++)
- position[movelist[m]] = m;
-}
-
-void
-moveset_to_list(Moveset ms, Move *r)
-{
- int n = 0;
- Move i;
-
- if (ms == NULL) {
- fprintf(stderr, "Error: no moveset given\n");
- return;
- }
-
- for (i = U; i < NMOVES; i++)
- if (ms(i))
- r[n++] = i;
-
- r[n] = NULLMOVE;
-}
-
-Alg *
-new_alg(char *str)
-{
- Alg *alg = malloc(sizeof(Alg));
- int i;
- bool niss = false, move_read;
- Move j, m;
-
- alg->move = malloc(30 * sizeof(Move));
- alg->inv = malloc(30 * sizeof(bool));
- alg->allocated = 30;
- alg->len = 0;
-
- for (i = 0; str[i]; i++) {
- if (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
- continue;
-
- if (str[i] == '(' && niss) {
- fprintf(stderr, "Error reading moves: nested ( )\n");
- return alg;
- }
-
- if (str[i] == ')' && !niss) {
- fprintf(stderr, "Error reading moves: unmatched )\n");
- return alg;
- }
-
- if (str[i] == '(' || str[i] == ')') {
- niss = !niss;
- continue;
- }
-
- move_read = false;
- for (j = 0; j < NMOVES; j++) {
- if (str[i] == move_string(j)[0] ||
- (str[i] >= 'a' && str[i] <= 'z' &&
- str[i] == move_string(j)[0]-('A'-'a') && j<=B)) {
- m = j;
- if (str[i] >= 'a' && str[i] <= 'z' && j<=B) {
- m += Uw - U;
- }
- if (m <= B && str[i+1]=='w') {
- m += Uw - U;
- i++;
- }
- if (str[i+1]=='2') {
- m += 1;
- i++;
- } else if (str[i+1] == '\'' ||
- str[i+1] == '3' ||
- str[i+1] == '`' ) {
- m += 2;
- i++;
- } else if ((int)str[i+1] == -62 &&
- (int)str[i+2] == -76) {
- /* Weird apostrophe */
- m += 2;
- i += 2;
- } else if ((int)str[i+1] == -30 &&
- (int)str[i+2] == -128 &&
- (int)str[i+3] == -103) {
- /* MacOS apostrophe */
- m += 2;
- i += 3;
- }
- append_move(alg, m, niss);
- move_read = true;
- break;
- }
- }
-
- if (!move_read) {
- alg = new_alg("");
- return alg;
- }
- }
-
- return alg;
-}
-
-AlgList *
-new_alglist()
-{
- AlgList *ret = malloc(sizeof(AlgList));
-
- ret->len = 0;
- ret->first = NULL;
- ret->last = NULL;
-
- return ret;
-}
-
-Alg *
-on_inverse(Alg *alg)
-{
- Alg *ret = new_alg("");
- int i;
-
- for (i = 0; i < alg->len; i++)
- append_move(ret, alg->move[i], !alg->inv[i]);
-
- return ret;
-}
-
-void
-print_alg(Alg *alg, bool l)
-{
- /* TODO: make it possible to print to stdout or to string */
- /* Maybe just return a string */
- char fill[4];
- int i;
- bool niss = false;
-
- for (i = 0; i < alg->len; i++) {
- if (!niss && alg->inv[i])
- strcpy(fill, i == 0 ? "(" : " (");
- if (niss && !alg->inv[i])
- strcpy(fill, ") ");
- if (niss == alg->inv[i])
- strcpy(fill, i == 0 ? "" : " ");
-
- printf("%s%s", fill, move_string(alg->move[i]));
- niss = alg->inv[i];
- }
-
- if (niss)
- printf(")");
- if (l)
- printf(" (%d)", alg->len);
-
- printf("\n");
-}
-
-void
-print_alglist(AlgList *al, bool l)
-{
- AlgListNode *i;
-
- for (i = al->first; i != NULL; i = i->next)
- print_alg(i->alg, l);
-}
-
-static void
-realloc_alg(Alg *alg, int n)
-{
- if (alg == NULL) {
- fprintf(stderr, "Error: trying to reallocate NULL alg.\n");
- return;
- }
-
- if (n < alg->len) {
- fprintf(stderr, "Error: alg too long for reallocation ");
- fprintf(stderr, "(%d vs %d)\n", alg->len, n);
- return;
- }
-
- if (n > 1000000) {
- fprintf(stderr, "Warning: very long alg,");
- fprintf(stderr, "something might go wrong.\n");
- }
-
- alg->move = realloc(alg->move, n * sizeof(int));
- alg->inv = realloc(alg->inv, n * sizeof(int));
- alg->allocated = n;
-}
-
diff --git a/old/2021-11-10-beforeremovingchecker/alg.h b/old/2021-11-10-beforeremovingchecker/alg.h
@@ -1,35 +0,0 @@
-#ifndef ALG_H
-#define ALG_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cubetypes.h"
-#include "utils.h"
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-bool moveset_eofb(Move m);
-bool moveset_drud(Move m);
-bool moveset_htr(Move m);
-
-void append_alg(AlgList *l, Alg *alg);
-void append_move(Alg *alg, Move m, bool inverse);
-void compose_alg(Alg *alg1, Alg *alg2);
-Move base_move(Move m);
-void free_alg(Alg *alg);
-void free_alglist(AlgList *l);
-Alg * inverse_alg(Alg *alg);
-Move inverse_move(Move m);
-char * move_string(Move m);
-void movelist_to_position(Move *ml, int *pos);
-void moveset_to_list(Moveset ms, Move *lst);
-Alg * new_alg(char *str);
-AlgList * new_alglist();
-Alg * on_inverse(Alg *alg);
-void print_alg(Alg *alg, bool l);
-void print_alglist(AlgList *al, bool l);
-
-#endif
-
diff --git a/old/2021-11-10-beforeremovingchecker/commands.c b/old/2021-11-10-beforeremovingchecker/commands.c
@@ -1,329 +0,0 @@
-#include "commands.h"
-
-/* Arg parsing functions *****************************************************/
-
-CommandArgs * solvestep_parse_args(int c, char **v);
-CommandArgs * help_parse_args(int c, char **v);
-CommandArgs * print_parse_args(int c, char **v);
-CommandArgs * parse_no_arg(int c, char **v);
-
-/* Exec functions ************************************************************/
-
-static void solvestep_exec(CommandArgs *args);
-static void steps_exec(CommandArgs *args);
-static void commands_exec(CommandArgs *args);
-static void print_exec(CommandArgs *args);
-static void help_exec(CommandArgs *args);
-static void quit_exec(CommandArgs *args);
-
-/* Local functions ***********************************************************/
-
-static bool read_step(CommandArgs *args, char *str);
-static bool read_scramble(int c, char **v, CommandArgs *args);
-
-/* Commands ******************************************************************/
-
-Command
-solvestep_cmd = {
- .name = "solve",
- .usage = "solve STEP [OPTIONS] SCRAMBLE",
- .description = "Solve a step",
- .parse_args = solvestep_parse_args,
- .exec = solvestep_exec
-};
-
-Command
-steps_cmd = {
- .name = "steps",
- .usage = "steps",
- .description = "List available steps",
- .parse_args = parse_no_arg,
- .exec = steps_exec
-};
-
-Command
-commands_cmd = {
- .name = "commands",
- .usage = "commands",
- .description = "List available commands",
- .parse_args = parse_no_arg,
- .exec = commands_exec
-};
-
-Command
-print_cmd = {
- .name = "print",
- .usage = "print SCRAMBLE",
- .description = "Print written description of the cube",
- .parse_args = print_parse_args,
- .exec = print_exec,
-};
-
-Command
-help_cmd = {
- .name = "help",
- .usage = "help [COMMAND]",
- .description = "Display nissy manual page or help on specific command",
- .parse_args = help_parse_args,
- .exec = help_exec,
-};
-
-Command
-quit_cmd = {
- .name = "quit",
- .usage = "quit",
- .description = "Quit nissy",
- .parse_args = parse_no_arg,
- .exec = quit_exec,
-};
-
-Command *commands[NCOMMANDS] = {
- &solvestep_cmd,
- &steps_cmd,
- &commands_cmd,
- &help_cmd,
- &print_cmd,
- &quit_cmd
-};
-
-/* Arg parsing functions implementation **************************************/
-
-CommandArgs *
-solvestep_parse_args(int c, char **v)
-{
- int i;
- long val;
-
- CommandArgs *a = malloc(sizeof(CommandArgs));
-
- a->success = false;
- a->opts = malloc(sizeof(SolveOptions));
- a->step = steps[0];
- a->command = NULL;
- a->scramble = NULL;
-
- a->opts->min_moves = 0;
- a->opts->max_moves = 20;
- a->opts->max_solutions = 1;
- a->opts->optimal_only = false;
- a->opts->can_niss = false;
- a->opts->feedback = false;
- a->opts->all = false;
- a->opts->print_number = true;
-
- for (i = 0; i < c; i++) {
- if (!strcmp(v[i], "-m")) {
- val = strtol(v[++i], NULL, 10);
- if (val < 0 || val > 100) {
- fprintf(stderr,
- "Invalid min number of moves.\n");
- return a;
- }
- a->opts->min_moves = val;
- } else if (!strcmp(v[i], "-M")) {
- val = strtol(v[++i], NULL, 10);
- if (val < 0 || val > 100) {
- fprintf(stderr,
- "Invalid max number of moves.\n");
- return a;
- }
- a->opts->max_moves = val;
- } else if (!strcmp(v[i], "-s")) {
- val = strtol(v[++i], NULL, 10);
- if (val < 1 || val > 1000000) {
- fprintf(stderr,
- "Invalid number of solutions.\n");
- return a;
- }
- a->opts->max_solutions = val;
- } else if (!strcmp(v[i], "-o")) {
- a->opts->optimal_only = true;
- } else if (!strcmp(v[i], "-n")) {
- a->opts->can_niss = true;
- } else if (!strcmp(v[i], "-v")) {
- a->opts->feedback = true;
- } else if (!strcmp(v[i], "-a")) {
- a->opts->all = true;
- } else if (!strcmp(v[i], "-p")) {
- a->opts->print_number = false;
- } else if (!read_step(a, v[i])) {
- break;
- }
- }
-
- a->success = read_scramble(c-i, &v[i], a);
- return a;
-}
-
-CommandArgs *
-help_parse_args(int c, char **v)
-{
- int i;
- CommandArgs *a = malloc(sizeof(CommandArgs));
-
- a->scramble = NULL;
- a->opts = NULL;
- a->step = NULL;
- a->command = NULL;
-
- if (c == 1) {
- for (i = 0; i < NCOMMANDS; i++)
- if (commands[i] != NULL &&
- !strcmp(v[0], commands[i]->name))
- a->command = commands[i];
- if (a->command == NULL)
- fprintf(stderr, "%s: command not found\n", v[0]);
- }
-
- a->success = c == 0 || (c == 1 && a->command != NULL);
- return a;
-}
-
-CommandArgs *
-parse_no_arg(int c, char **v)
-{
- CommandArgs *a = malloc(sizeof(CommandArgs));
-
- a->scramble = NULL;
- a->opts = NULL;
- a->step = NULL;
- a->command = NULL;
-
- return a;
-}
-
-CommandArgs *
-print_parse_args(int c, char **v)
-{
- CommandArgs *a = malloc(sizeof(CommandArgs));
-
- a->opts = NULL;
- a->step = NULL;
- a->command = NULL;
-
- a->success = read_scramble(c-1, &v[1], a);
- return a;
-}
-
-/* Exec functions implementation *********************************************/
-
-static void
-solvestep_exec(CommandArgs *args)
-{
- Cube c = apply_alg(args->scramble, (Cube){0});
- AlgList *sols = solve(c, args->step, args->opts);
- print_alglist(sols, args->opts->print_number);
- free_alglist(sols);
-}
-
-static void
-steps_exec(CommandArgs *args)
-{
- int i;
-
- for (i = 0; i < NSTEPS && steps[i] != NULL; i++)
- printf("%-15s %s\n", steps[i]->shortname, steps[i]->name);
-}
-
-static void
-commands_exec(CommandArgs *args)
-{
- int i;
-
- for (i = 0; i < NCOMMANDS && commands[i] != NULL; i++)
- printf("%s\n", commands[i]->usage);
-
-}
-
-static void
-print_exec(CommandArgs *args)
-{
- print_cube(apply_alg(args->scramble, (Cube){0}));
-}
-
-static void
-help_exec(CommandArgs *args)
-{
- /* TODO: print full nissy manpage */
- if (args->command == NULL) {
- printf("Type help COMMAND for information on a ");
- printf("specific command.\n");
- printf("A more complete manual page is work in progress.\n");
- } else {
- printf("Command %s: %s\nusage: %s\n", args->command->name,
- args->command->description, args->command->usage);
- }
-}
-
-static void
-quit_exec(CommandArgs *args)
-{
- exit(0);
-}
-
-/* Local functions implementation ********************************************/
-
-static bool
-read_step(CommandArgs *args, char *str)
-{
- int i;
-
- for (i = 0; i < NSTEPS; i++) {
- if (steps[i] != NULL && !strcmp(steps[i]->shortname, str)) {
- args->step = steps[i];
- return true;
- }
- }
-
- return false;
-}
-
-static bool
-read_scramble(int c, char **v, CommandArgs *args)
-{
- int i, k, n;
- unsigned int j;
- char *algstr;
-
- if (new_alg(v[0])->len == 0) {
- fprintf(stderr, "%s: moves or option unrecognized\n", v[0]);
- return false;
- }
-
- n = 0;
- for(i = 0; i < c; i++)
- n += strlen(v[i]);
-
- algstr = malloc((n + 1) * sizeof(char));
- k = 0;
- for (i = 0; i < c; i++)
- for (j = 0; j < strlen(v[i]); j++)
- algstr[k++] = v[i][j];
- algstr[k] = 0;
-
- args->scramble = new_alg(algstr);
- free(algstr);
-
- if (args->scramble->len == 0)
- fprintf(stderr, "Error reading scramble\n");
-
- return args->scramble->len > 0;
-}
-
-/* Public functions implementation *******************************************/
-
-void
-free_args(CommandArgs *args)
-{
- if (args == NULL)
- return;
-
- if (args->scramble != NULL)
- free_alg(args->scramble);
- if (args->opts != NULL)
- free(args->opts);
-
- /* step and command must not be freed, they are static! */
-
- free(args);
-}
diff --git a/old/2021-11-10-beforeremovingchecker/commands.h b/old/2021-11-10-beforeremovingchecker/commands.h
@@ -1,13 +0,0 @@
-#ifndef COMMANDS_H
-#define COMMANDS_H
-
-#include "solve.h"
-#include "steps.h"
-
-#define NCOMMANDS 10
-
-void free_args(CommandArgs *args);
-
-extern Command * commands[NCOMMANDS];
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/coord.c b/old/2021-11-10-beforeremovingchecker/coord.c
@@ -1,629 +0,0 @@
-#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 uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_epud(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cp(Cube cube);
-static uint64_t index_cphtr(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_cornershtrfin(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_drud_eofb(Cube cube);
-static uint64_t index_htr_drud(Cube cube);
-static uint64_t index_htrfin(Cube cube);
-
-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_cornershtrfin();
-
-
-/* All sorts of useful costants and tables **********************************/
-
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-static int cornershtrfin_ind[FACTORIAL8];
-static int cornershtrfin_ant[24*24/6];
-
-/* Coordinates and their implementation **************************************/
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11,
- .ntrans = 1,
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4,
- .ntrans = 1,
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7,
- .ntrans = 1,
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8,
- .ntrans = 1,
-};
-
-Coordinate
-coord_cp = {
- .index = index_cp,
- .cube = antindex_cp,
- .check = check_cp,
- .max = FACTORIAL8,
- .ntrans = 1,
-};
-
-Coordinate
-coord_cphtr = {
- .index = index_cphtr,
- .cube = antindex_cphtr,
- .check = check_cphtr,
- .max = BINOM8ON4 * 6,
- .ntrans = 1,
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6,
- .ntrans = 1,
-};
-
-Coordinate
-coord_cornershtrfin = {
- .index = index_cornershtrfin,
- .cube = antindex_cornershtrfin,
- .check = check_cp,
- .max = 24*24/6,
- .ntrans = 1,
-};
-
-Coordinate
-coord_epud = {
- .index = index_epud,
- .cube = antindex_epud,
- .check = check_epud,
- .max = FACTORIAL8,
- .ntrans = 1,
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4,
- .ntrans = 1,
-};
-
-Coordinate
-coord_htr_drud = {
- .index = index_htr_drud,
- .cube = antindex_htr_drud,
- .check = check_drud,
- .max = BINOM8ON4 * 6 * BINOM8ON4,
- .ntrans = 1,
-};
-
-Coordinate
-coord_htrfin = {
- .index = index_htrfin,
- .cube = antindex_htrfin,
- .check = check_htr,
- .max = 24 * 24 * 24 *24 * 24 / 6, /* should be /12 but it's ok */
- .ntrans = 1,
-};
-
-Coordinate
-coord_drud_eofb = {
- .index = index_drud_eofb,
- .cube = antindex_drud_eofb,
- .check = check_drud,
- .max = POW3TO7 * BINOM12ON4,
- .ntrans = 1,
-};
-
-/* Functions *****************************************************************/
-
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- Cube ret = {0};
-
- ret.eofb = ind % POW2TO11;
- ret.epose = (ind / POW2TO11) * 24;
-
- return ret;
-}
-
-static Cube
-antindex_epud(uint64_t ind)
-{
- 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];
-}
-
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-static Cube
-antindex_cp(uint64_t ind)
-{
- Cube c = {0};
-
- c.cp = ind;
-
- return c;
-}
-
-static Cube
-antindex_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = antindex_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-static Cube
-antindex_cornershtrfin(uint64_t ind)
-{
- return (Cube){ .cp = cornershtrfin_ant[ind] };
-}
-
-static Cube
-antindex_drud(uint64_t ind)
-{
- uint64_t epos, eofb;
- Cube c;
-
- eofb = ind % POW2TO11;
- epos = ind / (POW2TO11 * POW3TO7);
- c = antindex_eofbepos(eofb + POW2TO11 * epos);
-
- c.coud = (ind / POW2TO11) % POW3TO7;
-
- return c;
-}
-
-static Cube
-antindex_drud_eofb(uint64_t ind)
-{
- return antindex_drud(ind * POW2TO11);
-}
-
-static Cube
-antindex_htr_drud(uint64_t ind)
-{
- Cube ret;
-
- ret = antindex_cphtr(ind / BINOM8ON4);
- ret.eposs = (ind % BINOM8ON4) * FACTORIAL4;
-
- return ret;
-}
-
-static Cube
-antindex_htrfin(uint64_t ind)
-{
- Cube ret;
-
- ret = antindex_cornershtrfin(ind/(24*24*24));
-
- ret.eposm = ind % 24;
- ind /= 24;
- ret.eposs = ind % 24;
- ind /= 24;
- ret.epose = ind % 24;
-
- return ret;
-}
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cp(Cube cube)
-{
- return cube.cp == 0;
-}
-
-bool
-check_cphtr(Cube cube)
-{
- return index_cphtr(cube) == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && index_cphtr(cube) == 0;
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_htr(Cube cube)
-{
- return check_cornershtr(cube) &&
- cube.eofb == 0 && cube.eorl == 0 && cube.eoud == 0;
-}
-
-bool
-check_drudfin_noE(Cube cube)
-{
- return cube.eposs == 0 && cube.eposm == 0 && cube.cp == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_epud(Cube cube)
-{
- return cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-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);
-
- return ret;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cp(Cube cube)
-{
- return cube.cp;
-}
-
-static uint64_t
-index_cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube);
-}
-
-static uint64_t
-index_cornershtrfin(Cube cube)
-{
- return cornershtrfin_ind[cube.cp];
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud_eofb(Cube cube)
-{
- return index_drud(cube) / POW2TO11;
-}
-
-static uint64_t
-index_htr_drud(Cube cube)
-{
- return index_cphtr(cube) * BINOM8ON4 +
- (cube.eposs / FACTORIAL4) % BINOM8ON4;
-}
-
-static uint64_t
-index_htrfin(Cube cube)
-{
- uint64_t epe, eps, epm, cp, ep;
-
- epe = cube.epose % 24;
- eps = cube.eposs % 24;
- epm = cube.eposm % 24;
- ep = (epe * 24 + eps) *24 + epm;
- cp = index_cornershtrfin(cube);
-
- return cp * 24 * 24 * 24 + ep;
-}
-
-/* Init functions implementation *********************************************/
-
-/*
- * There is certainly a better way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- /*jj = cp_mtable[moves[k]][next[j]];*/
- /* TODO fix formatting */
- jj = apply_move(moves[k], (Cube){.cp=next[j]}).cp;
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_cornershtrfin()
-{
- unsigned int i, j;
- int n, c;
- Move m;
-
- for (i = 0; i < FACTORIAL8; i++)
- cornershtrfin_ind[i] = -1;
- cornershtrfin_ind[0] = 0;
-
- /* 10-pass, I think 5 is enough, but just in case */
- n = 1;
- for (i = 0; i < 10; i++) {
- for (j = 0; j < FACTORIAL8; j++) {
- if (cornershtrfin_ind[j] == -1)
- continue;
- for (m = U; m < NMOVES; m++) {
- if (moveset_htr(m)) {
- c = apply_move(m, (Cube){.cp = j}).cp;
- if (cornershtrfin_ind[c] == -1) {
- cornershtrfin_ind[c] = n;
- cornershtrfin_ant[n] = c;
- n++;
- }
- }
- }
- }
- }
-}
-
-void
-init_coord()
-{
- static bool initialized = false;
- if (initialized)
- return;
- initialized = true;
-
- init_cphtr_cosets();
- init_cornershtrfin();
-}
-
diff --git a/old/2021-11-10-beforeremovingchecker/coord.h b/old/2021-11-10-beforeremovingchecker/coord.h
@@ -1,40 +0,0 @@
-#ifndef COORD_H
-#define COORD_H
-
-#include "trans.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_cp;
-extern Coordinate coord_cphtr;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_cornershtrfin;
-extern Coordinate coord_epud;
-extern Coordinate coord_drud;
-extern Coordinate coord_drud_eofb;
-extern Coordinate coord_htr_drud;
-extern Coordinate coord_htrfin;
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cp(Cube cube);
-bool check_cphtr(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_htr(Cube cube);
-bool check_drudfin_noE(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_epud(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-void init_coord();
-
-#endif
-
diff --git a/old/2021-11-10-beforeremovingchecker/cube.c b/old/2021-11-10-beforeremovingchecker/cube.c
@@ -1,716 +0,0 @@
-#include "cube.h"
-
-/* Local functions **********************************************************/
-
-static int array_ep_to_epos(int *ep, int *eps_solved);
-static int epos_from_arrays(int *epos, int *ep);
-
-/* Local functions implementation ********************************************/
-
-static int
-array_ep_to_epos(int *ep, int *ss)
-{
- int epos[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- int eps[4];
- int i, j, is;
-
- for (i = 0, is = 0; i < 12; i++) {
- for (j = 0; j < 4; j++) {
- if (ep[i] == ss[j]) {
- eps[is++] = j;
- epos[i] = 1;
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- swap(&epos[ss[i]], &epos[i+8]);
-
- return epos_from_arrays(epos, eps);
-}
-
-static int
-epos_from_arrays(int *epos, int *ep)
-{
- return FACTORIAL4 * subset_to_index(epos,12,4) + perm_to_index(ep,4);
-}
-
-/* Public functions implementation *******************************************/
-
-Cube
-arrays_to_cube(CubeArray *arr, PieceFilter f)
-{
- Cube ret = {0};
-
- static int epe_solved[4] = {FR, FL, BL, BR};
- static int eps_solved[4] = {UL, UR, DL, DR};
- static int epm_solved[4] = {UF, UB, DF, DB};
-
- if (f.epose)
- ret.epose = array_ep_to_epos(arr->ep, epe_solved);
- if (f.eposs)
- ret.eposs = array_ep_to_epos(arr->ep, eps_solved);
- if (f.eposm)
- ret.eposm = array_ep_to_epos(arr->ep, epm_solved);
- if (f.eofb)
- ret.eofb = digit_array_to_int(arr->eofb, 11, 2);
- if (f.eorl)
- ret.eorl = digit_array_to_int(arr->eorl, 11, 2);
- if (f.eoud)
- ret.eoud = digit_array_to_int(arr->eoud, 11, 2);
- if (f.cp)
- ret.cp = perm_to_index(arr->cp, 8);
- if (f.coud)
- ret.coud = digit_array_to_int(arr->coud, 7, 3);
- if (f.corl)
- ret.corl = digit_array_to_int(arr->corl, 7, 3);
- if (f.cofb)
- ret.cofb = digit_array_to_int(arr->cofb, 7, 3);
- if (f.cpos)
- ret.cpos = perm_to_index(arr->cpos, 6);
-
- return ret;
-}
-
-Cube
-compose_filtered(Cube c2, Cube c1, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(c2, f);
- Cube ret;
-
- ret = move_via_arrays(arr, c1, f);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-void
-cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
-{
- int i;
-
- static int epe_solved[4] = {FR, FL, BL, BR};
- static int eps_solved[4] = {UL, UR, DL, DR};
- static int epm_solved[4] = {UF, UB, DF, DB};
-
- if (f.epose || f.eposs || f.eposm)
- for (i = 0; i < 12; i++)
- arr->ep[i] = -1;
-
- if (f.epose)
- epos_to_partial_ep(cube.epose, arr->ep, epe_solved);
- if (f.eposs)
- epos_to_partial_ep(cube.eposs, arr->ep, eps_solved);
- if (f.eposm)
- epos_to_partial_ep(cube.eposm, arr->ep, epm_solved);
- if (f.eofb)
- int_to_sum_zero_array(cube.eofb, 2, 12, arr->eofb);
- if (f.eorl)
- int_to_sum_zero_array(cube.eorl, 2, 12, arr->eorl);
- if (f.eoud)
- int_to_sum_zero_array(cube.eoud, 2, 12, arr->eoud);
- if (f.cp)
- index_to_perm(cube.cp, 8, arr->cp);
- if (f.coud)
- int_to_sum_zero_array(cube.coud, 3, 8, arr->coud);
- if (f.corl)
- int_to_sum_zero_array(cube.corl, 3, 8, arr->corl);
- if (f.cofb)
- int_to_sum_zero_array(cube.cofb, 3, 8, arr->cofb);
- if (f.cpos)
- index_to_perm(cube.cpos, 6, arr->cpos);
-}
-
-void
-epos_to_partial_ep(int epos, int *ep, int *ss)
-{
- int i, is, eposs[12], eps[4];
-
- index_to_perm(epos % FACTORIAL4, 4, eps);
- index_to_subset(epos / FACTORIAL4, 12, 4, eposs);
-
- for (i = 0; i < 4; i++)
- swap(&eposs[ss[i]], &eposs[i+8]);
-
- for (i = 0, is = 0; i < 12; i++)
- if (eposs[i])
- ep[i] = ss[eps[is++]];
-}
-
-void
-free_cubearray(CubeArray *arr, PieceFilter f)
-{
- if (f.epose || f.eposs || f.eposm)
- free(arr->ep);
- if (f.eofb)
- free(arr->eofb);
- if (f.eorl)
- free(arr->eorl);
- if (f.eoud)
- free(arr->eoud);
- if (f.cp)
- free(arr->cp);
- if (f.coud)
- free(arr->coud);
- if (f.corl)
- free(arr->corl);
- if (f.cofb)
- free(arr->cofb);
- if (f.cpos)
- free(arr->cpos);
-
- free(arr);
-}
-
-Cube
-move_via_arrays(CubeArray *arr, Cube c, PieceFilter f)
-{
- CubeArray *arrc = new_cubearray(c, f);
- Cube ret;
-
- if (f.epose || f.eposs || f.eposm)
- apply_permutation(arr->ep, arrc->ep, 12);
-
- if (f.eofb) {
- apply_permutation(arr->ep, arrc->eofb, 12);
- sum_arrays_mod(arr->eofb, arrc->eofb, 12, 2);
- }
-
- if (f.eorl) {
- apply_permutation(arr->ep, arrc->eorl, 12);
- sum_arrays_mod(arr->eorl, arrc->eorl, 12, 2);
- }
-
- if (f.eoud) {
- apply_permutation(arr->ep, arrc->eoud, 12);
- sum_arrays_mod(arr->eoud, arrc->eoud, 12, 2);
- }
-
- if (f.cp)
- apply_permutation(arr->cp, arrc->cp, 8);
-
- if (f.coud) {
- apply_permutation(arr->cp, arrc->coud, 8);
- sum_arrays_mod(arr->coud, arrc->coud, 8, 3);
- }
-
- if (f.corl) {
- apply_permutation(arr->cp, arrc->corl, 8);
- sum_arrays_mod(arr->corl, arrc->corl, 8, 3);
- }
-
- if (f.cofb) {
- apply_permutation(arr->cp, arrc->cofb, 8);
- sum_arrays_mod(arr->cofb, arrc->cofb, 8, 3);
- }
-
- if (f.cpos)
- apply_permutation(arr->cpos, arrc->cpos, 6);
-
- ret = arrays_to_cube(arrc, f);
- free_cubearray(arrc, f);
-
- return ret;
-}
-
-CubeArray *
-new_cubearray(Cube cube, PieceFilter f)
-{
- CubeArray *arr = malloc(sizeof(CubeArray));
-
- if (f.epose || f.eposs || f.eposm)
- arr->ep = malloc(12 * sizeof(int));
- if (f.eofb)
- arr->eofb = malloc(12 * sizeof(int));
- if (f.eorl)
- arr->eorl = malloc(12 * sizeof(int));
- if (f.eoud)
- arr->eoud = malloc(12 * sizeof(int));
- if (f.cp)
- arr->cp = malloc(8 * sizeof(int));
- if (f.coud)
- arr->coud = malloc(8 * sizeof(int));
- if (f.corl)
- arr->corl = malloc(8 * sizeof(int));
- if (f.cofb)
- arr->cofb = malloc(8 * sizeof(int));
- if (f.cpos)
- arr->cpos = malloc(6 * sizeof(int));
-
- cube_to_arrays(cube, arr, f);
-
- return arr;
-}
-
-
-/* TODO: consider if this is good here or better in coord.c
- in any case it is used in transformation init at the moment */
-Cube
-admissible_ep(Cube cube, PieceFilter f)
-{
- CubeArray *arr = new_cubearray(cube, f);
- Cube ret;
- bool used[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- for (i = 0; i < 12; i++)
- if (arr->ep[i] != -1)
- used[arr->ep[i]] = true;
-
- for (i = 0, j = 0; i < 12; i++) {
- for ( ; j < 11 && used[j]; j++);
- if (arr->ep[i] == -1)
- arr->ep[i] = j++;
- }
-
- ret = arrays_to_cube(arr, pf_ep);
- free_cubearray(arr, f);
-
- return ret;
-}
-
-Cube
-compose(Cube c2, Cube c1)
-{
- return compose_filtered(c2, c1, pf_all);
-}
-
-int
-edge_slice(Edge e) {
- if (e < 0 || e > 11)
- return -1;
-
- if (e == FR || e == FL || e == BL || e == BR)
- return 0;
- if (e == UR || e == UL || e == DR || e == DL)
- return 1;
-
- return 2;
-}
-
-bool
-equal(Cube c1, Cube c2)
-{
- return c1.eofb == c2.eofb &&
- c1.epose == c2.epose &&
- c1.eposs == c2.eposs &&
- c1.eposm == c2.eposm &&
- c1.coud == c2.coud &&
- c1.cp == c2.cp &&
- c1.cpos == c2.cpos;
-}
-
-Cube
-inverse_cube(Cube cube)
-{
- CubeArray *arr = new_cubearray(cube, pf_all);
- CubeArray *inv = new_cubearray((Cube){0}, pf_all);
- Cube ret;
- int i;
-
- for (i = 0; i < 12; i++) {
- inv->ep[arr->ep[i]] = i;
- inv->eofb[arr->ep[i]] = arr->eofb[i];
- inv->eorl[arr->ep[i]] = arr->eorl[i];
- inv->eoud[arr->ep[i]] = arr->eoud[i];
- }
-
- for (i = 0; i < 8; i++) {
- inv->cp[arr->cp[i]] = i;
- inv->coud[arr->cp[i]] = (3 - arr->coud[i]) % 3;
- inv->corl[arr->cp[i]] = (3 - arr->corl[i]) % 3;
- inv->cofb[arr->cp[i]] = (3 - arr->cofb[i]) % 3;
- }
-
- for (int i = 0; i < 6; i++)
- inv->cpos[arr->cpos[i]] = i;
-
- ret = arrays_to_cube(inv, pf_all);
- free_cubearray(arr, pf_all);
- free_cubearray(inv, pf_all);
-
- return ret;
-}
-
-bool
-is_admissible(Cube cube)
-{
- /* TODO: this should check consistency of different orientations */
- /* TODO: check that centers are opposite and admissible */
-
- CubeArray *a = new_cubearray(cube, pf_all);
- int parity;
- bool perm;
-
- perm = is_perm(a->ep, 12) &&
- is_perm(a->cp, 8) &&
- is_perm(a->cpos, 6);
- parity = perm_sign(a->ep, 12) +
- perm_sign(a->cp, 8) +
- perm_sign(a->cpos, 6);
-
- return perm && parity % 2 == 0;
-}
-
-bool
-is_solved(Cube cube)
-{
- /* TODO: move somewhere else, like in solve.c
- int i;
- if (reorient) {
- for (i = 0; i < NROTATIONS; i++)
- if (is_solved(apply_alg(rotation_algs[i], cube),false))
- return true;
- return false;
- } else {
- return equal(cube, (Cube){0});
- }
- */
-
- return equal(cube, (Cube){0});
-}
-
-bool
-is_solved_block(Cube cube, Block block)
-{
- int i;
-
- for (i = 0; i < 12; i++)
- if (block.edge[i] && !is_solved_edge(cube, i))
- return false;
- for (i = 0; i < 8; i++)
- if (block.corner[i] && !is_solved_corner(cube, i))
- return false;
- for (i = 0; i < 6; i++)
- if (block.center[i] && !is_solved_center(cube, i))
- return false;
-
- return true;
-}
-
-bool
-is_solved_center(Cube cube, Center c)
-{
- return what_center_at(cube, c) == c;
-}
-
-bool
-is_solved_corner(Cube cube, Corner c)
-{
- return what_corner_at(cube, c) == c &&
- what_orientation_corner(cube.coud, c);
-}
-
-bool
-is_solved_edge(Cube cube, Edge e)
-{
- return what_edge_at(cube, e) == e &&
- what_orientation_edge(cube.eofb, e);
-}
-
-int
-piece_orientation(Cube cube, int piece, char *orientation)
-{
- int arr[12], n, b, x;
-
- if (!strcmp(orientation, "eofb")) {
- x = cube.eofb;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eorl")) {
- x = cube.eorl;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "eoud")) {
- x = cube.eoud;
- n = 12;
- b = 2;
- } else if (!strcmp(orientation, "coud")) {
- x = cube.coud;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "corl")) {
- x = cube.corl;
- n = 8;
- b = 3;
- } else if (!strcmp(orientation, "cofb")) {
- x = cube.cofb;
- n = 8;
- b = 3;
- } else {
- return -1;
- }
-
- int_to_sum_zero_array(x, b, n, arr);
- if (piece < n)
- return arr[piece];
-
- return -1;
-}
-
-void
-print_cube(Cube cube)
-{
- static char edge_string[12][7] = {
- [UF] = "UF", [UL] = "UL", [UB] = "UB", [UR] = "UR",
- [DF] = "DF", [DL] = "DL", [DB] = "DB", [DR] = "DR",
- [FR] = "FR", [FL] = "FL", [BL] = "BL", [BR] = "BR"
- };
-
- static char corner_string[8][7] = {
- [UFR] = "UFR", [UFL] = "UFL", [UBL] = "UBL", [UBR] = "UBR",
- [DFR] = "DFR", [DFL] = "DFL", [DBL] = "DBL", [DBR] = "DBR"
- };
-
- static char center_string[6][7] = {
- [U_center] = "U", [D_center] = "D",
- [R_center] = "R", [L_center] = "L",
- [F_center] = "F", [B_center] = "B"
- };
-
- for (int i = 0; i < 12; i++)
- printf(" %s ", edge_string[what_edge_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 12; i++)
- printf(" %d ", what_orientation_edge(cube.eofb, i));
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf("%s ", corner_string[what_corner_at(cube, i)]);
- printf("\n");
-
- for (int i = 0; i < 8; i++)
- printf(" %d ", what_orientation_corner(cube.coud, i));
- printf("\n");
-
- for (int i = 0; i < 6; i++)
- printf(" %s ", center_string[what_center_at(cube, i)]);
- printf("\n");
-}
-
-Cube
-random_cube()
-{
- CubeArray *arr = new_cubearray((Cube){0}, pf_4val);
- Cube ret;
- int ep, cp, eo, co;
-
- ep = rand() % FACTORIAL12;
- cp = rand() % FACTORIAL8;
- eo = rand() % POW2TO11;
- co = rand() % POW3TO7;
-
- index_to_perm(ep, 12, arr->ep);
- index_to_perm(cp, 8, arr->cp);
- int_to_sum_zero_array(eo, 2, 12, arr->eofb);
- int_to_sum_zero_array(co, 3, 8, arr->coud);
-
- if (perm_sign(arr->ep, 12) != perm_sign(arr->cp, 8))
- swap(&(arr->ep[0]), &(arr->ep[1]));
-
- ret = arrays_to_cube(arr, pf_4val);
- free_cubearray(arr, pf_4val);
-
- return ret;
-}
-
-Center
-what_center_at(Cube cube, Center c)
-{
- static bool initialized = false;
- static Center aux[FACTORIAL6][6];
- static int i;
- static unsigned int ui;
- static CubeArray *arr;
-
- if (!initialized) {
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++)
- aux[ui][i] = arr->cpos[i];
- free_cubearray(arr, pf_cpos);
- }
-
- initialized = true;
- }
-
- return aux[cube.cpos][c];
-}
-
-Corner
-what_corner_at(Cube cube, Corner c)
-{
- static bool initialized = false;
- static Corner aux[FACTORIAL8][8];
- static int i;
- static unsigned int ui;
- static CubeArray *arr;
-
- if (!initialized) {
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++)
- aux[ui][i] = arr->cp[i];
- free_cubearray(arr, pf_cp);
- }
-
- initialized = true;
- }
-
- return aux[cube.cp][c];
-}
-
-Edge
-what_edge_at(Cube cube, Edge e)
-{
- Edge ret;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- ret = arr->ep[e];
-
- free_cubearray(arr, pf_ep);
- return ret;
-}
-
-int
-what_orientation_corner(int co, Corner c)
-{
- static bool initialized = false;
- static int auxlast[POW3TO7];
- static int auxarr[8];
- static unsigned int ui;
-
- if (!initialized) {
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, auxarr);
- auxlast[ui] = auxarr[7];
- }
-
- initialized = true;
- }
-
- if (c < 7)
- return (co / powint(3, c)) % 3;
- else
- return auxlast[co];
-}
-
-int
-what_orientation_edge(int eo, Edge e)
-{
- static bool initialized = false;
- static int auxlast[POW2TO11];
- static int auxarr[12];
- static unsigned int ui;
-
- if (!initialized) {
- for (ui = 0; ui < POW2TO11; ui++) {
- int_to_sum_zero_array(ui, 2, 12, auxarr);
- auxlast[ui] = auxarr[11];
- }
-
- initialized = true;
- }
-
- if (e < 11)
- return (eo & (1 << e)) ? 1 : 0;
- else
- return auxlast[eo];
-}
-
-Center
-where_is_center(Cube cube, Center c)
-{
- static bool initialized = false;
- static Center aux[FACTORIAL6][6];
- static int i;
- static unsigned int ui;
- static CubeArray *arr;
-
- if (!initialized) {
- for (ui = 0; ui < FACTORIAL6; ui++) {
- arr = new_cubearray((Cube){.cpos = ui}, pf_cpos);
- for (i = 0; i < 6; i++)
- aux[ui][arr->cpos[i]] = i;
- free_cubearray(arr, pf_cpos);
- }
-
- initialized = true;
- }
-
- return aux[cube.cpos][c];
-}
-
-Corner
-where_is_corner(Cube cube, Corner c)
-{
- static bool initialized = false;
- static Corner aux[FACTORIAL8][8];
- static int i;
- static unsigned int ui;
- static CubeArray *arr;
-
- if (!initialized) {
- for (ui = 0; ui < FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.cp = ui}, pf_cp);
- for (i = 0; i < 8; i++)
- aux[ui][arr->cp[i]] = i;
- free_cubearray(arr, pf_cp);
- }
-
- initialized = true;
- }
- return aux[cube.cp][c];
-}
-
-Edge
-where_is_edge(Cube cube, Edge e)
-{
- /* TODO: when I wrote this code I forgot to add the final
- part, and now I can't remember how it was supposed to
- work (i.e. how to recover the location of the edge
- from these tables. I think it is either very easy or
- wrong, in any case it is not a priority now.
- Future Seba can deal with it.
-
- static bool initialized = false;
- static Edge aux[3][FACTORIAL12/FACTORIAL8][12];
- static int i;
- static unsigned int ui;
- static CubeArray *arr;
-
- if (!initialized) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- arr = new_cubearray((Cube){.epose = ui}, pf_e);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 0)
- aux[0][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_e);
-
- arr = new_cubearray((Cube){.eposs = ui}, pf_s);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 1)
- aux[1][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_s);
-
- arr = new_cubearray((Cube){.eposm = ui}, pf_m);
- for (i = 0; i < 12; i++)
- if (edge_slice(arr->ep[i]) == 2)
- aux[2][ui][arr->ep[i]] = i;
- free_cubearray(arr, pf_m);
- }
-
- initialized = true;
- }
- */
-
- int i;
- CubeArray *arr = new_cubearray(cube, pf_ep);
-
- for (i = 0; i < 12; i++)
- if ((Edge)arr->ep[i] == e)
- return i;
-
- return -1;
-}
diff --git a/old/2021-11-10-beforeremovingchecker/cube.h b/old/2021-11-10-beforeremovingchecker/cube.h
@@ -1,40 +0,0 @@
-#ifndef CUBE_H
-#define CUBE_H
-
-#include <stdio.h>
-#include <time.h>
-
-#include "pf.h"
-#include "utils.h"
-
-Cube admissible_ep(Cube cube, PieceFilter f); /* TODO: move? */
-Cube arrays_to_cube(CubeArray *arr, PieceFilter f); /* TODO: remove */
-Cube compose(Cube c2, Cube c1); /* Use c2 as an alg on c1 */
-Cube compose_filtered(Cube c2, Cube c1, PieceFilter f);
-void cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f);
-int edge_slice(Edge e); /* E=0, S=1, M=2 */
-bool equal(Cube c1, Cube c2);
-Cube inverse_cube(Cube cube);
-bool is_admissible(Cube cube);
-bool is_solved(Cube cube);
-bool block_solved(Cube cube, Block); /*TODO: rename to is_solved_block()*/
-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 free_cubearray(CubeArray *arr, PieceFilter f); /* TODO: remove */
-Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
-CubeArray * new_cubearray(Cube cube, PieceFilter f); /* TODO: remove */
-void print_cube(Cube cube);
-Cube random_cube();
-Center what_center_at(Cube cube, Center c);
-Corner what_corner_at(Cube cube, Corner c);
-Edge what_edge_at(Cube cube, Edge e);
-int what_orientation_corner(int co, Corner c);
-int what_orientation_edge(int eo, Edge e);
-Center where_is_center(Cube cube, Center c);
-Corner where_is_corner(Cube cube, Corner c);
-Edge where_is_edge(Cube cube, Edge e);
-
-#endif
-
diff --git a/old/2021-11-10-beforeremovingchecker/cubetypes.h b/old/2021-11-10-beforeremovingchecker/cubetypes.h
@@ -1,298 +0,0 @@
-#ifndef CUBETYPES_H
-#define CUBETYPES_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#define NMOVES 55 /* Actually 55, but one is NULLMOVE */
-#define NTRANS 48
-#define NROTATIONS 24
-
-
-/* Typedefs ******************************************************************/
-
-typedef enum center Center;
-typedef enum corner Corner;
-typedef enum edge Edge;
-typedef enum move Move;
-typedef enum trans Trans;
-
-typedef struct alg Alg;
-typedef struct alglist AlgList;
-typedef struct alglistnode AlgListNode;
-typedef struct block Block;
-typedef struct command Command;
-typedef struct commandargs CommandArgs;
-typedef struct coordinate Coordinate;
-typedef struct cube Cube;
-typedef struct cubearray CubeArray;
-typedef struct cubetarget CubeTarget;
-typedef struct dfsdata DfsData;
-typedef struct piecefilter PieceFilter;
-typedef struct prunedata PruneData;
-typedef struct solveoptions SolveOptions;
-typedef struct step Step;
-typedef struct symdata SymData;
-
-typedef Cube (*AntiIndexer) (uint64_t);
-typedef bool (*Checker) (Cube);
-typedef int (*Estimator) (CubeTarget);
-typedef bool (*Validator) (Alg *);
-typedef void (*Exec) (CommandArgs *);
-typedef uint64_t (*Indexer) (Cube);
-typedef bool (*Moveset) (Move);
-typedef CommandArgs * (*ArgParser) (int, char **);
-typedef Trans (*TransDetector) (Cube);
-
-
-/* Enums *********************************************************************/
-
-enum
-center
-{
- U_center, D_center,
- R_center, L_center,
- F_center, B_center
-};
-
-enum
-corner
-{
- UFR, UFL, UBL, UBR,
- DFR, DFL, DBL, DBR
-};
-
-enum
-edge
-{
- UF, UL, UB, UR,
- DF, DL, DB, DR,
- FR, FL, BL, BR
-};
-
-enum
-move
-{
- NULLMOVE,
- U, U2, U3, D, D2, D3,
- R, R2, R3, L, L2, L3,
- F, F2, F3, B, B2, B3,
- Uw, Uw2, Uw3, Dw, Dw2, Dw3,
- Rw, Rw2, Rw3, Lw, Lw2, Lw3,
- Fw, Fw2, Fw3, Bw, Bw2, Bw3,
- M, M2, M3,
- S, S2, S3,
- E, E2, E3,
- x, x2, x3,
- y, y2, y3,
- z, z2, z3,
-};
-
-enum
-trans
-{
- uf, ur, ub, ul,
- df, dr, db, dl,
- rf, rd, rb, ru,
- lf, ld, lb, lu,
- fu, fr, fd, fl,
- bu, br, bd, bl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
- rf_mirror, rd_mirror, rb_mirror, ru_mirror,
- lf_mirror, ld_mirror, lb_mirror, lu_mirror,
- fu_mirror, fr_mirror, fd_mirror, fl_mirror,
- bu_mirror, br_mirror, bd_mirror, bl_mirror,
-};
-
-
-/* Structs *******************************************************************/
-
-struct
-alg
-{
- Move * move;
- bool * inv;
- int len;
- int allocated;
-};
-
-struct
-alglist
-{
- AlgListNode * first;
- AlgListNode * last;
- int len;
-};
-
-struct
-alglistnode
-{
- Alg * alg;
- AlgListNode * next;
-};
-
-struct
-block
-{
- bool edge[12];
- bool corner[8];
- bool center[6];
-};
-
-struct
-command
-{
- /* TODO: more stuff to add? maybe complete help? */
- /* Maybe add list of options */
- char * name;
- char * usage;
- char * description;
- ArgParser parse_args;
- Exec exec;
-};
-
-struct
-commandargs
-{
- bool success;
- Alg * scramble;
- SolveOptions * opts;
- Step * step;
- Command * command; /* For help */
-};
-
-struct
-coordinate
-{
- Indexer index;
- AntiIndexer cube;
- Checker check;
- uint64_t max;
- int ntrans;
- Trans * trans;
-};
-
-struct
-cube
-{
- int epose;
- int eposs;
- int eposm;
- int eofb;
- int eorl;
- int eoud;
- int cp;
- int coud;
- int cofb;
- int corl;
- int cpos;
-};
-
-struct
-cubearray
-{
- int * ep;
- int * eofb;
- int * eorl;
- int * eoud;
- int * cp;
- int * coud;
- int * corl;
- int * cofb;
- int * cpos;
-};
-
-struct
-cubetarget
-{
- Cube cube;
- int target;
-};
-
-struct
-dfsdata
-{
- int d;
- int m;
- int lb;
- bool niss;
- Move last1;
- Move last2;
- AlgList * sols;
- Alg * current_alg;
- Move sorted_moves[NMOVES];
- int move_position[NMOVES];
-};
-
-struct
-piecefilter
-{
- bool epose;
- bool eposs;
- bool eposm;
- bool eofb;
- bool eorl;
- bool eoud;
- bool cp;
- bool coud;
- bool cofb;
- bool corl;
- bool cpos;
-};
-
-struct
-prunedata
-{
- char * filename;
- uint8_t * ptable;
- bool generated;
- uint64_t n;
- Coordinate * coord;
- Moveset moveset;
-};
-
-struct
-solveoptions
-{
- /* TODO: add option to list *all* solutions satisfying other
- constraints (min/max moves and optimality) */
- int min_moves;
- int max_moves;
- int max_solutions;
- bool optimal_only;
- bool can_niss;
- bool feedback; /* TODO: rename with "verbose" */
- bool all;
- bool print_number;
-};
-
-struct
-step
-{
- char * shortname;
- char * name;
- Estimator estimate;
- Checker ready;
- char * ready_msg;
- Validator is_valid;
- Moveset moveset;
- Trans pre_trans;
- TransDetector detect;
-};
-
-struct
-symdata
-{
- char * filename;
- bool generated;
- Coordinate * coord;
- Coordinate * sym_coord;
- int ntrans;
- Trans * trans;
- uint64_t * class;
- Cube * rep;
- Trans * transtorep;
-};
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/env.c b/old/2021-11-10-beforeremovingchecker/env.c
@@ -1,45 +0,0 @@
-#include "env.h"
-
-bool initialized_env = false;
-char *tabledir;
-
-void
-init_env()
-{
- char *nissydata = getenv("NISSYDATA");
- char *localdata = getenv("XDG_DATA_HOME");
- char *home = getenv("HOME");
- bool read, write;
-
- if (initialized_env)
- return;
-
- if (nissydata != NULL) {
- tabledir = malloc(strlen(nissydata) * sizeof(char) + 20);
- strcpy(tabledir, nissydata);
- } else if (localdata != NULL) {
- tabledir = malloc(strlen(localdata) * sizeof(char) + 20);
- strcpy(tabledir, localdata);
- strcat(tabledir, "/nissy");
- } else if (home != NULL) {
- tabledir = malloc(strlen(home) * sizeof(char) + 20);
- strcpy(tabledir, home);
- strcat(tabledir, "/.nissy");
- }
-
- mkdir(tabledir, 0777);
- strcat(tabledir, "/tables");
- mkdir(tabledir, 0777);
-
- read = !access(tabledir, R_OK);
- write = !access(tabledir, W_OK);
-
- if (!read) {
- fprintf(stderr, "Table files cannot be read.\n");
- } else if (!write) {
- fprintf(stderr, "Data directory not writable: ");
- fprintf(stderr, "tables can be loaded, but not saved.\n");
- }
-
- initialized_env = true;
-}
diff --git a/old/2021-11-10-beforeremovingchecker/env.h b/old/2021-11-10-beforeremovingchecker/env.h
@@ -1,15 +0,0 @@
-#ifndef ENV_H
-#define ENV_H
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-extern char *tabledir;
-
-void init_env();
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/moves.c b/old/2021-11-10-beforeremovingchecker/moves.c
@@ -1,474 +0,0 @@
-#include "moves.h"
-
-/* Local functions ***********************************************************/
-
-static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f);
-static bool read_mtables_file();
-static bool write_mtables_file();
-
-/* Tables and other data *****************************************************/
-
-/* Every move is translated to a an <U, x, y> alg before filling the
- transition tables, see init_moves() */
-
-static int edge_cycle[NMOVES][12] =
-{
- [U] = { UR, UF, UL, UB, DF, DL, DB, DR, FR, FL, BL, BR },
- [x] = { DF, FL, UF, FR, DB, BL, UB, BR, DR, DL, UL, UR },
- [y] = { UR, UF, UL, UB, DR, DF, DL, DB, BR, FR, FL, BL }
-};
-
-static int corner_cycle[NMOVES][8] =
-{
- [U] = { UBR, UFR, UFL, UBL, DFR, DFL, DBL, DBR },
- [x] = { DFR, DFL, UFL, UFR, DBR, DBL, UBL, UBR },
- [y] = { UBR, UFR, UFL, UBL, DBR, DFR, DFL, DBL }
-};
-
-static int center_cycle[NMOVES][6] =
-{
- [x] = { F_center, B_center, R_center, L_center, D_center, U_center },
- [y] = { U_center, D_center, B_center, F_center, R_center, L_center }
-};
-
-static int eofb_flipped[NMOVES][12] = {
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
-};
-
-static int eorl_flipped[NMOVES][12] = {
- [x] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [y] = { [FR] = 1, [FL] = 1, [BL] = 1, [BR] = 1 }
-};
-
-static int eoud_flipped[NMOVES][12] = {
- [U] = { [UF] = 1, [UL] = 1, [UB] = 1, [UR] = 1 },
- [x] = { [UF] = 1, [UB] = 1, [DF] = 1, [DB] = 1 },
- [y] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
-};
-
-static int coud_flipped[NMOVES][8] = {
- [x] = {
- [UFR] = 2, [UBR] = 1, [UFL] = 1, [UBL] = 2,
- [DBR] = 2, [DFR] = 1, [DBL] = 1, [DFL] = 2
- }
-};
-
-static int corl_flipped[NMOVES][8] = {
- [U] = { [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2 },
- [y] = {
- [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
- [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
- }
-};
-
-static int cofb_flipped[NMOVES][8] = {
- [U] = { [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1 },
- [x] = {
- [UFR] = 1, [UBR] = 2, [UBL] = 1, [UFL] = 2,
- [DFR] = 2, [DBR] = 1, [DBL] = 2, [DFL] = 1
- },
- [y] = {
- [UFR] = 2, [UBR] = 1, [UBL] = 2, [UFL] = 1,
- [DFR] = 1, [DBR] = 2, [DBL] = 1, [DFL] = 2
- }
-};
-
-static char equiv_alg_string[100][NMOVES] = {
- [NULLMOVE] = "",
-
- [U] = " U ",
- [U2] = " UU ",
- [U3] = " UUU ",
- [D] = " xx U xx ",
- [D2] = " xx UU xx ",
- [D3] = " xx UUU xx ",
- [R] = " yx U xxxyyy ",
- [R2] = " yx UU xxxyyy ",
- [R3] = " yx UUU xxxyyy ",
- [L] = " yyyx U xxxy ",
- [L2] = " yyyx UU xxxy ",
- [L3] = " yyyx UUU xxxy ",
- [F] = " x U xxx ",
- [F2] = " x UU xxx ",
- [F3] = " x UUU xxx ",
- [B] = " xxx U x ",
- [B2] = " xxx UU x ",
- [B3] = " xxx UUU x ",
-
- [Uw] = " xx U xx y ",
- [Uw2] = " xx UU xx yy ",
- [Uw3] = " xx UUU xx yyy ",
- [Dw] = " U yyy ",
- [Dw2] = " UU yy ",
- [Dw3] = " UUU y ",
- [Rw] = " yyyx U xxxy x ",
- [Rw2] = " yyyx UU xxxy xx ",
- [Rw3] = " yyyx UUU xxxy xxx ",
- [Lw] = " yx U xxxyyy xxx ",
- [Lw2] = " yx UU xxxyyy xx ",
- [Lw3] = " yx UUU xxxyyy x ",
- [Fw] = " xxx U x yxxxyyy ",
- [Fw2] = " xxx UU x yxxyyy ",
- [Fw3] = " xxx UUU x yxyyy ",
- [Bw] = " x U xxx yxyyy ",
- [Bw2] = " x UU xxx yxxyyy ",
- [Bw3] = " x UUU xxx yxxxyyy ",
-
- [M] = " yx U xx UUU yxyyy ",
- [M2] = " yx UU xx UU xxxy ",
- [M3] = " yx UUU xx U yxxxy ",
- [S] = " x UUU xx U yyyx ",
- [S2] = " x UU xx UU yyx ",
- [S3] = " x U xx UUU yx ",
- [E] = " U xx UUU xxyyy ",
- [E2] = " UU xx UU xxyy ",
- [E3] = " UUU xx U xxy ",
-
- [x] = " x ",
- [x2] = " xx ",
- [x3] = " xxx ",
- [y] = " y ",
- [y2] = " yy ",
- [y3] = " yyy ",
- [z] = " yyy x y ",
- [z2] = " yy xx ",
- [z3] = " y x yyy "
-};
-
-/* Transition tables, to be loaded up at the beginning */
-static int epose_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposs_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eposm_mtable[NMOVES][FACTORIAL12/FACTORIAL8];
-static int eofb_mtable[NMOVES][POW2TO11];
-static int eorl_mtable[NMOVES][POW2TO11];
-static int eoud_mtable[NMOVES][POW2TO11];
-static int cp_mtable[NMOVES][FACTORIAL8];
-static int coud_mtable[NMOVES][POW3TO7];
-static int cofb_mtable[NMOVES][POW3TO7];
-static int corl_mtable[NMOVES][POW3TO7];
-static int cpos_mtable[NMOVES][FACTORIAL6];
-
-
-/* Local functions implementation ********************************************/
-
-static Cube
-apply_move_cubearray(Move m, Cube cube, PieceFilter f)
-{
- /*init_moves();*/
-
- CubeArray m_arr = {
- edge_cycle[m],
- eofb_flipped[m],
- eorl_flipped[m],
- eoud_flipped[m],
- corner_cycle[m],
- coud_flipped[m],
- corl_flipped[m],
- cofb_flipped[m],
- center_cycle[m]
- };
-
- return move_via_arrays(&m_arr, cube, f);
-}
-
-/* Public functions **********************************************************/
-
-Cube
-apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a)
-{
- Cube ret = {0};
- int i;
-
- for (i = 0; i < alg->len; i++)
- if (alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- ret = compose_filtered(c, inverse_cube(ret), f);
-
- for (i = 0; i < alg->len; i++)
- if (!alg->inv[i])
- ret = a ? apply_move(alg->move[i], ret) :
- apply_move_cubearray(alg->move[i], ret, f);
-
- return ret;
-}
-
-Cube
-apply_alg(Alg *alg, Cube cube)
-{
- return apply_alg_generic(alg, cube, pf_all, true);
-}
-
-Cube
-apply_move(Move m, Cube cube)
-{
- /*init_moves();*/
-
- return (Cube) {
- .epose = epose_mtable[m][cube.epose],
- .eposs = eposs_mtable[m][cube.eposs],
- .eposm = eposm_mtable[m][cube.eposm],
- .eofb = eofb_mtable[m][cube.eofb],
- .eorl = eorl_mtable[m][cube.eorl],
- .eoud = eoud_mtable[m][cube.eoud],
- .coud = coud_mtable[m][cube.coud],
- .cofb = cofb_mtable[m][cube.cofb],
- .corl = corl_mtable[m][cube.corl],
- .cp = cp_mtable[m][cube.cp],
- .cpos = cpos_mtable[m][cube.cpos]
- };
-}
-
-void
-init_moves() {
- static bool initialized = false;
- if (initialized)
- return;
- initialized = true;
-
- Cube c;
- CubeArray arrs;
- int i;
- unsigned int ui;
- Move m;
- Alg *equiv_alg[NMOVES];
-
- for (i = 0; i < NMOVES; i++)
- equiv_alg[i] = new_alg(equiv_alg_string[i]);
-
- /* Generate all move cycles and flips; I do this regardless */
- for (i = 0; i < NMOVES; i++) {
- if (i == U || i == x || i == y)
- continue;
-
- c = apply_alg_generic(equiv_alg[i], (Cube){0}, pf_all, false);
-
- arrs = (CubeArray) {
- edge_cycle[i],
- eofb_flipped[i],
- eorl_flipped[i],
- eoud_flipped[i],
- corner_cycle[i],
- coud_flipped[i],
- corl_flipped[i],
- cofb_flipped[i],
- center_cycle[i]
- };
- cube_to_arrays(c, &arrs, pf_all);
- }
-
- if (read_mtables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "mtables");
-
- /* Initialize transition tables */
- for (m = 0; m < NMOVES; m++) {
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c = (Cube){ .epose = ui };
- c = apply_move_cubearray(m, c, pf_e);
- epose_mtable[m][ui] = c.epose;
-
- c = (Cube){ .eposs = ui };
- c = apply_move_cubearray(m, c, pf_s);
- eposs_mtable[m][ui] = c.eposs;
-
- c = (Cube){ .eposm = ui };
- c = apply_move_cubearray(m, c, pf_m);
- eposm_mtable[m][ui] = c.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- c = (Cube){ .eofb = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eofb_mtable[m][ui] = c.eofb;
-
- c = (Cube){ .eorl = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eorl_mtable[m][ui] = c.eorl;
-
- c = (Cube){ .eoud = ui };
- c = apply_move_cubearray(m, c, pf_eo);
- eoud_mtable[m][ui] = c.eoud;
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- c = (Cube){ .coud = ui };
- c = apply_move_cubearray(m, c, pf_co);
- coud_mtable[m][ui] = c.coud;
-
- c = (Cube){ .corl = ui };
- c = apply_move_cubearray(m, c, pf_co);
- corl_mtable[m][ui] = c.corl;
-
- c = (Cube){ .cofb = ui };
- c = apply_move_cubearray(m, c, pf_co);
- cofb_mtable[m][ui] = c.cofb;
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- c = (Cube){ .cp = ui };
- c = apply_move_cubearray(m, c, pf_cp);
- cp_mtable[m][ui] = c.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- c = (Cube){ .cpos = ui };
- c = apply_move_cubearray(m, c, pf_cpos);
- cpos_mtable[m][ui] = c.cpos;
- }
- }
-
- if (!write_mtables_file())
- fprintf(stderr, "Error writing mtables\n");
-
- for (i = 0; i < NMOVES; i++)
- free_alg(equiv_alg[i]);
-}
-
-static bool
-read_mtables_file()
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- /* Table sizes, used for reading and writing files */
- uint64_t me[11] = {
- [0] = FACTORIAL12/FACTORIAL8,
- [1] = FACTORIAL12/FACTORIAL8,
- [2] = FACTORIAL12/FACTORIAL8,
- [3] = POW2TO11,
- [4] = POW2TO11,
- [5] = POW2TO11,
- [6] = FACTORIAL8,
- [7] = POW3TO7,
- [8] = POW3TO7,
- [9] = POW3TO7,
- [10] = FACTORIAL6
- };
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fread(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fread(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fread(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fread(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fread(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fread(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fread(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fread(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fread(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-static bool
-write_mtables_file()
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+20];
- int m, b = sizeof(int);
- bool r = true;
-
- /* Table sizes, used for reading and writing files */
- uint64_t me[11] = {
- [0] = FACTORIAL12/FACTORIAL8,
- [1] = FACTORIAL12/FACTORIAL8,
- [2] = FACTORIAL12/FACTORIAL8,
- [3] = POW2TO11,
- [4] = POW2TO11,
- [5] = POW2TO11,
- [6] = FACTORIAL8,
- [7] = POW3TO7,
- [8] = POW3TO7,
- [9] = POW3TO7,
- [10] = FACTORIAL6
- };
-
- strcpy(fname, tabledir);
- strcat(fname, "/mtables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NMOVES; m++) {
- r = r && fwrite(epose_mtable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_mtable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_mtable[m], b, me[2], f) == me[2];
- r = r && fwrite(eofb_mtable[m], b, me[3], f) == me[3];
- r = r && fwrite(eorl_mtable[m], b, me[4], f) == me[4];
- r = r && fwrite(eoud_mtable[m], b, me[5], f) == me[5];
- r = r && fwrite(cp_mtable[m], b, me[6], f) == me[6];
- r = r && fwrite(coud_mtable[m], b, me[7], f) == me[7];
- r = r && fwrite(corl_mtable[m], b, me[8], f) == me[8];
- r = r && fwrite(cofb_mtable[m], b, me[9], f) == me[9];
- r = r && fwrite(cpos_mtable[m], b, me[10], f) == me[10];
- }
-
- fclose(f);
- return r;
-}
-
-bool
-commute(Move m1, Move m2)
-{
- static bool initialized = false;
- static bool commute_aux[NMOVES][NMOVES];
-
- if (!initialized) {
- Cube c1, c2;
- int i, j;
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute_aux[i][j] = equal(c1, c2) && i && j;
- }
- }
-
- initialized = true;
- }
-
- return commute_aux[m1][m2];
-}
-
-bool
-possible_next(Move m1, Move m2, Move m3)
-{
- static bool initialized = false;
- static bool paux[NMOVES][NMOVES][NMOVES];
-
- if (!initialized) {
- int i, j, k;
- bool p, q, c;
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- for (k = 0; k < NMOVES; k++) {
- p = j && base_move(j) == base_move(k);
- q = i && base_move(i) == base_move(k);
- c = commute(i, j);
- paux[i][j][k] = !(p || (c && q));
- }
- }
- }
-
- initialized = true;
- }
-
- return paux[m1][m2][m3];
-}
diff --git a/old/2021-11-10-beforeremovingchecker/moves.h b/old/2021-11-10-beforeremovingchecker/moves.h
@@ -1,16 +0,0 @@
-#ifndef MOVES_H
-#define MOVES_H
-
-#include "alg.h"
-#include "cube.h"
-#include "env.h"
-
-Cube apply_alg(Alg *alg, Cube cube);
-Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a);
-Cube apply_move(Move m, Cube cube);
-bool commute(Move m1, Move m2);
-bool possible_next(Move m1, Move m2, Move m3);
-
-void init_moves();
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/pf.c b/old/2021-11-10-beforeremovingchecker/pf.c
@@ -1,80 +0,0 @@
-#include "pf.h"
-
-PieceFilter
-pf_all = {
- .epose = true,
- .eposs = true,
- .eposm = true,
- .eofb = true,
- .eorl = true,
- .eoud = true,
- .cp = true,
- .cofb = true,
- .corl = true,
- .coud = true,
- .cpos = true
-};
-
-PieceFilter
-pf_4val = {
- .epose = true,
- .eposs = true,
- .eposm = true,
- .eofb = true,
- .coud = true,
- .cp = true
-};
-
-PieceFilter
-pf_epcp = {
- .epose = true,
- .eposs = true,
- .eposm = true,
- .cp = true
-};
-
-PieceFilter
-pf_cpos = {
- .cpos = true
-};
-
-PieceFilter
-pf_cp = {
- .cp = true
-};
-
-PieceFilter
-pf_ep = {
- .epose = true,
- .eposs = true,
- .eposm = true
-};
-
-PieceFilter
-pf_e = {
- .epose = true
-};
-
-PieceFilter
-pf_s = {
- .eposs = true
-};
-
-PieceFilter
-pf_m = {
- .eposm = true
-};
-
-PieceFilter
-pf_eo = {
- .eofb = true,
- .eorl = true,
- .eoud = true
-};
-
-PieceFilter
-pf_co = {
- .cofb = true,
- .corl = true,
- .coud = true
-};
diff --git a/old/2021-11-10-beforeremovingchecker/pf.h b/old/2021-11-10-beforeremovingchecker/pf.h
@@ -1,18 +0,0 @@
-#ifndef PF_H
-#define PF_H
-
-#include "cubetypes.h"
-
-extern PieceFilter pf_all;
-extern PieceFilter pf_4val;
-extern PieceFilter pf_epcp;
-extern PieceFilter pf_cpos;
-extern PieceFilter pf_cp;
-extern PieceFilter pf_ep;
-extern PieceFilter pf_e;
-extern PieceFilter pf_s;
-extern PieceFilter pf_m;
-extern PieceFilter pf_eo;
-extern PieceFilter pf_co;
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/pruning.c b/old/2021-11-10-beforeremovingchecker/pruning.c
@@ -1,272 +0,0 @@
-#include "pruning.h"
-
-static void genptable_bfs(PruneData *pd, int d, Move *ms);
-static void genptable_branch(PruneData *pd, uint64_t i, int d, Move *m);
-static void ptable_update(PruneData *pd, Cube cube, int m);
-static void ptable_update_index(PruneData *pd, uint64_t ind, int m);
-static int ptableval_index(PruneData *pd, uint64_t ind);
-static bool read_ptable_file(PruneData *pd);
-static bool write_ptable_file(PruneData *pd);
-
-PruneData
-pd_eofb_HTM = {
- .filename = "pt_eofb_HTM",
- .coord = &coord_eofb,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "pt_coud_HTM",
- .coord = &coord_coud,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_cornershtr_HTM = {
- .filename = "pt_cornershtr_withcosets_HTM",
- .coord = &coord_cornershtr,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "pt_corners_HTM",
- .coord = &coord_corners,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_drud_sym16_HTM = {
- .filename = "pt_drud_sym16_HTM",
- .coord = &coord_drud_sym16,
- .moveset = moveset_HTM,
-};
-
-PruneData
-pd_drud_eofb = {
- .filename = "pt_drud_eofb",
- .coord = &coord_drud_eofb,
- .moveset = moveset_eofb,
-};
-
-PruneData
-pd_drudfin_noE_sym16_drud = {
- .filename = "pt_drudfin_noE_sym16_drud",
- .coord = &coord_drudfin_noE_sym16,
- .moveset = moveset_drud,
-};
-
-PruneData
-pd_htr_drud = {
- .filename = "pt_htr_drud",
- .coord = &coord_htr_drud,
- .moveset = moveset_drud,
-};
-
-PruneData
-pd_htrfin_htr = {
- .filename = "pt_htrfin_htr",
- .coord = &coord_htrfin,
- .moveset = moveset_htr,
-};
-
-PruneData
-pd_khuge_HTM = {
- .filename = "pt_khuge_HTM",
- .coord = &coord_khuge,
- .moveset = moveset_HTM,
-};
-
-void
-genptable(PruneData *pd)
-{
- Move ms[NMOVES];
- int d;
- uint64_t j, oldn;
-
- if (pd->generated)
- return;
-
- /* TODO: check if memory is enough, otherwise maybe exit gracefully? */
- pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t));
-
- if (read_ptable_file(pd)) {
- pd->generated = true;
- return;
- }
- pd->generated = true;
-
- fprintf(stderr, "Cannot load %s, generating it\n", pd->filename);
-
- moveset_to_list(pd->moveset, ms);
-
- /* We use 4 bits per value, so any distance >= 15 is set to 15 */
- for (j = 0; j < pd->coord->max; j++)
- ptable_update_index(pd, j, 15);
-
- for (j = 0; j < pd->coord->max; j++)
- if (ptableval_index(pd, j) != 15) {
- printf("Error, non-max value at index %lu!\n", j);
- break;
- }
- printf("Table set, ready to start\n");
-
- /*TODO: change, set to 0 for every solved state (might be more than 1)*/
- ptable_update(pd, (Cube){0}, 0);
- pd->n = 1;
- oldn = 0;
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- 0, pd->n - oldn, pd->n, pd->coord->max);
- oldn = 1;
- for (d = 0; d < 15 && pd->n < pd->coord->max; d++) {
- genptable_bfs(pd, d, ms);
- fprintf(stderr, "Depth %d done, generated %lu\t(%lu/%lu)\n",
- d+1, pd->n - oldn, pd->n, pd->coord->max);
- oldn = pd->n;
- }
-
- if (!write_ptable_file(pd))
- fprintf(stderr, "Error writing ptable file\n");
-}
-
-static void
-genptable_bfs(PruneData *pd, int d, Move *ms)
-{
- uint64_t i;
-
- for (i = 0; i < pd->coord->max; i++)
- if (ptableval_index(pd, i) == d)
- genptable_branch(pd, i, d, ms);
-}
-
-static void
-genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms)
-{
- int i, j;
- Cube ci, cc, c;
-
- /*
- * This is the only line of the whole program where we REALLY need an
- * anti-indexer function. We could get rid of it if only we could save
- * a cube object for each index value as we go, but then we would need
- * an incredible amount of memory to generate each ptable: assuming
- * fields in struct cube are 32 bit ints that would take 88 times the
- * memory of the table to be generated, more than 120Gb for
- * ptable_khuge for example!
- */
- ci = pd->coord->cube(ind);
-
- for (i = 0; i < pd->coord->ntrans; i++) {
- /* For simplicity trans[] is NULL when ntrans = 1 */
- c = i == 0 ? ci :
- apply_trans(pd->coord->trans[i], ci);
- for (j = 0; ms[j] != NULLMOVE; j++) {
- cc = apply_move(ms[j], c);
- if (ptableval(pd, cc) > d+1)
- ptable_update(pd, cc, d+1);
- }
- }
-}
-
-void
-print_ptable(PruneData *pd)
-{
- uint64_t i, a[16];
-
- for (i = 0; i < 16; i++)
- a[i] = 0;
-
- if (!pd->generated)
- genptable(pd);
-
- for (i = 0; i < pd->coord->max; i++)
- a[ptableval_index(pd, i)]++;
-
- fprintf(stderr, "Values for table %s\n", pd->filename);
- for (i = 0; i < 16; i++)
- printf("%2lu\t%10lu\n", i, a[i]);
-}
-
-uint64_t
-ptablesize(PruneData *pd)
-{
- return (pd->coord->max + 1) / 2;
-}
-
-static void
-ptable_update(PruneData *pd, Cube cube, int n)
-{
- uint64_t ind = pd->coord->index(cube);
- ptable_update_index(pd, ind, n);
-}
-
-static void
-ptable_update_index(PruneData *pd, uint64_t ind, int n)
-{
- uint8_t oldval2 = pd->ptable[ind/2];
- int other = (ind % 2) ? oldval2 % 16 : oldval2 / 16;
-
- pd->ptable[ind/2] = (ind % 2) ? 16*n + other : 16*other + n;
- pd->n++;
-}
-
-int
-ptableval(PruneData *pd, Cube cube)
-{
- return ptableval_index(pd, pd->coord->index(cube));
-}
-
-static int
-ptableval_index(PruneData *pd, uint64_t ind)
-{
- if (!pd->generated)
- genptable(pd);
-
- return (ind % 2) ? pd->ptable[ind/2] / 16 : pd->ptable[ind/2] % 16;
-}
-
-static bool
-read_ptable_file(PruneData *pd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t r;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- r = fread(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return r == ptablesize(pd);
-}
-
-static bool
-write_ptable_file(PruneData *pd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t written;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, pd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- written = fwrite(pd->ptable, sizeof(uint8_t), ptablesize(pd), f);
- fclose(f);
-
- return written == ptablesize(pd);
-}
-
diff --git a/old/2021-11-10-beforeremovingchecker/pruning.h b/old/2021-11-10-beforeremovingchecker/pruning.h
@@ -1,23 +0,0 @@
-#ifndef PRUNING_H
-#define PRUNING_H
-
-#include "symcoord.h"
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_cornershtr_HTM;
-extern PruneData pd_drud_sym16_HTM;
-extern PruneData pd_drud_eofb;
-extern PruneData pd_drudfin_noE_sym16_drud;
-extern PruneData pd_htr_drud;
-extern PruneData pd_htrfin_htr;
-extern PruneData pd_khuge_HTM;
-
-void genptable(PruneData *pd);
-void print_ptable(PruneData *pd);
-uint64_t ptablesize(PruneData *pd);
-int ptableval(PruneData *pd, Cube cube);
-
-#endif
-
diff --git a/old/2021-11-10-beforeremovingchecker/shell.c b/old/2021-11-10-beforeremovingchecker/shell.c
@@ -1,99 +0,0 @@
-#include "shell.h"
-
-static void cleanwhitespaces(char *line);
-static int parseline(char *line, char **v);
-
-static void
-cleanwhitespaces(char *line)
-{
- char *i;
-
- for (i = line; *i != 0; i++)
- if (*i == '\t' || *i == '\n')
- *i = ' ';
-}
-
-/* This function assumes that **v is large enough */
-static int
-parseline(char *line, char **v)
-{
- char *t;
- int n = 0;
-
- cleanwhitespaces(line);
-
- for (t = strtok(line, " "); t != NULL; t = strtok(NULL, " "))
- strcpy(v[n++], t);
-
- return n;
-}
-
-void
-exec_args(int c, char **v)
-{
- int i;
- Command *cmd = NULL;
- CommandArgs *args;
-
- for (i = 0; i < NCOMMANDS; i++)
- if (commands[i] != NULL && !strcmp(v[0], commands[i]->name))
- cmd = commands[i];
-
- if (cmd == NULL) {
- fprintf(stderr, "%s: command not found\n", v[0]);
- return;
- }
-
- args = cmd->parse_args(c-1, &v[1]);
- if (!args->success) {
- fprintf(stderr, "usage: %s\n", cmd->usage);
- return;
- }
-
- cmd->exec(args);
- free_args(args);
-}
-
-void
-launch()
-{
- int i, shell_argc;
- char line[MAXLINELEN], **shell_argv;
-
- shell_argv = malloc(MAXNTOKENS * sizeof(char *));
- for (i = 0; i < MAXNTOKENS; i++)
- shell_argv[i] = malloc((MAXTOKENLEN+1) * sizeof(char));
-
- fprintf(stderr, "Welcome to Nissy 2.0 (demo version).\n");
- fprintf(stderr, "Limited commands available. ");
- fprintf(stderr, "Type 'help' for a list.\n");
-
- while (true) {
- fprintf(stderr, "nissy-# ");
- if (fgets(line, MAXLINELEN, stdin) == NULL)
- break;
- shell_argc = parseline(line, shell_argv);
- exec_args(shell_argc, shell_argv);
- }
-
- for (i = 0; i < MAXNTOKENS; i++)
- free(shell_argv[i]);
- free(shell_argv);
-}
-
-/* We will have our main() here, for now */
-int
-main(int argc, char *argv[])
-{
- init_moves();
- init_trans();
- init_coord();
- init_symcoord();
-
- if (argc > 1)
- exec_args(argc-1, &argv[1]);
- else
- launch();
-
- return 0;
-}
diff --git a/old/2021-11-10-beforeremovingchecker/shell.h b/old/2021-11-10-beforeremovingchecker/shell.h
@@ -1,13 +0,0 @@
-#ifndef SHELL_H
-#define SHELL_H
-
-#include "commands.h"
-
-#define MAXLINELEN 10000
-#define MAXTOKENLEN 255
-#define MAXNTOKENS 255
-
-void exec_args(int c, char **v);
-void launch();
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/solve.c b/old/2021-11-10-beforeremovingchecker/solve.c
@@ -1,209 +0,0 @@
-#include "solve.h"
-
-/* Local functions ***********************************************************/
-
-static bool allowed_next(Move move, DfsData *dd);
-static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd);
-static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd);
-static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd);
-static void dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd);
-static bool dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd);
-
-/* Local functions ***********************************************************/
-
-static bool
-allowed_next(Move move, DfsData *dd)
-{
-
-/* TODO: remove the commented part, was added to moves.c
- static bool initialized = false;
- static bool commute[NMOVES][NMOVES], pnext[NMOVES][NMOVES][NMOVES];
-
- if (!initialized) {
- Cube c1, c2;
- int i, j, k;
- bool p1, p2, cij;
-
- for (i = 0; i < NMOVES; i++) {
- for (j = 0; j < NMOVES; j++) {
- c1 = apply_move(i, apply_move(j, (Cube){0}));
- c2 = apply_move(j, apply_move(i, (Cube){0}));
- commute[i][j] = equal(c1, c2) && i && j;
- for (k = 0; k < NMOVES; k++) {
- p1 = j && base_move(j) == base_move(k);
- p2 = i && base_move(i) == base_move(k);
- cij = commute[i][j];
- pnext[i][j][k] = !(p1 || (cij && p2));
- }
- }
- }
-
- initialized = true;
- }
-
- if (!pnext[dd->last2][dd->last1][move])
- return false;
-
- if (commute[dd->last1][move])
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-*/
-
- if (!possible_next(dd->last2, dd->last1, move))
- return false;
-
- if (commute(dd->last1, move))
- return dd->move_position[dd->last1] < dd->move_position[move];
-
- return true;
-}
-
-static void
-dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
-{
- if (dfs_stop(c, s, opts, dd))
- return;
-
- if (dfs_check_solved(s, opts, dd))
- return;
-
- dfs_branch(c, s, opts, dd);
-
- if (opts->can_niss && !dd->niss)
- dfs_niss(c, s, opts, dd);
-}
-
-static void
-dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
-{
- Move m, l1 = dd->last1, l2 = dd->last2, *moves = dd->sorted_moves;
-
- int i, maxnsol = opts->max_solutions;
-
- for (i = 0; moves[i] != NULLMOVE && dd->sols->len < maxnsol; i++) {
- m = moves[i];
- if (allowed_next(m, dd)) {
- dd->last2 = dd->last1;
- dd->last1 = m;
- append_move(dd->current_alg, m, dd->niss);
-
- dfs(apply_move(m, c), s, opts, dd);
-
- dd->current_alg->len--;
- dd->last2 = l2;
- dd->last1 = l1;
- }
- }
-}
-
-static bool
-dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd)
-{
- if (dd->lb != 0)
- return false;
-
- if (dd->current_alg->len == dd->d) {
- if (s->is_valid(dd->current_alg) || opts->all)
- append_alg(dd->sols, dd->current_alg);
-
- if (opts->feedback)
- print_alg(dd->current_alg, false);
- }
-
- return true;
-}
-
-static void
-dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
-{
- Move l1 = dd->last1, l2 = dd->last2;
- CubeTarget ct;
-
- ct.cube = apply_move(inverse_move(l1), (Cube){0});
- ct.target = 1;
-
- if (dd->current_alg->len == 0 || s->estimate(ct)) {
- dd->niss = true;
- dd->last1 = NULLMOVE;
- dd->last2 = NULLMOVE;
-
- dfs(inverse_cube(c), s, opts, dd);
-
- dd->last1 = l1;
- dd->last2 = l2;
- dd->niss = false;
- }
-}
-
-static bool
-dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd)
-{
- CubeTarget ct = {
- .cube = c,
- .target = dd->d - dd->current_alg->len
- };
-
- if (dd->sols->len >= opts->max_solutions)
- return true;
-
- dd->lb = s->estimate(ct);
- if (opts->can_niss && !dd->niss)
- dd->lb = MIN(1, dd->lb);
-
- if (dd->current_alg->len + dd->lb > dd->d)
- return true;
-
- return false;
-}
-
-/* Public functions **********************************************************/
-
-AlgList *
-solve(Cube cube, Step *step, SolveOptions *opts)
-{
- AlgListNode *node;
- AlgList *sols = new_alglist();
- Cube c;
-
- if (step->detect != NULL)
- step->pre_trans = step->detect(cube);
- c = apply_trans(step->pre_trans, cube);
-
- DfsData dd = {
- .m = 0,
- .niss = false,
- .lb = -1,
- .last1 = NULLMOVE,
- .last2 = NULLMOVE,
- .sols = sols,
- .current_alg = new_alg("")
- };
-
- if (step->ready != NULL && !step->ready(c)) {
- fprintf(stderr, "Cube not ready for solving step: ");
- fprintf(stderr, "%s\n", step->ready_msg);
- return sols;
- }
-
- moveset_to_list(step->moveset, dd.sorted_moves);
- movelist_to_position(dd.sorted_moves, dd.move_position);
-
- for (dd.d = opts->min_moves;
- dd.d <= opts->max_moves &&
- !(sols->len && opts->optimal_only) &&
- sols->len < opts->max_solutions;
- dd.d++) {
- if (opts->feedback)
- fprintf(stderr,
- "Found %d solutions, searching depth %d...\n",
- sols->len, dd.d);
- dfs(c, step, opts, &dd);
- }
-
- for (node = sols->first; node != NULL; node = node->next)
- transform_alg(inverse_trans(step->pre_trans), node->alg);
-
- free_alg(dd.current_alg);
- return sols;
-}
diff --git a/old/2021-11-10-beforeremovingchecker/solve.h b/old/2021-11-10-beforeremovingchecker/solve.h
@@ -1,9 +0,0 @@
-#ifndef SOLVE_H
-#define SOLVE_H
-
-#include "moves.h"
-#include "trans.h"
-
-AlgList * solve(Cube cube, Step *step, SolveOptions *opts);
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/steps.c b/old/2021-11-10-beforeremovingchecker/steps.c
@@ -1,916 +0,0 @@
-#include "steps.h"
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int estimate_eoany_HTM(CubeTarget ct);
-static int estimate_eofb_HTM(CubeTarget ct);
-static int estimate_coany_HTM(CubeTarget ct);
-static int estimate_coud_HTM(CubeTarget ct);
-static int estimate_coany_URF(CubeTarget ct);
-static int estimate_coud_URF(CubeTarget ct);
-static int estimate_corners_HTM(CubeTarget ct);
-static int estimate_cornershtr_HTM(CubeTarget ct);
-static int estimate_corners_URF(CubeTarget ct);
-static int estimate_cornershtr_URF(CubeTarget ct);
-static int estimate_drany_HTM(CubeTarget ct);
-static int estimate_drud_HTM(CubeTarget ct);
-static int estimate_drud_eofb(CubeTarget ct);
-static int estimate_dr_eofb(CubeTarget ct);
-static int estimate_drudfin_drud(CubeTarget ct);
-static int estimate_htr_drud(CubeTarget ct);
-static int estimate_htrfin_htr(CubeTarget ct);
-static int estimate_optimal_HTM(CubeTarget ct);
-
-/* Validators ****************************************************************/
-
-static bool always_valid(Alg *alg);
-static bool validate_singlecw_ending(Alg *alg);
-
-/* Pre-transformation detectors **********************************************/
-
-static Trans detect_pretrans_eofb(Cube cube);
-static Trans detect_pretrans_drud(Cube cube);
-
-/* Messages for when cube is not ready ***************************************/
-
-static char check_centers_msg[100] = "cube must be oriented (centers solved)";
-static char check_eo_msg[100] = "EO must be solved on given axis";
-static char check_dr_msg[100] = "DR must be solved on given axis";
-static char check_htr_msg[100] = "HTR must be solved";
-static char check_drany_msg[100] = "DR must be solved on at least one axis";
-
-/* Steps *********************************************************************/
-
-Step
-optimal_HTM = {
- .shortname = "optimal",
- .name = "Optimal solve (in HTM)",
-
- .estimate = estimate_optimal_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = always_valid,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-/* EO steps **************************/
-Step
-eoany_HTM = {
- .shortname = "eo",
- .name = "EO on any axis",
-
- .estimate = estimate_eoany_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-eofb_HTM = {
- .shortname = "eofb",
- .name = "EO on F/B",
-
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-eorl_HTM = {
- .shortname = "eorl",
- .name = "EO on R/L",
-
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = ur,
-};
-
-Step
-eoud_HTM = {
- .shortname = "eoud",
- .name = "EO on U/D",
-
- .estimate = estimate_eofb_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = fd,
-};
-
-/* CO steps **************************/
-Step
-coany_HTM = {
- .shortname = "co",
- .name = "CO on any axis",
-
- .estimate = estimate_coany_HTM,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-coud_HTM = {
- .shortname = "coud",
- .name = "CO on U/D",
-
- .estimate = estimate_coud_HTM,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-corl_HTM = {
- .shortname = "corl",
- .name = "CO on R/L",
-
- .estimate = estimate_coud_HTM,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = rf,
-};
-
-Step
-cofb_HTM = {
- .shortname = "cofb",
- .name = "CO on F/B",
-
- .estimate = estimate_coud_HTM,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = fd,
-};
-
-Step
-coany_URF = {
- .shortname = "co-URF",
- .name = "CO any axis (URF moveset)",
-
- .estimate = estimate_coany_URF,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_URF,
-
- .pre_trans = uf,
-};
-
-Step
-coud_URF = {
- .shortname = "coud-URF",
- .name = "CO on U/D (URF moveset)",
-
- .estimate = estimate_coud_URF,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_URF,
-
- .pre_trans = uf,
-};
-
-Step
-corl_URF = {
- .shortname = "corl-URF",
- .name = "CO on R/L (URF moveset)",
-
- .estimate = estimate_coud_URF,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_URF,
-
- .pre_trans = rf,
-};
-
-Step
-cofb_URF = {
- .shortname = "cofb-URF",
- .name = "CO on F/B (URF moveset)",
-
- .estimate = estimate_coud_URF,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_URF,
-
- .pre_trans = fd,
-};
-
-/* Misc corner steps *****************/
-Step
-cornershtr_HTM = {
- .shortname = "chtr",
- .name = "Solve corners to HTR state",
-
- .estimate = estimate_cornershtr_HTM,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-cornershtr_URF = {
- .shortname = "chtr-URF",
- .name = "Solve corners to HTR state (URF moveset)",
-
- .estimate = estimate_cornershtr_URF,
- .ready = NULL,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_URF,
-
- .pre_trans = uf,
-};
-
-Step
-corners_HTM = {
- .shortname = "corners",
- .name = "Solve corners",
-
- .estimate = estimate_corners_HTM,
- .ready = NULL,
- .is_valid = always_valid,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-corners_URF = {
- .shortname = "corners-URF",
- .name = "Solve corners (URF moveset)",
-
- .estimate = estimate_corners_URF,
- .ready = NULL,
- .is_valid = always_valid,
- .moveset = moveset_URF,
-
- .pre_trans = uf,
-};
-
-/* DR steps **************************/
-Step
-drany_HTM = {
- .shortname = "dr",
- .name = "DR on any axis",
-
- .estimate = estimate_drany_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-drud_HTM = {
- .shortname = "drud",
- .name = "DR on U/D",
-
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = uf,
-};
-
-Step
-drrl_HTM = {
- .shortname = "drrl",
- .name = "DR on R/L",
-
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = rf,
-};
-
-Step
-drfb_HTM = {
- .shortname = "drfb",
- .name = "DR on F/B",
-
- .estimate = estimate_drud_HTM,
- .ready = check_centers,
- .ready_msg = check_centers_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_HTM,
-
- .pre_trans = fd,
-};
-
-/* DR from EO */
-Step
-dr_eo = {
- .shortname = "dr-eo",
- .name = "DR without breaking EO (automatically detected)",
-
- .estimate = estimate_dr_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .detect = detect_pretrans_eofb,
-};
-
-Step
-dr_eofb = {
- .shortname = "dr-eofb",
- .name = "DR on U/D or R/L without breaking EO on F/B",
-
- .estimate = estimate_dr_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = uf,
-};
-
-Step
-dr_eorl = {
- .shortname = "dr-eorl",
- .name = "DR on U/D or F/B without breaking EO on R/L",
-
- .estimate = estimate_dr_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = ur,
-};
-
-Step
-dr_eoud = {
- .shortname = "dr-eoud",
- .name = "DR on R/L or F/B without breaking EO on U/R",
-
- .estimate = estimate_dr_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = fd,
-};
-
-Step
-drud_eofb = {
- .shortname = "drud-eofb",
- .name = "DR on U/D without breaking EO on F/B",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = uf,
-};
-
-Step
-drrl_eofb = {
- .shortname = "drrl-eofb",
- .name = "DR on R/L without breaking EO on F/B",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = rf,
-};
-
-Step
-drud_eorl = {
- .shortname = "drud-eorl",
- .name = "DR on U/D without breaking EO on R/L",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = ur,
-};
-
-Step
-drfb_eorl = {
- .shortname = "drfb-eorl",
- .name = "DR on F/B without breaking EO on R/L",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = fr,
-};
-
-Step
-drfb_eoud = {
- .shortname = "drfb-eoud",
- .name = "DR on F/B without breaking EO on U/D",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = fd,
-};
-
-Step
-drrl_eoud = {
- .shortname = "drrl-eoud",
- .name = "DR on R/L without breaking EO on U/D",
-
- .estimate = estimate_drud_eofb,
- .ready = check_eofb,
- .ready_msg = check_eo_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_eofb,
-
- .pre_trans = rd,
-};
-
-/* DR finish steps */
-Step
-dranyfin_DR = {
- .shortname = "drfin",
- .name = "DR finish on any axis without breaking DR",
-
- .estimate = estimate_drudfin_drud,
- .ready = check_drud,
- .ready_msg = check_drany_msg,
- .is_valid = always_valid,
- .moveset = moveset_drud,
-
- .detect = detect_pretrans_drud,
-};
-
-Step
-drudfin_drud = {
- .shortname = "drudfin",
- .name = "DR finish on U/D without breaking DR",
-
- .estimate = estimate_drudfin_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = always_valid,
- .moveset = moveset_drud,
-
- .pre_trans = uf,
-};
-
-Step
-drrlfin_drrl = {
- .shortname = "drrlfin",
- .name = "DR finish on R/L without breaking DR",
-
- .estimate = estimate_drudfin_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = always_valid,
- .moveset = moveset_drud,
-
- .pre_trans = rf,
-};
-
-Step
-drfbfin_drfb = {
- .shortname = "drfbfin",
- .name = "DR finish on F/B without breaking DR",
-
- .estimate = estimate_drudfin_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = always_valid,
- .moveset = moveset_drud,
-
- .pre_trans = fd,
-};
-
-/* HTR from DR */
-Step
-htr_any = {
- .shortname = "htr",
- .name = "HTR from DR",
-
- .estimate = estimate_htr_drud,
- .ready = check_drud,
- .ready_msg = check_drany_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_drud,
-
- .detect = detect_pretrans_drud,
-};
-
-Step
-htr_drud = {
- .shortname = "htr-drud",
- .name = "HTR from DR on U/D",
-
- .estimate = estimate_htr_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_drud,
-
- .pre_trans = uf,
-};
-
-Step
-htr_drrl = {
- .shortname = "htr-drrl",
- .name = "HTR from DR on R/L",
-
- .estimate = estimate_htr_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_drud,
-
- .pre_trans = rf,
-};
-
-Step
-htr_drfb = {
- .shortname = "htr-drfb",
- .name = "HTR from DR on F/B",
-
- .estimate = estimate_htr_drud,
- .ready = check_drud,
- .ready_msg = check_dr_msg,
- .is_valid = validate_singlecw_ending,
- .moveset = moveset_drud,
-
- .pre_trans = fd,
-};
-
-/* HTR finish */
-Step
-htrfin_htr = {
- .shortname = "htrfin",
- .name = "HTR finish without breaking HTR",
-
- .estimate = estimate_htrfin_htr,
- .ready = check_htr,
- .ready_msg = check_htr_msg,
- .is_valid = always_valid,
- .moveset = moveset_htr,
-
- .pre_trans = uf,
-};
-
-Step *steps[NSTEPS] = {
- &optimal_HTM, /* first is default */
-
- &eoany_HTM,
- &eofb_HTM,
- &eorl_HTM,
- &eoud_HTM,
-
- &coany_HTM,
- &coud_HTM,
- &corl_HTM,
- &cofb_HTM,
-
- &coany_URF,
- &coud_URF,
- &corl_URF,
- &cofb_URF,
-
- &drany_HTM,
- &drud_HTM,
- &drrl_HTM,
- &drfb_HTM,
-
- &dr_eo,
- &dr_eofb,
- &dr_eorl,
- &dr_eoud,
- &drud_eofb,
- &drrl_eofb,
- &drud_eorl,
- &drfb_eorl,
- &drfb_eoud,
- &drrl_eoud,
-
- &dranyfin_DR,
- &drudfin_drud,
- &drrlfin_drrl,
- &drfbfin_drfb,
-
- &htr_any,
- &htr_drud,
- &htr_drrl,
- &htr_drfb,
-
- &htrfin_htr,
-
- &cornershtr_HTM,
- &cornershtr_URF,
- &corners_HTM,
- &corners_URF,
-};
-
-/* Standard checkers (return lower bound) ************************************/
-
-static int
-estimate_eoany_HTM(CubeTarget ct)
-{
- int r1, r2, r3;
-
- r1 = ptableval(&pd_eofb_HTM, ct.cube);
- r2 = ptableval(&pd_eofb_HTM, apply_trans(ur, ct.cube));
- r3 = ptableval(&pd_eofb_HTM, apply_trans(fd, ct.cube));
-
- return MIN(r1, MIN(r2, r3));
-}
-
-static int
-estimate_eofb_HTM(CubeTarget ct)
-{
- return ptableval(&pd_eofb_HTM, ct.cube);
-}
-
-static int
-estimate_coany_HTM(CubeTarget ct)
-{
- int r1, r2, r3;
-
- r1 = ptableval(&pd_coud_HTM, ct.cube);
- r2 = ptableval(&pd_coud_HTM, apply_trans(rf, ct.cube));
- r3 = ptableval(&pd_coud_HTM, apply_trans(fd, ct.cube));
-
- return MIN(r1, MIN(r2, r3));
-}
-
-static int
-estimate_coud_HTM(CubeTarget ct)
-{
- return ptableval(&pd_coud_HTM, ct.cube);
-}
-
-static int
-estimate_coany_URF(CubeTarget ct)
-{
- int r1, r2, r3;
- CubeTarget ct2, ct3;
-
- ct2.cube = apply_trans(rf, ct.cube);
- ct2.target = ct.target;
-
- ct3.cube = apply_trans(fd, ct.cube);
- ct3.target = ct.target;
-
- r1 = estimate_coud_URF(ct);
- r2 = estimate_coud_URF(ct2);
- r3 = estimate_coud_URF(ct3);
-
- return MIN(r1, MIN(r2, r3));
-}
-
-static int
-estimate_coud_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- CubeTarget ct2 = {.cube = apply_move(z, ct.cube), .target = ct.target};
- CubeTarget ct3 = {.cube = apply_move(x, ct.cube), .target = ct.target};
-
- int ud = estimate_coud_HTM(ct);
- int rl = estimate_coud_HTM(ct2);
- int fb = estimate_coud_HTM(ct3);
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-estimate_corners_HTM(CubeTarget ct)
-{
- return ptableval(&pd_corners_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_HTM(CubeTarget ct)
-{
- return ptableval(&pd_cornershtr_HTM, ct.cube);
-}
-
-static int
-estimate_cornershtr_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_cornershtr_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_corners_URF(CubeTarget ct)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int c, ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++) {
- ct.cube = apply_alg(rotation_alg(i), ct.cube);
- c = estimate_corners_HTM(ct);
- ret = MIN(ret, c);
- }
-
- return ret;
-}
-
-static int
-estimate_drany_HTM(CubeTarget ct)
-{
- int r1, r2, r3;
-
- r1 = ptableval(&pd_drud_sym16_HTM, ct.cube);
- r2 = ptableval(&pd_drud_sym16_HTM, apply_trans(rf, ct.cube));
- r3 = ptableval(&pd_drud_sym16_HTM, apply_trans(fd, ct.cube));
-
- return MIN(r1, MIN(r2, r3));
-}
-
-static int
-estimate_drud_HTM(CubeTarget ct)
-{
- return ptableval(&pd_drud_sym16_HTM, ct.cube);
-}
-
-static int
-estimate_drud_eofb(CubeTarget ct)
-{
- return ptableval(&pd_drud_eofb, ct.cube);
-}
-
-static int
-estimate_dr_eofb(CubeTarget ct)
-{
- int r1, r2;
-
- r1 = ptableval(&pd_drud_eofb, ct.cube);
- r2 = ptableval(&pd_drud_eofb, apply_trans(rf, ct.cube));
-
- return MIN(r1, r2);
-}
-
-static int
-estimate_drudfin_drud(CubeTarget ct)
-{
- int val = ptableval(&pd_drudfin_noE_sym16_drud, ct.cube);
-
- if (val != 0)
- return val;
-
- return ct.cube.epose % 24 == 0 ? 0 : 1;
-}
-
-static int
-estimate_htr_drud(CubeTarget ct)
-{
- return ptableval(&pd_htr_drud, ct.cube);
-}
-
-static int
-estimate_htrfin_htr(CubeTarget ct)
-{
- return ptableval(&pd_htrfin_htr, ct.cube);
-}
-
-static int
-estimate_optimal_HTM(CubeTarget ct)
-{
- int dr1, dr2, dr3, cor, ret;
- Cube cube = ct.cube;
-
- dr1 = ptableval(&pd_khuge_HTM, cube);
- cor = estimate_corners_HTM(ct);
- ret = MAX(dr1, cor);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(rf, ct.cube);
- dr2 = ptableval(&pd_khuge_HTM, cube);
- ret = MAX(ret, dr2);
-
- if (ret > ct.target)
- return ret;
-
- cube = apply_trans(fd, ct.cube);
- dr3 = ptableval(&pd_khuge_HTM, cube);
-
- /* Michiel de Bondt's trick */
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- dr3++;
-
- return MAX(ret, dr3);
-}
-
-/* Validators ****************************************************************/
-
-static bool
-always_valid(Alg *alg)
-{
- return true;
-}
-
-static bool
-validate_singlecw_ending(Alg *alg)
-{
- int i;
- bool nor, inv;
- Move l2 = NULLMOVE, l1 = NULLMOVE, l2i = NULLMOVE, l1i = NULLMOVE;
-
- for (i = 0; i < alg->len; i++) {
- if (alg->inv[i]) {
- l2i = l1i;
- l1i = alg->move[i];
- } else {
- l2 = l1;
- l1 = alg->move[i];
- }
- }
-
- nor = l1 ==base_move(l1) && (!commute(l1, l2) ||l2 ==base_move(l2));
- inv = l1i==base_move(l1i) && (!commute(l1i,l2i)||l2i==base_move(l2i));
-
- return nor && inv;
-}
-
-/* Pre-transformation detectors **********************************************/
-
-static Trans
-detect_pretrans_eofb(Cube cube)
-{
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++)
- if (check_eofb(apply_trans(i, cube)))
- return i;
-
- return 0;
-}
-
-static Trans
-detect_pretrans_drud(Cube cube)
-{
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++)
- if (check_drud(apply_trans(i, cube)))
- return i;
-
- return 0;
-}
diff --git a/old/2021-11-10-beforeremovingchecker/steps.h b/old/2021-11-10-beforeremovingchecker/steps.h
@@ -1,10 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "pruning.h"
-
-#define NSTEPS 50
-
-extern Step * steps[NSTEPS];
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/symcoord.c b/old/2021-11-10-beforeremovingchecker/symcoord.c
@@ -1,359 +0,0 @@
-#include "symcoord.h"
-
-static Cube antindex_coud_sym16(uint64_t ind);
-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_khuge(uint64_t ind);
-
-static uint64_t index_coud_sym16(Cube cube);
-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_khuge(Cube cube);
-
-static void gensym(SymData *sd);
-static bool read_symdata_file(SymData *sd);
-static bool write_symdata_file(SymData *sd);
-
-/* Transformation groups and symmetry data ***********************************/
-
-static Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-static SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static SymData
-sd_cp_16 = {
- .filename = "sd_cp_16",
- .coord = &coord_cp,
- .sym_coord = &coord_cp_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int nsymdata = 3;
-static SymData * all_sd[] = {
- &sd_coud_16,
- &sd_cp_16,
- &sd_eofbepos_16,
-};
-
-
-/* Coordinates and their implementation **************************************/
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_cp_sym16 = {
- .index = index_cp_sym16,
- .cube = antindex_cp_sym16,
- .check = check_cp,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_drudfin_noE_sym16 = {
- .index = index_drudfin_noE_sym16,
- .cube = antindex_drudfin_noE_sym16,
- .check = check_drudfin_noE,
- .max = FACTORIAL8 * 2768,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-/* Functions *****************************************************************/
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_16.rep[ind];
-}
-
-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_khuge(uint64_t ind)
-{
- Cube c;
-
- c = antindex_eofbepos_sym16(ind/(FACTORIAL4*POW3TO7));
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[coord_coud.index(cube)];
-}
-
-static uint64_t
-index_cp_sym16(Cube cube)
-{
- return sd_cp_16.class[coord_cp.index(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[coord_eofbepos.index(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_drudfin_noE_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_cp_16.transtorep[coord_cp.index(cube)];
- c = apply_trans(t, cube);
-
- return index_cp_sym16(c) * FACTORIAL8 + coord_epud.index(c);
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[coord_eofbepos.index(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[coord_eofbepos.index(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-/* Other functions ***********************************************************/
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-void
-init_symcoord()
-{
- int i;
-
- static bool initialized = false;
- if (initialized)
- return;
- initialized = true;
-
- for (i = 0; i < nsymdata; i++)
- gensym(all_sd[i]);
-}
-
diff --git a/old/2021-11-10-beforeremovingchecker/symcoord.h b/old/2021-11-10-beforeremovingchecker/symcoord.h
@@ -1,15 +0,0 @@
-#ifndef SYMCOORD_H
-#define SYMCOORD_H
-
-#include "coord.h"
-
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_cp_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_drudfin_noE_sym16;
-extern Coordinate coord_khuge;
-
-void init_symcoord();
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/trans.c b/old/2021-11-10-beforeremovingchecker/trans.c
@@ -1,372 +0,0 @@
-#include "trans.h"
-
-/* Local functions ***********************************************************/
-
-static bool read_ttables_file();
-static Cube rotate_via_compose(Trans r, Cube c, PieceFilter f);
-static bool write_ttables_file();
-
-/* Tables and other data *****************************************************/
-
-static int ep_mirror[12] = {
- [UF] = UF, [UL] = UR, [UB] = UB, [UR] = UL,
- [DF] = DF, [DL] = DR, [DB] = DB, [DR] = DL,
- [FR] = FL, [FL] = FR, [BL] = BR, [BR] = BL
-};
-
-static int cp_mirror[8] = {
- [UFR] = UFL, [UFL] = UFR, [UBL] = UBR, [UBR] = UBL,
- [DFR] = DFL, [DFL] = DFR, [DBL] = DBR, [DBR] = DBL
-};
-
-static int cpos_mirror[6] = {
- [U_center] = U_center, [D_center] = D_center,
- [R_center] = L_center, [L_center] = R_center,
- [F_center] = F_center, [B_center] = B_center
-};
-
-/* TODO Is there a more elegant way? */
-static char rotation_alg_string[100][NROTATIONS] = {
- [uf] = "", [ur] = "y", [ub] = "y2", [ul] = "y3",
- [df] = "z2", [dr] = "y z2", [db] = "x2", [dl] = "y3 z2",
- [rf] = "z3", [rd] = "z3 y", [rb] = "z3 y2", [ru] = "z3 y3",
- [lf] = "z", [ld] = "z y3", [lb] = "z y2", [lu] = "z y",
- [fu] = "x y2", [fr] = "x y", [fd] = "x", [fl] = "x y3",
- [bu] = "x3", [br] = "x3 y", [bd] = "x3 y2", [bl] = "x3 y3",
-};
-
-static int epose_source[NTRANS]; /* 0=epose, 1=eposs, 2=eposm */
-static int eposs_source[NTRANS];
-static int eposm_source[NTRANS];
-static int eofb_source[NTRANS]; /* 0=eoud, 1=eorl, 2=eofb */
-static int eorl_source[NTRANS];
-static int eoud_source[NTRANS];
-static int coud_source[NTRANS]; /* 0=coud, 1=corl, 2=cofb */
-static int cofb_source[NTRANS];
-static int corl_source[NTRANS];
-
-static int epose_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposs_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eposm_ttable[NTRANS][FACTORIAL12/FACTORIAL8];
-static int eo_ttable[NTRANS][POW2TO11];
-static int cp_ttable[NTRANS][FACTORIAL8];
-static int co_ttable[NTRANS][POW3TO7];
-static int cpos_ttable[NTRANS][FACTORIAL6];
-static Move moves_ttable[NTRANS][NMOVES];
-
-/* Local functions implementation ********************************************/
-
-void
-init_trans() {
- static bool initialized = false;
- if (initialized)
- return;
- initialized = true;
-
- Cube aux, cube, c[3];
- CubeArray epcp;
- int i, eparr[12], eoarr[12], cparr[8], coarr[8];
- unsigned int ui;
- Move mi, move;
- Trans m;
-
- /* Compute sources */
- for (i = 0; i < NTRANS; i++) {
- cube = apply_alg(rotation_alg(i), (Cube){0});
-
- epose_source[i] = edge_slice(what_edge_at(cube, FR));
- eposs_source[i] = edge_slice(what_edge_at(cube, UR));
- eposm_source[i] = edge_slice(what_edge_at(cube, UF));
- eofb_source[i] = what_center_at(cube, F_center)/2;
- eorl_source[i] = what_center_at(cube, R_center)/2;
- eoud_source[i] = what_center_at(cube, U_center)/2;
- coud_source[i] = what_center_at(cube, U_center)/2;
- cofb_source[i] = what_center_at(cube, F_center)/2;
- corl_source[i] = what_center_at(cube, R_center)/2;
- }
-
- if (read_ttables_file())
- return;
-
- fprintf(stderr, "Cannot load %s, generating it\n", "ttables");
-
- /* Initialize tables */
- for (m = 0; m < NTRANS; m++) {
- epcp = (CubeArray){ .ep = eparr, .cp = cparr };
- cube = apply_alg(rotation_alg(m), (Cube){0});
- cube_to_arrays(cube, &epcp, pf_epcp);
- if (m >= NROTATIONS) {
- apply_permutation(ep_mirror, eparr, 12);
- apply_permutation(cp_mirror, cparr, 8);
- }
-
- for (ui = 0; ui < FACTORIAL12/FACTORIAL8; ui++) {
- c[0] = admissible_ep((Cube){ .epose = ui }, pf_e);
- c[1] = admissible_ep((Cube){ .eposs = ui }, pf_s);
- c[2] = admissible_ep((Cube){ .eposm = ui }, pf_m);
-
- cube = rotate_via_compose(m,c[epose_source[m]],pf_ep);
- epose_ttable[m][ui] = cube.epose;
-
- cube = rotate_via_compose(m,c[eposs_source[m]],pf_ep);
- eposs_ttable[m][ui] = cube.eposs;
-
- cube = rotate_via_compose(m,c[eposm_source[m]],pf_ep);
- eposm_ttable[m][ui] = cube.eposm;
- }
- for (ui = 0; ui < POW2TO11; ui++ ) {
- int_to_sum_zero_array(ui, 2, 12, eoarr);
- apply_permutation(eparr, eoarr, 12);
- eo_ttable[m][ui] = digit_array_to_int(eoarr, 11, 2);
- }
- for (ui = 0; ui < POW3TO7; ui++) {
- int_to_sum_zero_array(ui, 3, 8, coarr);
- apply_permutation(cparr, coarr, 8);
- co_ttable[m][ui] = digit_array_to_int(coarr, 7, 3);
- if (m >= NROTATIONS)
- co_ttable[m][ui] =
- invert_digits(co_ttable[m][ui], 3, 7);
- }
- for (ui = 0; ui < FACTORIAL8; ui++) {
- cube = (Cube){ .cp = ui };
- cube = rotate_via_compose(m, cube, pf_cp);
- cp_ttable[m][ui] = cube.cp;
- }
- for (ui = 0; ui < FACTORIAL6; ui++) {
- cube = (Cube){ .cpos = ui };
- cube = rotate_via_compose(m, cube, pf_cpos);
- cpos_ttable[m][ui] = cube.cpos;
- }
- for (mi = 0; mi < NMOVES; mi++) {
- /* Old version:
- *
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move(move), aux);
- mirr = apply_trans(uf_mirror, cube);
- if (is_solved(cube) || is_solved(mirr))
- moves_ttable[m][mi] = move;
- }
- */
-
- aux = apply_trans(m, apply_move(mi, (Cube){0}));
- for (move = 0; move < NMOVES; move++) {
- cube = apply_move(inverse_move(move), aux);
- if (is_solved(cube)) {
- moves_ttable[m][mi] = move;
- break;
- }
- }
- }
- }
-
- if (!write_ttables_file())
- fprintf(stderr, "Error writing ttables\n");
-}
-
-static bool
-read_ttables_file()
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+20];
- int b = sizeof(int);
- bool r = true;
- Move m;
-
- /* Table sizes, used for reading and writing files */
- uint64_t me[11] = {
- [0] = FACTORIAL12/FACTORIAL8,
- [1] = FACTORIAL12/FACTORIAL8,
- [2] = FACTORIAL12/FACTORIAL8,
- [3] = POW2TO11,
- [4] = FACTORIAL8,
- [5] = POW3TO7,
- [6] = FACTORIAL6,
- [7] = NMOVES
- };
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, "ttables");
-
- if ((f = fopen(fname, "rb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fread(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fread(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fread(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fread(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fread(cp_ttable[m], b, me[4], f) == me[4];
- r = r && fread(co_ttable[m], b, me[5], f) == me[5];
- r = r && fread(cpos_ttable[m], b, me[6], f) == me[6];
- r = r && fread(moves_ttable[m], b, me[7], f) == me[7];
- }
-
- fclose(f);
- return r;
-}
-
-static Cube
-rotate_via_compose(Trans r, Cube c, PieceFilter f)
-{
- static int zero12[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- static int zero8[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- static CubeArray ma = {
- .ep = ep_mirror,
- .eofb = zero12,
- .eorl = zero12,
- .eoud = zero12,
- .cp = cp_mirror,
- .coud = zero8,
- .corl = zero8,
- .cofb = zero8,
- .cpos = cpos_mirror
- };
-
- Alg *inv = inverse_alg(rotation_alg(r));
- Cube ret = {0};
-
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
- ret = apply_alg_generic(inv, ret, f, true);
-
- ret = compose_filtered(c, ret, f);
-
- ret = apply_alg_generic(rotation_alg(r), ret, f, true);
- if (r >= NROTATIONS)
- ret = move_via_arrays(&ma, ret, f);
-
- free_alg(inv);
- return ret;
-}
-
-static bool
-write_ttables_file()
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+20];
- bool r = true;
- int b = sizeof(int);
- Move m;
-
- /* Table sizes, used for reading and writing files */
- uint64_t me[11] = {
- [0] = FACTORIAL12/FACTORIAL8,
- [1] = FACTORIAL12/FACTORIAL8,
- [2] = FACTORIAL12/FACTORIAL8,
- [3] = POW2TO11,
- [4] = FACTORIAL8,
- [5] = POW3TO7,
- [6] = FACTORIAL6,
- [7] = NMOVES
- };
-
- strcpy(fname, tabledir);
- strcat(fname, "/ttables");
-
- if ((f = fopen(fname, "wb")) == NULL)
- return false;
-
- for (m = 0; m < NTRANS; m++) {
- r = r && fwrite(epose_ttable[m], b, me[0], f) == me[0];
- r = r && fwrite(eposs_ttable[m], b, me[1], f) == me[1];
- r = r && fwrite(eposm_ttable[m], b, me[2], f) == me[2];
- r = r && fwrite(eo_ttable[m], b, me[3], f) == me[3];
- r = r && fwrite(cp_ttable[m], b, me[4], f) == me[4];
- r = r && fwrite(co_ttable[m], b, me[5], f) == me[5];
- r = r && fwrite(cpos_ttable[m], b, me[6], f) == me[6];
- r = r && fwrite(moves_ttable[m], b, me[7], f) == me[7];
- }
-
- fclose(f);
- return r;
-}
-
-/* Public functions **********************************************************/
-
-Cube
-apply_trans(Trans t, Cube cube)
-{
- /*init_trans();*/
-
- int aux_epos[3] = { cube.epose, cube.eposs, cube.eposm };
- int aux_eo[3] = { cube.eoud, cube.eorl, cube.eofb };
- int aux_co[3] = { cube.coud, cube.corl, cube.cofb };
-
- return (Cube) {
- .epose = epose_ttable[t][aux_epos[epose_source[t]]],
- .eposs = eposs_ttable[t][aux_epos[eposs_source[t]]],
- .eposm = eposm_ttable[t][aux_epos[eposm_source[t]]],
- .eofb = eo_ttable[t][aux_eo[eofb_source[t]]],
- .eorl = eo_ttable[t][aux_eo[eorl_source[t]]],
- .eoud = eo_ttable[t][aux_eo[eoud_source[t]]],
- .coud = co_ttable[t][aux_co[coud_source[t]]],
- .corl = co_ttable[t][aux_co[corl_source[t]]],
- .cofb = co_ttable[t][aux_co[cofb_source[t]]],
- .cp = cp_ttable[t][cube.cp],
- .cpos = cpos_ttable[t][cube.cpos]
- };
-}
-
-Trans
-inverse_trans(Trans t)
-{
- /* TODO is there a more elegant way? */
- static Trans inverse_trans_aux[NTRANS] = {
- [uf] = uf, [ur] = ul, [ul] = ur, [ub] = ub,
- [df] = df, [dr] = dr, [dl] = dl, [db] = db,
- [rf] = lf, [rd] = bl, [rb] = rb, [ru] = fr,
- [lf] = rf, [ld] = br, [lb] = lb, [lu] = fl,
- [fu] = fu, [fr] = ru, [fd] = bu, [fl] = lu,
- [bu] = fd, [br] = ld, [bd] = bd, [bl] = rd,
-
- [uf_mirror] = uf_mirror, [ur_mirror] = ur_mirror,
- [ul_mirror] = ul_mirror, [ub_mirror] = ub_mirror,
- [df_mirror] = df_mirror, [dr_mirror] = dl_mirror,
- [dl_mirror] = dr_mirror, [db_mirror] = db_mirror,
- [rf_mirror] = rf_mirror, [rd_mirror] = br_mirror,
- [rb_mirror] = lb_mirror, [ru_mirror] = fl_mirror,
- [lf_mirror] = lf_mirror, [ld_mirror] = bl_mirror,
- [lb_mirror] = rb_mirror, [lu_mirror] = fr_mirror,
- [fu_mirror] = fu_mirror, [fr_mirror] = lu_mirror,
- [fd_mirror] = bu_mirror, [fl_mirror] = ru_mirror,
- [bu_mirror] = fd_mirror, [br_mirror] = rd_mirror,
- [bd_mirror] = bd_mirror, [bl_mirror] = ld_mirror
- };
-
- return inverse_trans_aux[t];
-}
-
-Alg *
-rotation_alg(Trans t)
-{
- int i;
-
- static Alg *rotation_alg_arr[NROTATIONS];
- static bool initialized = false;
-
- if (!initialized) {
- for (i = 0; i < NROTATIONS; i++)
- rotation_alg_arr[i] = new_alg(rotation_alg_string[i]);
-
- initialized = true;
- }
-
- return rotation_alg_arr[t % NROTATIONS];
-}
-
-void
-transform_alg(Trans t, Alg *alg)
-{
- int i;
-
- /*init_trans();*/
-
- for (i = 0; i < alg->len; i++)
- alg->move[i] = moves_ttable[t][alg->move[i]];
-}
diff --git a/old/2021-11-10-beforeremovingchecker/trans.h b/old/2021-11-10-beforeremovingchecker/trans.h
@@ -1,13 +0,0 @@
-#ifndef TRANS_H
-#define TRANS_H
-
-#include "moves.h"
-
-Cube apply_trans(Trans t, Cube cube);
-Trans inverse_trans(Trans t);
-Alg * rotation_alg(Trans i);
-void transform_alg(Trans i, Alg *alg);
-
-void init_trans();
-
-#endif
diff --git a/old/2021-11-10-beforeremovingchecker/utils.c b/old/2021-11-10-beforeremovingchecker/utils.c
@@ -1,274 +0,0 @@
-#include "utils.h"
-
-void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- memcpy(set, aux, n * sizeof(int));
- free(aux);
-}
-
-int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-int
-invert_digits(int a, int b, int n)
-{
- int i, ret, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- ret = digit_array_to_int(r, n, b);
- free(r);
- return ret;
-}
-
-bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
-
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-int
-powint(int a, int b)
-{
- if (b < 0)
- return 0;
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-int
-subset_to_index(int *a, int n, int k)
-{
- int i, ret = 0;
-
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
-
-void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
diff --git a/old/2021-11-10-beforeremovingchecker/utils.h b/old/2021-11-10-beforeremovingchecker/utils.h
@@ -1,41 +0,0 @@
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define POW2TO6 64ULL
-#define POW2TO11 2048ULL
-#define POW2TO12 4096ULL
-#define POW3TO7 2187ULL
-#define POW3TO8 6561ULL
-#define FACTORIAL4 24ULL
-#define FACTORIAL6 720ULL
-#define FACTORIAL7 5040ULL
-#define FACTORIAL8 40320ULL
-#define FACTORIAL12 479001600ULL
-#define BINOM12ON4 495ULL
-#define BINOM8ON4 70ULL
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
-void apply_permutation(int *perm, int *set, int n);
-int binomial(int n, int k);
-int digit_array_to_int(int *a, int n, int b);
-int factorial(int n);
-void index_to_perm(int p, int n, int *r);
-void index_to_subset(int s, int n, int k, int *r);
-void int_to_digit_array(int a, int b, int n, int *r);
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-int invert_digits(int a, int b, int n);
-bool is_perm(int *a, int n);
-bool is_subset(int *a, int n, int k);
-int perm_sign(int *a, int n);
-int perm_to_index(int *a, int n);
-int powint(int a, int b);
-int subset_to_index(int *a, int n, int k);
-void sum_arrays_mod(int *src, int *dst, int n, int m);
-void swap(int *a, int *b);
-
-#endif
diff --git a/old/backup-manysteps-pretrans/steps.c b/old/backup-manysteps-pretrans/steps.c
@@ -1,369 +0,0 @@
-#include "steps.h"
-
-/* Check functions ***********************************************************/
-
-static int check_nothing(Cube cube);
-static int check_eofb_HTM(Cube cube);
-static int check_coud_HTM(Cube cube);
-static int check_coud_URF(Cube cube);
-static int check_corners_HTM(Cube cube);
-static int check_corners_URF(Cube cube);
-static int check_edges_HTM(Cube cube);
-static int check_drud_HTM(Cube cube);
-static int check_optimal_HTM(Cube cube);
-
-
-/* Index functions ***********************************************************/
-
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_ep(Cube cube);
-static uint64_t index_drud(Cube cube);
-
-
-/* Steps *********************************************************************/
-
-Step
-eofb_HTM = {
- .check = check_eofb_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-Step
-eorl_HTM = {
- .check = check_eofb_HTM,
- .ready = check_nothing,
- .pre_trans = ur,
- .moveset = moveset_HTM
-};
-
-Step
-eoud_HTM = {
- .check = check_eofb_HTM,
- .ready = check_nothing,
- .pre_trans = bu,
- .moveset = moveset_HTM
-};
-
-Step
-coud_HTM = {
- .check = check_coud_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-Step
-corl_HTM = {
- .check = check_coud_HTM,
- .ready = check_nothing,
- .pre_trans = rf,
- .moveset = moveset_HTM
-};
-
-Step
-cofb_HTM = {
- .check = check_coud_HTM,
- .ready = check_nothing,
- .pre_trans = fd,
- .moveset = moveset_HTM
-};
-
-Step
-coud_URF = {
- .check = check_coud_URF,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_URF
-};
-
-Step
-corl_URF = {
- .check = check_coud_URF,
- .ready = check_nothing,
- .pre_trans = rf,
- .moveset = moveset_URF
-};
-
-Step
-cofb_URF = {
- .check = check_coud_URF,
- .ready = check_nothing,
- .pre_trans = fd,
- .moveset = moveset_URF
-};
-
-Step
-corners_HTM = {
- .check = check_corners_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-Step
-corners_URF = {
- .check = check_corners_URF,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_URF
-};
-
-Step
-edges_HTM = {
- .check = check_edges_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-Step
-drud_HTM = {
- .check = check_drud_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-Step
-optimal_HTM = {
- .check = check_optimal_HTM,
- .ready = check_nothing,
- .pre_trans = uf,
- .moveset = moveset_HTM
-};
-
-
-/* Pruning tables ************************************************************/
-
-PruneData
-pd_eofb_HTM = {
- .filename = "ptable_eofb_HTM",
- .size = POW2TO11,
- .index = index_eofb,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_coud_HTM = {
- .filename = "ptable_coud_HTM",
- .size = POW3TO7,
- .index = index_coud,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_corners_HTM = {
- .filename = "ptable_corners_HTM",
- .size = POW3TO7 * FACTORIAL8,
- .index = index_corners,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_ep_HTM = {
- .filename = "ptable_ep_HTM",
- .size = FACTORIAL12,
- .index = index_ep,
- .moveset = moveset_HTM
-};
-
-PruneData
-pd_drud_HTM = {
- .filename = "ptable_drud_HTM",
- .size = POW2TO11 * POW3TO7 * BINOM12ON4,
- .index = index_drud,
- .moveset = moveset_HTM
-};
-
-
-/* Check functions implementation ********************************************/
-
-static int
-check_nothing(Cube cube)
-{
- /* At least we check that it is admissible */
- return is_admissible(cube);
-}
-
-static int
-check_eofb_HTM(Cube cube)
-{
- if (!pd_eofb_HTM.generated)
- generate_ptable(&pd_eofb_HTM);
-
- return PTABLEVAL(pd_eofb_HTM.ptable, cube.eofb);
-}
-
-static int
-check_coud_HTM(Cube cube)
-{
- if (!pd_coud_HTM.generated)
- generate_ptable(&pd_coud_HTM);
-
- return PTABLEVAL(pd_coud_HTM.ptable, cube.coud);
-}
-
-static int
-check_coud_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the orientation of
- * the corner in DBL and use that as a reference */
-
- int ud = check_coud_HTM(cube);
- int rl = check_coud_HTM(apply_move(z, cube));
- int fb = check_coud_HTM(apply_move(x, cube));
-
- return MIN(ud, MIN(rl, fb));
-}
-
-static int
-check_corners_HTM(Cube cube)
-{
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
-
- return PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
-}
-
-static int
-check_corners_URF(Cube cube)
-{
- /* TODO: I can improve this by checking first the corner in DBL
- * and use that as a reference */
-
- int ret = 15;
- Trans i;
-
- for (i = 0; i < NROTATIONS; i++)
- ret = MIN(ret,check_corners_HTM(apply_alg(trans_alg(i),cube)));
-
- return ret;
-}
-
-static int
-check_edges_HTM(Cube cube)
-{
- int ret = 0;
-
- if (!pd_ep_HTM.generated)
- generate_ptable(&pd_ep_HTM);
-
- ret = MAX(ret, PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)));
- ret = MAX(ret, check_eofb_HTM(cube));
- ret = MAX(ret, check_eofb_HTM(apply_trans(ur, cube)));
- ret = MAX(ret, check_eofb_HTM(apply_trans(fd, cube)));
-
- return ret;
-}
-
-static int
-check_drud_HTM(Cube cube)
-{
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
-
- return PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
-}
-
-static int
-check_optimal_HTM(Cube cube)
-{
- int dr1, dr2, dr3, drmax, cor; /*ep;*/
-
- if (!pd_drud_HTM.generated)
- generate_ptable(&pd_drud_HTM);
- if (!pd_corners_HTM.generated)
- generate_ptable(&pd_corners_HTM);
- /*
- *if (!pd_ep_HTM.generated)
- * generate_ptable(&pd_ep_HTM);
- */
-
- dr1 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(cube));
- dr2 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(rf, cube)));
- dr3 = PTABLEVAL(pd_drud_HTM.ptable, index_drud(apply_trans(fd, cube)));
-
- drmax = MAX(dr1, MAX(dr2, dr3));
- if (dr1 == dr2 && dr2 == dr3 && dr1 != 0)
- drmax++;
-
- cor = PTABLEVAL(pd_corners_HTM.ptable, index_corners(cube));
- /* ep = PTABLEVAL(pd_ep_HTM.ptable, index_ep(cube)); */
-
- /*return MAX(drmax, MAX(ep, cor));*/
- if (drmax == 0 && cor == 0)
- return is_solved(cube, false) ? 0 : 1;
- return MAX(drmax, cor);
-}
-
-
-/* Index functions implementation ********************************************/
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_ep(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eposs;
- b = (cube.epose % FACTORIAL4) + epos_dependent_cube(cube)*FACTORIAL4;
- c = cube.eposm % FACTORIAL4;
-
- b *= FACTORIAL4 * BINOM12ON4;
- c *= FACTORIAL4 * BINOM12ON4 * FACTORIAL4 * BINOM8ON4;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-/* Movesets ******************************************************************/
-
-bool
-moveset_HTM(Move m)
-{
- return m >= U && m <= B3;
-}
-
-bool
-moveset_URF(Move m)
-{
- Move b = base_move(m);
-
- return b == U || b == R || b == F;
-}
-
diff --git a/old/backup-manysteps-pretrans/steps.h b/old/backup-manysteps-pretrans/steps.h
@@ -1,36 +0,0 @@
-#ifndef STEPS_H
-#define STEPS_H
-
-#include "cube.h"
-
-/* Steps *********************************************************************/
-
-extern Step eofb_HTM;
-extern Step eorl_HTM;
-extern Step eoud_HTM;
-extern Step coud_HTM;
-extern Step corl_HTM;
-extern Step cofb_HTM;
-extern Step coud_URF;
-extern Step corl_URF;
-extern Step cofb_URF;
-extern Step corners_HTM;
-extern Step corners_URF;
-extern Step edges_HTM;
-extern Step drud_HTM;
-extern Step optimal_HTM;
-
-/* Pruning tables ************************************************************/
-
-extern PruneData pd_eofb_HTM;
-extern PruneData pd_coud_HTM;
-extern PruneData pd_corners_HTM;
-extern PruneData pd_ep_HTM;
-extern PruneData pd_drud_HTM;
-
-/* Movesets ******************************************************************/
-
-bool moveset_HTM(Move m);
-bool moveset_URF(Move m);
-
-#endif
diff --git a/old/coord.c b/old/coord.c
@@ -1,1014 +0,0 @@
-#include "coord.h"
-
-static Cube admissible_eos_from_eofbepos(Cube cube);
-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_cornershtr(uint64_t ind);
-static Cube antindex_drud(uint64_t ind);
-static Cube antindex_coud_sym16(uint64_t ind);
-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_drud_eofb(uint64_t ind);
-static Cube antindex_drudfin_noE_sym16(uint64_t ind);
-static Cube antindex_htrfin(uint64_t ind);
-static Cube antindex_khuge(uint64_t ind);
-static int epos_dependent_pos(int pos1, int pos2);
-static void gensym(SymData *sd);
-static uint64_t index_eofb(Cube cube);
-static uint64_t index_eofbepos(Cube cube);
-static uint64_t index_epud(Cube cube);
-static uint64_t index_coud(Cube cube);
-static uint64_t index_corners(Cube cube);
-static uint64_t index_cp(Cube cube);
-static uint64_t index_cornershtr(Cube cube);
-static uint64_t index_drud(Cube cube);
-static uint64_t index_coud_sym16(Cube cube);
-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_drud_eofb(Cube cube);
-static uint64_t index_drudfin_noE_sym16(Cube cube);
-static uint64_t index_htrfin(Cube cube);
-static uint64_t index_khuge(Cube cube);
-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_symdata();
-static bool read_symdata_file(SymData *sd);
-static bool write_symdata_file(SymData *sd);
-
-/* All sorts of useful costants and tables **********************************/
-
-/* TODO: Can I move inside functions that use them?
- Maybe I need to pass them as argument to some
- secondary function */
-static int cphtr_left_cosets[FACTORIAL8];
-static int cphtr_right_cosets[FACTORIAL8];
-static int cphtr_right_rep[BINOM8ON4*6];
-
-
-/* Symmetry data for some coordinates ****************************************/
-
-static Trans
-trans_group_trivial[1] = { uf };
-
-static Trans
-trans_group_udfix[16] = {
- uf, ur, ub, ul,
- df, dr, db, dl,
- uf_mirror, ur_mirror, ub_mirror, ul_mirror,
- df_mirror, dr_mirror, db_mirror, dl_mirror,
-};
-
-SymData
-sd_coud_16 = {
- .filename = "sd_coud_16",
- .coord = &coord_coud,
- .sym_coord = &coord_coud_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_cp_16 = {
- .filename = "sd_cp_16",
- .coord = &coord_cp,
- .sym_coord = &coord_cp_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-SymData
-sd_eofbepos_16 = {
- .filename = "sd_eofbepos_16",
- .coord = &coord_eofbepos,
- .sym_coord = &coord_eofbepos_sym16,
- .ntrans = 16,
- .trans = trans_group_udfix
-};
-
-static int n_all_symdata = 3;
-static SymData * all_sd[3] = {
- &sd_coud_16,
- &sd_cp_16,
- &sd_eofbepos_16,
-};
-
-/* Coordinates and their implementation **************************************/
-
-Coordinate
-coord_eofb = {
- .index = index_eofb,
- .cube = antindex_eofb,
- .check = check_eofb,
- .max = POW2TO11,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_eofbepos = {
- .index = index_eofbepos,
- .cube = antindex_eofbepos,
- .check = check_eofbepos,
- .max = POW2TO11 * BINOM12ON4,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_coud = {
- .index = index_coud,
- .cube = antindex_coud,
- .check = check_coud,
- .max = POW3TO7,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_corners = {
- .index = index_corners,
- .cube = antindex_corners,
- .check = check_corners,
- .max = POW3TO7 * FACTORIAL8,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_cp = {
- .index = index_cp,
- .cube = antindex_cp,
- .check = check_cp,
- .max = FACTORIAL8,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_cornershtr = {
- .index = index_cornershtr,
- .cube = antindex_cornershtr,
- .check = check_cornershtr,
- .max = POW3TO7 * BINOM8ON4 * 6,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_drud = {
- .index = index_drud,
- .cube = antindex_drud,
- .check = check_drud,
- .max = POW2TO11 * POW3TO7 * BINOM12ON4,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_htrfin = {
- .index = index_htrfin,
- .cube = antindex_htrfin,
- .check = check_htrfin,
- .max = 24 * 24 * 24 *24 * 24,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_drud_eofb = {
- .index = index_drud_eofb,
- .cube = antindex_drud_eofb,
- .check = check_drud,
- .max = POW3TO7 * BINOM12ON4,
- .ntrans = 1,
- .trans = trans_group_trivial,
-};
-
-Coordinate
-coord_eofbepos_sym16 = {
- .index = index_eofbepos_sym16,
- .cube = antindex_eofbepos_sym16,
- .check = check_eofbepos,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_coud_sym16 = {
- .index = index_coud_sym16,
- .cube = antindex_coud_sym16,
- .check = check_coud,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_cp_sym16 = {
- .index = index_cp_sym16,
- .cube = antindex_cp_sym16,
- .check = check_cp,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_drud_sym16 = {
- .index = index_drud_sym16,
- .cube = antindex_drud_sym16,
- .check = check_drud,
- .max = POW3TO7 * 64430,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_drudfin_noE_sym16 = {
- .index = index_drudfin_noE_sym16,
- .cube = antindex_drudfin_noE_sym16,
- .check = check_drudfin_noE,
- .max = FACTORIAL8 * 2768,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-Coordinate
-coord_khuge = {
- .index = index_khuge,
- .cube = antindex_khuge,
- .check = check_khuge,
- .max = POW3TO7 * FACTORIAL4 * 64430,
- .ntrans = 16,
- .trans = trans_group_udfix,
-};
-
-/* Functions *****************************************************************/
-
-static Cube
-admissible_eos_from_eofbepos(Cube cube)
-{
- Edge e;
- Cube ret;
- CubeArray *arr = new_cubearray(cube, pf_all);
-
- memcpy(arr->eorl, arr->eofb, 12 * sizeof(int));
- memcpy(arr->eoud, arr->eofb, 12 * sizeof(int));
-
- for (e = 0; e < 12; e++) {
- if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) ||
- (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0))
- arr->eorl[e] = 1 - arr->eorl[e];
- if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) ||
- (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2))
- arr->eoud[e] = 1 - arr->eoud[e];
- }
-
- ret = arrays_to_cube(arr, pf_all);
- free_cubearray(arr, pf_all);
-
- return ret;
-}
-
-
-static Cube
-antindex_eofb(uint64_t ind)
-{
- return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
-}
-
-static Cube
-antindex_eofbepos(uint64_t ind)
-{
- static bool initialized = false;
- static Cube admissible_ee_aux[POW2TO11*BINOM12ON4];
- static Cube c1;
- static int k;
- static uint64_t ui;
-
- if (!initialized) {
- for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) {
- k = (ui / POW2TO11) * 24;
- c1 = admissible_ep((Cube){ .epose = k }, pf_e);
- c1.eofb = ui % POW2TO11;
- c1 = admissible_eos_from_eofbepos(c1);
- admissible_ee_aux[ui] = c1;
- }
-
- initialized = true;
- }
-
- return admissible_ee_aux[ind];
-}
-
-static Cube
-antindex_epud(uint64_t ind)
-{
- 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];
-}
-
-static Cube
-antindex_coud(uint64_t ind)
-{
- return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
-}
-
-static Cube
-antindex_corners(uint64_t ind)
-{
- Cube c = {0};
-
- c.coud = ind / FACTORIAL8;
- c.cp = ind % FACTORIAL8;
-
- return c;
-}
-
-static Cube
-antindex_cp(uint64_t ind)
-{
- Cube c = {0};
-
- c.cp = ind;
-
- return c;
-}
-
-static Cube
-antindex_cornershtr(uint64_t ind)
-{
- Cube c = anti_cphtr(ind % (BINOM8ON4 * 6));
-
- c.coud = ind / (BINOM8ON4 * 6);
-
- return c;
-}
-
-/* TODO: admissible eos and cos */
-/* DONE: temporary fix, make it better */
-/* Or maybe it's ok like this? */
-static Cube
-antindex_drud(uint64_t ind)
-{
- uint64_t epos, eofb;
- Cube c;
-
- eofb = ind % POW2TO11;
- epos = ind / (POW2TO11 * POW3TO7);
- c = antindex_eofbepos(eofb + POW2TO11 * epos);
-
- c.coud = (ind / POW2TO11) % POW3TO7;
- c.corl = c.coud;
- c.cofb = c.coud;
-
- return c;
-}
-
-static Cube
-antindex_drud_eofb(uint64_t ind)
-{
- return antindex_drud(ind * POW2TO11);
-}
-
-static Cube
-antindex_coud_sym16(uint64_t ind)
-{
- return sd_coud_16.rep[ind];
-}
-
-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 = sd_eofbepos_16.rep[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 = antindex_epud(ind % FACTORIAL8);
- c2 = sd_cp_16.rep[ind/FACTORIAL8];
- c1.cp = c2.cp;
-
- return c1;
-}
-
-static Cube
-antindex_htrfin(uint64_t ind)
-{
- Cube ret = {0};
- uint64_t cp1, cp2;
-
- static bool initialized = false;
- static int i, j, k, c[8], c1[4], c2[4], cp[24][24];
- static int c1solved[4] = {UFR, UBL, DFL, DBR};
- static int c2solved[4] = {UFL, UBR, DFR, DBL};
-
- if (!initialized) {
- for (i = 0; i < 24; i++) {
- for (j = 0; j < 24; j++) {
- index_to_perm(i, 4, c1);
- index_to_perm(j, 4, c2);
- for (k = 0; k < 8; k++)
- if (k == UFR || k == UBL ||
- k == DFL || k == DBR)
- c[k] = c1[c1solved[k/2]];
- else
- c[k] = c2[c2solved[k/2]];
-
- cp[i][j] = perm_to_index(c, 8);
- }
- }
-
- initialized = true;
- }
-
- cp2 = ind % 24;
- ind /= 24;
- cp1 = ind % 24;
- ret.cp = cp[cp1][cp2];
-
- ind /= 24;
- ret.eposm = ind % 24;
- ind /= 24;
- ret.eposs = ind % 24;
- ret.epose = ind / 24;
-
- return ret;
-}
-
-static Cube
-antindex_khuge(uint64_t ind)
-{
- Cube c;
-
- c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)];
- c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24);
- c.coud = ind % POW3TO7;
-
- return c;
-}
-
-bool
-check_centers(Cube cube)
-{
- return cube.cpos == 0;
-}
-
-bool
-check_corners(Cube cube)
-{
- return cube.cp == 0 && cube.coud == 0;
-}
-
-bool
-check_cp(Cube cube)
-{
- return cube.cp == 0;
-}
-
-bool
-check_cornershtr(Cube cube)
-{
- return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/
-}
-
-bool
-check_coud(Cube cube)
-{
- return cube.coud == 0;
-}
-
-bool
-check_drud(Cube cube)
-{
- return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0;
-}
-
-bool
-check_htr(Cube cube)
-{
- return check_cornershtr(cube) &&
- cube.eofb == 0 && cube.eorl == 0 && cube.eoud == 0;
-}
-
-bool
-check_htrfin(Cube cube)
-{
- return cube.cp == 0 &&
- cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_drudfin_noE(Cube cube)
-{
- return cube.eposs == 0 && cube.eposm == 0 && cube.cp == 0;
-}
-
-bool
-check_eofb(Cube cube)
-{
- return cube.eofb == 0;
-}
-
-bool
-check_eofbepos(Cube cube)
-{
- return cube.eofb == 0 && cube.epose / 24 == 0;
-}
-
-bool
-check_epose(Cube cube)
-{
- return cube.epose == 0;
-}
-
-bool
-check_ep(Cube cube)
-{
- return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0;
-}
-
-bool
-check_khuge(Cube cube)
-{
- return check_drud(cube) && cube.epose % 24 == 0;
-}
-
-bool
-check_nothing(Cube cube)
-{
- return is_admissible(cube); /*TODO: maybe change?*/
-}
-
-static int
-epos_dependent_pos(int poss, int pose)
-{
- static int epe_solved[4] = {FR, FL, BL, BR};
- static int eps_solved[4] = {UL, UR, DL, DR};
- int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- int i, j;
-
- epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved);
- epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved);
-
- for (i = 0, j = 0; i < 12; i++)
- if (edge_slice(ep[i]) != 0)
- ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0;
-
- swap(&ep8[1], &ep8[4]);
- swap(&ep8[3], &ep8[6]);
-
- return subset_to_index(ep8, 8, 4);
-}
-
-static void
-gensym(SymData *sd)
-{
- uint64_t i, in, nreps = 0;
- 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->transtorep = malloc(sd->coord->max * sizeof(Trans));
-
- if (read_symdata_file(sd)) {
- sd->generated = true;
- return;
- }
-
- fprintf(stderr, "Cannot load %s, generating it\n", sd->filename);
-
- for (i = 0; i < sd->coord->max; i++)
- sd->class[i] = sd->coord->max + 1;
-
- 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;
- 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]);
- }
- }
- nreps++;
- }
- }
-
- sd->sym_coord->max = nreps;
- sd->rep = realloc(sd->rep, nreps * sizeof(Cube));
- sd->generated = true;
-
- fprintf(stderr, "Found %lu classes\n", nreps);
-
- if (!write_symdata_file(sd))
- fprintf(stderr, "Error writing SymData file\n");
-
- return;
-}
-
-static uint64_t
-index_eofb(Cube cube)
-{
- return cube.eofb;
-}
-
-static uint64_t
-index_eofbepos(Cube cube)
-{
- return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
-}
-
-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);
-
- return ret;
-}
-
-static uint64_t
-index_coud(Cube cube)
-{
- return cube.coud;
-}
-
-static uint64_t
-index_corners(Cube cube)
-{
- return cube.coud * FACTORIAL8 + cube.cp;
-}
-
-static uint64_t
-index_cp(Cube cube)
-{
- return cube.cp;
-}
-
-static uint64_t
-index_cornershtr(Cube cube)
-{
- return cube.coud * BINOM8ON4 * 6 + cphtr(cube);
-}
-
-static uint64_t
-index_drud(Cube cube)
-{
- uint64_t a, b, c;
-
- a = cube.eofb;
- b = cube.coud;
- c = cube.epose / FACTORIAL4;
-
- b *= POW2TO11;
- c *= POW2TO11 * POW3TO7;
-
- return a + b + c;
-}
-
-static uint64_t
-index_drud_eofb(Cube cube)
-{
- return index_drud(cube) / POW2TO11;
-}
-
-static uint64_t
-index_coud_sym16(Cube cube)
-{
- return sd_coud_16.class[index_coud(cube)];
-}
-
-static uint64_t
-index_cp_sym16(Cube cube)
-{
- return sd_cp_16.class[index_cp(cube)];
-}
-
-static uint64_t
-index_drud_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
-
- return index_eofbepos_sym16(c) * POW3TO7 + c.coud;
-}
-
-static uint64_t
-index_drudfin_noE_sym16(Cube cube)
-{
- Trans t;
- Cube c;
-
- t = sd_cp_16.transtorep[index_cp(cube)];
- c = apply_trans(t, cube);
-
- return index_cp_sym16(c) * FACTORIAL8 + index_epud(c);
-}
-
-static uint64_t
-index_htrfin(Cube cube)
-{
- uint64_t epe, eps, epm, cp, ep;
-
- static bool initialized = false;
- static uint64_t cp1[FACTORIAL8], cp2[FACTORIAL8];
- static unsigned int i;
- static int j, n1, n2, c[8], c1[4], c2[4];
-
- if (!initialized) {
- for (i = 0; i < FACTORIAL8; i++) {
- index_to_perm(i, 8, c);
- n1 = 0;
- n2 = 0;
- for (j = 0; j < 8; j++)
- if (c[j] == UFR || c[j] == UBL ||
- c[j] == DFL || c[j] == DBR)
- c1[n1++] = c[j] / 2;
- else
- c2[n2++] = c[j] / 2;
-
- cp1[i] = perm_to_index(c1, 4);
- cp2[i] = perm_to_index(c2, 4);
- }
-
- initialized = true;
- }
-
- epe = cube.epose % 24;
- eps = cube.eposs % 24;
- epm = cube.eposm % 24;
-
- cp = cp1[cube.cp] * 24 + cp2[cube.cp];
- ep = (epe * 24 + eps) *24 + epm;
-
- return ep * 24 * 24 + cp;
-}
-
-static uint64_t
-index_eofbepos_sym16(Cube cube)
-{
- return sd_eofbepos_16.class[index_eofbepos(cube)];
-}
-
-static uint64_t
-index_khuge(Cube cube)
-{
- Trans t;
- Cube c;
- uint64_t a;
-
- t = sd_eofbepos_16.transtorep[index_eofbepos(cube)];
- c = apply_trans(t, cube);
- a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24);
-
- return a * POW3TO7 + c.coud;
-}
-
-static bool
-read_symdata_file(SymData *sd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "rb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-static bool
-write_symdata_file(SymData *sd)
-{
- init_env();
-
- FILE *f;
- char fname[strlen(tabledir)+100];
- uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max;
- bool r = true;
-
- strcpy(fname, tabledir);
- strcat(fname, "/");
- strcat(fname, sd->filename);
-
- if ((f = fopen(fname, "wb")) == NULL)
- 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->class, sizeof(uint64_t), n, f) == n;
- r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
-
- fclose(f);
- return r;
-}
-
-/* Init functions implementation *********************************************/
-
-/*
- * There is certainly a bette way to do this, but for now I just use
- * a "graph coloring" algorithm to compute the left cosets, and I compose
- * with every possible cp to get the right cosets (it is possible that I am
- * mixing up left and right).
- *
- * For doing it better "Mathematically", we need 3 things:
- * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
- * This is easy and it is done in the commented function cphtr_cp().
- * - Check that there is no ep/cp parity
- * - Check that we are not in the "3c" case; this is the part I don't
- * know how to do.
- */
-static void
-init_cphtr_cosets()
-{
- unsigned int i;
- int c = 0, d = 0;
-
- for (i = 0; i < FACTORIAL8; i++) {
- cphtr_left_cosets[i] = -1;
- cphtr_right_cosets[i] = -1;
- }
-
- /* First we compute left cosets with a bfs */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_left_cosets[i] == -1)
- init_cphtr_left_cosets_bfs(i, c++);
-
- /* Then we compute right cosets using compose() */
- for (i = 0; i < FACTORIAL8; i++)
- if (cphtr_right_cosets[i] == -1)
- init_cphtr_right_cosets_color(i, d++);
-}
-
-static void
-init_cphtr_left_cosets_bfs(int i, int c)
-{
- int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
- Move moves[6] = {U2, D2, R2, L2, F2, B2};
-
- n = 1;
- next[0] = i;
- cphtr_left_cosets[i] = c;
-
- while (n != 0) {
- for (j = 0, n2 = 0; j < n; j++) {
- for (k = 0; k < 6; k++) {
- /*jj = cp_mtable[moves[k]][next[j]];*/
- /* TODO fix formatting */
- jj = apply_move(moves[k], (Cube){.cp=next[j]}).cp;
- if (cphtr_left_cosets[jj] == -1) {
- cphtr_left_cosets[jj] = c;
- next2[n2++] = jj;
- }
- }
- }
-
- for (j = 0; j < n2; j++)
- next[j] = next2[j];
- n = n2;
- }
-}
-
-static void
-init_cphtr_right_cosets_color(int i, int d)
-{
- int cp;
- unsigned int j;
-
- cphtr_right_rep[d] = i;
- for (j = 0; j < FACTORIAL8; j++) {
- if (cphtr_left_cosets[j] == 0) {
- /* TODO: use antindexer, it's nicer */
- cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
- cphtr_right_cosets[cp] = d;
- }
- }
-}
-
-static void
-init_symdata()
-{
- int i;
-
- for (i = 0; i < n_all_symdata; i++)
- gensym(all_sd[i]);
-}
-
-/*TODO maybe move the next two */
-uint64_t
-cphtr(Cube cube)
-{
- return cphtr_right_cosets[cube.cp];
-}
-
-Cube
-anti_cphtr(uint64_t ind)
-{
- return (Cube) { .cp = cphtr_right_rep[ind] };
-}
-
-uint64_t
-epos_dependent(Cube c)
-{
- static int initialized = false;
- static int aux[BINOM12ON4][BINOM12ON4];
- static uint64_t ui, uj;
-
- if (!initialized) {
- for (ui = 0; ui < BINOM12ON4; ui++)
- for (uj = 0; uj < BINOM12ON4; uj++)
- aux[ui][uj] = epos_dependent_pos(ui, uj);
-
- initialized = true;
- }
-
- return aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4];
-}
-
-void
-init_coord()
-{
- static bool initialized = false;
- if (initialized)
- return;
- initialized = true;
-
- init_cphtr_cosets();
- init_symdata();
-}
-
diff --git a/old/coord.h b/old/coord.h
@@ -1,45 +0,0 @@
-#ifndef COORD_H
-#define COORD_H
-
-#include "trans.h"
-
-extern Coordinate coord_eofb;
-extern Coordinate coord_eofbepos;
-extern Coordinate coord_coud;
-extern Coordinate coord_cp;
-extern Coordinate coord_corners;
-extern Coordinate coord_cornershtr;
-extern Coordinate coord_drud;
-extern Coordinate coord_coud_sym16;
-extern Coordinate coord_drud_eofb;
-extern Coordinate coord_cp_sym16;
-extern Coordinate coord_eofbepos_sym16;
-extern Coordinate coord_drud_sym16;
-extern Coordinate coord_drudfin_noE_sym16;
-extern Coordinate coord_htrfin;
-extern Coordinate coord_khuge;
-
-uint64_t cphtr(Cube cube); /* TODO: rename (something with cosets) */
-Cube anti_cphtr(uint64_t ind); /*TODO also this */
-uint64_t epos_dependent(Cube cube); /* TODO: rename and turn into an indexer */
-
-bool check_centers(Cube cube);
-bool check_corners(Cube cube);
-bool check_cp(Cube cube);
-bool check_cornershtr(Cube cube);
-bool check_coud(Cube cube);
-bool check_drud(Cube cube);
-bool check_htr(Cube cube);
-bool check_htrfin(Cube cube);
-bool check_drudfin_noE(Cube cube);
-bool check_eofb(Cube cube);
-bool check_eofbepos(Cube cube);
-bool check_epose(Cube cube);
-bool check_ep(Cube cube);
-bool check_khuge(Cube cube);
-bool check_nothing(Cube cube);
-
-void init_coord();
-
-#endif
-
diff --git a/old/utils.c b/old/utils.c
@@ -1,294 +0,0 @@
-#include "utils.h"
-
-/* Generic utility functions *************************************************/
-
-void
-apply_permutation(int *perm, int *set, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- if (!is_perm(perm, n))
- return;
-
- for (i = 0; i < n; i++)
- aux[i] = set[perm[i]];
-
- intarrcopy(aux, set, n);
- free(aux);
-}
-
-void
-intarrcopy(int *src, int *dst, int n)
-{
- int i;
- for (i = 0; i < n; i++)
- dst[i] = src[i];
-}
-
-bool
-is_perm(int *a, int n)
-{
- int *aux = malloc(n * sizeof(int));
- int i;
-
- for (i = 0; i < n; i++)
- if (a[i] < 0 || a[i] >= n)
- return false;
- else
- aux[a[i]] = 1;
-
- for (i = 0; i < n; i++)
- if (!aux[i])
- return false;
-
- free(aux);
-
- return true;
-}
-
-bool
-is_subset(int *a, int n, int k)
-{
- int i, sum = 0;
-
- for (i = 0; i < n; i++)
- sum += a[i] ? 1 : 0;
-
- return sum == k;
-}
-
-int
-sum(int *a, int n)
-{
- int i, ret = 0;
-
- for (i = 0; i < n; i++)
- ret += a[i];
-
- return ret;
-}
-
-void
-sum_arrays_mod(int *src, int *dst, int n, int m)
-{
- int i;
-
- for (i = 0; i < n; i++)
- dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
-}
-
-void
-swap(int *a, int *b)
-{
- int aux;
-
- aux = *a;
- *a = *b;
- *b = aux;
-}
-
-/* Standard mathematical functions *******************************************/
-
-int
-binomial(int n, int k)
-{
- if (n < 0 || k < 0 || k > n)
- return 0;
-
- return factorial(n) / (factorial(k) * factorial(n-k));
-}
-
-int
-factorial(int n)
-{
- int i, ret = 1;
-
- if (n < 0)
- return 0;
-
- for (i = 1; i <= n; i++)
- ret *= i;
-
- return ret;
-}
-
-int
-perm_sign(int *a, int n)
-{
- int i, j, ret = 0;
- if (!is_perm(a,n))
- return -1;
-
- for (i = 0; i < n; i++)
- for (j = i+1; j < n; j++)
- ret += (a[i] > a[j]) ? 1 : 0;
-
- return ret % 2;
-}
-
-int
-powint(int a, int b)
-{
- if (b < 0)
- return 0; /* Truncate */
- if (b == 0)
- return 1;
-
- if (b % 2)
- return a * powint(a, b-1);
- else
- return powint(a*a, b/2);
-}
-
-/* Conversions to and from int (base b digits, permutations...) **************/
-
-int
-digit_array_to_int(int *a, int n, int b)
-{
- int i, ret = 0, p = 1;
-
- for (i = 0; i < n; i++, p *= b)
- ret += a[i] * p;
-
- return ret;
-}
-
-void
-int_to_digit_array(int a, int b, int n, int *r)
-{
- int i;
-
- if (b <= 1)
- for (i = 0; i < n; i++)
- r[i] = 0;
- else
- for (i = 0; i < n; i++, a /= b)
- r[i] = a % b;
-}
-
-void
-int_to_sum_zero_array(int x, int b, int n, int *a)
-{
- int i, s = 0;
-
- if (b <= 1) {
- for (i = 0; i < n; i++)
- a[i] = 0;
- } else {
- int_to_digit_array(x, b, n-1, a);
- for (i = 0; i < n - 1; i++)
- s = (s + a[i]) % b;
- a[n-1] = (b - s) % b;
- }
-}
-
-int
-invert_digits(int a, int b, int n)
-{
- int i, *r = malloc(n * sizeof(int));
-
- int_to_digit_array(a, b, n, r);
- for (i = 0; i < n; i++)
- r[i] = (b-r[i]) % b;
-
- return digit_array_to_int(r, n, b);
-}
-
-void
-index_to_perm(int p, int n, int *r)
-{
- int *a = malloc(n * sizeof(int));
- int i, j, c;
-
- for (i = 0; i < n; i++)
- a[i] = 0;
-
- if (p < 0 || p >= factorial(n))
- for (i = 0; i < n; i++)
- r[i] = -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- j = 0;
- while (c <= p / factorial(n-i-1))
- c += a[j++] ? 0 : 1;
- r[i] = j-1;
- a[j-1] = 1;
- p %= factorial(n-i-1);
- }
-
- free(a);
-}
-
-int
-perm_to_index(int *a, int n)
-{
- int i, j, c, ret = 0;
-
- if (!is_perm(a, n))
- return -1;
-
- for (i = 0; i < n; i++) {
- c = 0;
- for (j = i+1; j < n; j++)
- c += (a[i] > a[j]) ? 1 : 0;
- ret += factorial(n-i-1) * c;
- }
-
- return ret;
-}
-
-void
-index_to_subset(int s, int n, int k, int *r)
-{
- int i, j, v;
-
- if (s < 0 || s >= binomial(n, k)) {
- for (i = 0; i < n; i++)
- r[i] = -1;
- return;
- }
-
- for (i = 0; i < n; i++) {
- if (k == n-i) {
- for (j = i; j < n; j++)
- r[j] = 1;
- return;
- }
-
- if (k == 0) {
- for (j = i; j < n; j++)
- r[j] = 0;
- return;
- }
-
- v = binomial(n-i-1, k);
- if (s >= v) {
- r[i] = 1;
- k--;
- s -= v;
- } else {
- r[i] = 0;
- }
- }
-}
-
-int subset_to_index(int *a, int n, int k) {
- int i, ret = 0;
-
- /* TODO: better checks */
- if (!is_subset(a, n, k))
- return binomial(n, k);
-
- for (i = 0; i < n; i++) {
- if (k == n-i)
- return ret;
- if (a[i]) {
- ret += binomial(n-i-1, k);
- k--;
- }
- }
-
- return ret;
-}
diff --git a/old/utils.h b/old/utils.h
@@ -1,59 +0,0 @@
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdbool.h>
-#include <stdlib.h>
-
-/* Constants and macros *****************************************************/
-
-#define pow2to11 2048
-#define pow2to12 4096
-#define pow3to7 2187
-#define pow3to8 6561
-#define pow12to4 20736
-#define factorial4 24
-#define factorial6 720
-#define factorial8 40320
-#define factorial12 479001600
-#define binom12on4 495
-#define binom8on4 70
-
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/* Generic utility functions *************************************************/
-
-void apply_permutation(int *perm, int *set, int n);
-void intarrcopy(int *src, int *dst, int n);
-bool is_perm(int *a, int n);
-bool is_subset(int *a, int n, int k);
-int sum(int *a, int n);
-void sum_arrays_mod(int *src, int *dst, int n, int m);
-void swap(int *a, int *b);
-
-/* Standard mathematical functions *******************************************/
-
-int binomial(int n, int k);
-int factorial(int n);
-int perm_sign(int a[], int n);
-int powint(int a, int b);
-
-/* Conversions to and from int (base b digits, permutations...) **************/
-
-int digit_array_to_int(int *a, int n, int b);
-void int_to_digit_array(int a, int b, int n, int *r);
-void int_to_sum_zero_array(int x, int b, int n, int *a);
-int invert_digits(int a, int b, int n);
-
-void index_to_perm(int p, int n, int *r);
-int perm_to_index(int *a, int n);
-
-void index_to_subset(int s, int n, int k, int *r);
-int subset_to_index(int *a, int n, int k);
-
-/* Am I not using these two?
-void index_to_ordered_subset(int s, int n, int k, int *r);
-int ordered_subset_to_index(int *a, int n, int k);
-*/
-
-#endif