diff options
| author | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-11-11 21:37:34 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-11-11 21:37:34 +0100 |
| commit | 3568412f8f230774d0d11d7ed1c897424f95d3ef (patch) | |
| tree | 77223792d8c925a9b1fc32b3f4341e943b5f8209 /old/coord.c | |
| parent | 67e1b5e6e6a2c917a2fe58a37a1382c982b1e5c5 (diff) | |
| download | nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.tar.gz nissy-3568412f8f230774d0d11d7ed1c897424f95d3ef.zip | |
Rewritten from scratch. Welocme nissy 2.0!
Diffstat (limited to 'old/coord.c')
| -rw-r--r-- | old/coord.c | 1014 |
1 files changed, 1014 insertions, 0 deletions
diff --git a/old/coord.c b/old/coord.c new file mode 100644 index 0000000..cd2da69 --- /dev/null +++ b/old/coord.c | |||
| @@ -0,0 +1,1014 @@ | |||
| 1 | #include "coord.h" | ||
| 2 | |||
| 3 | static Cube admissible_eos_from_eofbepos(Cube cube); | ||
| 4 | static Cube antindex_eofb(uint64_t ind); | ||
| 5 | static Cube antindex_eofbepos(uint64_t ind); | ||
| 6 | static Cube antindex_epud(uint64_t ind); | ||
| 7 | static Cube antindex_coud(uint64_t ind); | ||
| 8 | static Cube antindex_corners(uint64_t ind); | ||
| 9 | static Cube antindex_cp(uint64_t ind); | ||
| 10 | static Cube antindex_cornershtr(uint64_t ind); | ||
| 11 | static Cube antindex_drud(uint64_t ind); | ||
| 12 | static Cube antindex_coud_sym16(uint64_t ind); | ||
| 13 | static Cube antindex_cp_sym16(uint64_t ind); | ||
| 14 | static Cube antindex_eofbepos_sym16(uint64_t ind); | ||
| 15 | static Cube antindex_drud_sym16(uint64_t ind); | ||
| 16 | static Cube antindex_drud_eofb(uint64_t ind); | ||
| 17 | static Cube antindex_drudfin_noE_sym16(uint64_t ind); | ||
| 18 | static Cube antindex_htrfin(uint64_t ind); | ||
| 19 | static Cube antindex_khuge(uint64_t ind); | ||
| 20 | static int epos_dependent_pos(int pos1, int pos2); | ||
| 21 | static void gensym(SymData *sd); | ||
| 22 | static uint64_t index_eofb(Cube cube); | ||
| 23 | static uint64_t index_eofbepos(Cube cube); | ||
| 24 | static uint64_t index_epud(Cube cube); | ||
| 25 | static uint64_t index_coud(Cube cube); | ||
| 26 | static uint64_t index_corners(Cube cube); | ||
| 27 | static uint64_t index_cp(Cube cube); | ||
| 28 | static uint64_t index_cornershtr(Cube cube); | ||
| 29 | static uint64_t index_drud(Cube cube); | ||
| 30 | static uint64_t index_coud_sym16(Cube cube); | ||
| 31 | static uint64_t index_cp_sym16(Cube cube); | ||
| 32 | static uint64_t index_eofbepos_sym16(Cube cube); | ||
| 33 | static uint64_t index_drud_sym16(Cube cube); | ||
| 34 | static uint64_t index_drud_eofb(Cube cube); | ||
| 35 | static uint64_t index_drudfin_noE_sym16(Cube cube); | ||
| 36 | static uint64_t index_htrfin(Cube cube); | ||
| 37 | static uint64_t index_khuge(Cube cube); | ||
| 38 | static void init_cphtr_cosets(); | ||
| 39 | static void init_cphtr_left_cosets_bfs(int i, int c); | ||
| 40 | static void init_cphtr_right_cosets_color(int i, int c); | ||
| 41 | static void init_symdata(); | ||
| 42 | static bool read_symdata_file(SymData *sd); | ||
| 43 | static bool write_symdata_file(SymData *sd); | ||
| 44 | |||
| 45 | /* All sorts of useful costants and tables **********************************/ | ||
| 46 | |||
| 47 | /* TODO: Can I move inside functions that use them? | ||
| 48 | Maybe I need to pass them as argument to some | ||
| 49 | secondary function */ | ||
| 50 | static int cphtr_left_cosets[FACTORIAL8]; | ||
| 51 | static int cphtr_right_cosets[FACTORIAL8]; | ||
| 52 | static int cphtr_right_rep[BINOM8ON4*6]; | ||
| 53 | |||
| 54 | |||
| 55 | /* Symmetry data for some coordinates ****************************************/ | ||
| 56 | |||
| 57 | static Trans | ||
| 58 | trans_group_trivial[1] = { uf }; | ||
| 59 | |||
| 60 | static Trans | ||
| 61 | trans_group_udfix[16] = { | ||
| 62 | uf, ur, ub, ul, | ||
| 63 | df, dr, db, dl, | ||
| 64 | uf_mirror, ur_mirror, ub_mirror, ul_mirror, | ||
| 65 | df_mirror, dr_mirror, db_mirror, dl_mirror, | ||
| 66 | }; | ||
| 67 | |||
| 68 | SymData | ||
| 69 | sd_coud_16 = { | ||
| 70 | .filename = "sd_coud_16", | ||
| 71 | .coord = &coord_coud, | ||
| 72 | .sym_coord = &coord_coud_sym16, | ||
| 73 | .ntrans = 16, | ||
| 74 | .trans = trans_group_udfix | ||
| 75 | }; | ||
| 76 | |||
| 77 | SymData | ||
| 78 | sd_cp_16 = { | ||
| 79 | .filename = "sd_cp_16", | ||
| 80 | .coord = &coord_cp, | ||
| 81 | .sym_coord = &coord_cp_sym16, | ||
| 82 | .ntrans = 16, | ||
| 83 | .trans = trans_group_udfix | ||
| 84 | }; | ||
| 85 | |||
| 86 | SymData | ||
| 87 | sd_eofbepos_16 = { | ||
| 88 | .filename = "sd_eofbepos_16", | ||
| 89 | .coord = &coord_eofbepos, | ||
| 90 | .sym_coord = &coord_eofbepos_sym16, | ||
| 91 | .ntrans = 16, | ||
| 92 | .trans = trans_group_udfix | ||
| 93 | }; | ||
| 94 | |||
| 95 | static int n_all_symdata = 3; | ||
| 96 | static SymData * all_sd[3] = { | ||
| 97 | &sd_coud_16, | ||
| 98 | &sd_cp_16, | ||
| 99 | &sd_eofbepos_16, | ||
| 100 | }; | ||
| 101 | |||
| 102 | /* Coordinates and their implementation **************************************/ | ||
| 103 | |||
| 104 | Coordinate | ||
| 105 | coord_eofb = { | ||
| 106 | .index = index_eofb, | ||
| 107 | .cube = antindex_eofb, | ||
| 108 | .check = check_eofb, | ||
| 109 | .max = POW2TO11, | ||
| 110 | .ntrans = 1, | ||
| 111 | .trans = trans_group_trivial, | ||
| 112 | }; | ||
| 113 | |||
| 114 | Coordinate | ||
| 115 | coord_eofbepos = { | ||
| 116 | .index = index_eofbepos, | ||
| 117 | .cube = antindex_eofbepos, | ||
| 118 | .check = check_eofbepos, | ||
| 119 | .max = POW2TO11 * BINOM12ON4, | ||
| 120 | .ntrans = 1, | ||
| 121 | .trans = trans_group_trivial, | ||
| 122 | }; | ||
| 123 | |||
| 124 | Coordinate | ||
| 125 | coord_coud = { | ||
| 126 | .index = index_coud, | ||
| 127 | .cube = antindex_coud, | ||
| 128 | .check = check_coud, | ||
| 129 | .max = POW3TO7, | ||
| 130 | .ntrans = 1, | ||
| 131 | .trans = trans_group_trivial, | ||
| 132 | }; | ||
| 133 | |||
| 134 | Coordinate | ||
| 135 | coord_corners = { | ||
| 136 | .index = index_corners, | ||
| 137 | .cube = antindex_corners, | ||
| 138 | .check = check_corners, | ||
| 139 | .max = POW3TO7 * FACTORIAL8, | ||
| 140 | .ntrans = 1, | ||
| 141 | .trans = trans_group_trivial, | ||
| 142 | }; | ||
| 143 | |||
| 144 | Coordinate | ||
| 145 | coord_cp = { | ||
| 146 | .index = index_cp, | ||
| 147 | .cube = antindex_cp, | ||
| 148 | .check = check_cp, | ||
| 149 | .max = FACTORIAL8, | ||
| 150 | .ntrans = 1, | ||
| 151 | .trans = trans_group_trivial, | ||
| 152 | }; | ||
| 153 | |||
| 154 | Coordinate | ||
| 155 | coord_cornershtr = { | ||
| 156 | .index = index_cornershtr, | ||
| 157 | .cube = antindex_cornershtr, | ||
| 158 | .check = check_cornershtr, | ||
| 159 | .max = POW3TO7 * BINOM8ON4 * 6, | ||
| 160 | .ntrans = 1, | ||
| 161 | .trans = trans_group_trivial, | ||
| 162 | }; | ||
| 163 | |||
| 164 | Coordinate | ||
| 165 | coord_drud = { | ||
| 166 | .index = index_drud, | ||
| 167 | .cube = antindex_drud, | ||
| 168 | .check = check_drud, | ||
| 169 | .max = POW2TO11 * POW3TO7 * BINOM12ON4, | ||
| 170 | .ntrans = 1, | ||
| 171 | .trans = trans_group_trivial, | ||
| 172 | }; | ||
| 173 | |||
| 174 | Coordinate | ||
| 175 | coord_htrfin = { | ||
| 176 | .index = index_htrfin, | ||
| 177 | .cube = antindex_htrfin, | ||
| 178 | .check = check_htrfin, | ||
| 179 | .max = 24 * 24 * 24 *24 * 24, | ||
| 180 | .ntrans = 1, | ||
| 181 | .trans = trans_group_trivial, | ||
| 182 | }; | ||
| 183 | |||
| 184 | Coordinate | ||
| 185 | coord_drud_eofb = { | ||
| 186 | .index = index_drud_eofb, | ||
| 187 | .cube = antindex_drud_eofb, | ||
| 188 | .check = check_drud, | ||
| 189 | .max = POW3TO7 * BINOM12ON4, | ||
| 190 | .ntrans = 1, | ||
| 191 | .trans = trans_group_trivial, | ||
| 192 | }; | ||
| 193 | |||
| 194 | Coordinate | ||
| 195 | coord_eofbepos_sym16 = { | ||
| 196 | .index = index_eofbepos_sym16, | ||
| 197 | .cube = antindex_eofbepos_sym16, | ||
| 198 | .check = check_eofbepos, | ||
| 199 | .ntrans = 16, | ||
| 200 | .trans = trans_group_udfix, | ||
| 201 | }; | ||
| 202 | |||
| 203 | Coordinate | ||
| 204 | coord_coud_sym16 = { | ||
| 205 | .index = index_coud_sym16, | ||
| 206 | .cube = antindex_coud_sym16, | ||
| 207 | .check = check_coud, | ||
| 208 | .ntrans = 16, | ||
| 209 | .trans = trans_group_udfix, | ||
| 210 | }; | ||
| 211 | |||
| 212 | Coordinate | ||
| 213 | coord_cp_sym16 = { | ||
| 214 | .index = index_cp_sym16, | ||
| 215 | .cube = antindex_cp_sym16, | ||
| 216 | .check = check_cp, | ||
| 217 | .ntrans = 16, | ||
| 218 | .trans = trans_group_udfix, | ||
| 219 | }; | ||
| 220 | |||
| 221 | Coordinate | ||
| 222 | coord_drud_sym16 = { | ||
| 223 | .index = index_drud_sym16, | ||
| 224 | .cube = antindex_drud_sym16, | ||
| 225 | .check = check_drud, | ||
| 226 | .max = POW3TO7 * 64430, | ||
| 227 | .ntrans = 16, | ||
| 228 | .trans = trans_group_udfix, | ||
| 229 | }; | ||
| 230 | |||
| 231 | Coordinate | ||
| 232 | coord_drudfin_noE_sym16 = { | ||
| 233 | .index = index_drudfin_noE_sym16, | ||
| 234 | .cube = antindex_drudfin_noE_sym16, | ||
| 235 | .check = check_drudfin_noE, | ||
| 236 | .max = FACTORIAL8 * 2768, | ||
| 237 | .ntrans = 16, | ||
| 238 | .trans = trans_group_udfix, | ||
| 239 | }; | ||
| 240 | |||
| 241 | Coordinate | ||
| 242 | coord_khuge = { | ||
| 243 | .index = index_khuge, | ||
| 244 | .cube = antindex_khuge, | ||
| 245 | .check = check_khuge, | ||
| 246 | .max = POW3TO7 * FACTORIAL4 * 64430, | ||
| 247 | .ntrans = 16, | ||
| 248 | .trans = trans_group_udfix, | ||
| 249 | }; | ||
| 250 | |||
| 251 | /* Functions *****************************************************************/ | ||
| 252 | |||
| 253 | static Cube | ||
| 254 | admissible_eos_from_eofbepos(Cube cube) | ||
| 255 | { | ||
| 256 | Edge e; | ||
| 257 | Cube ret; | ||
| 258 | CubeArray *arr = new_cubearray(cube, pf_all); | ||
| 259 | |||
| 260 | memcpy(arr->eorl, arr->eofb, 12 * sizeof(int)); | ||
| 261 | memcpy(arr->eoud, arr->eofb, 12 * sizeof(int)); | ||
| 262 | |||
| 263 | for (e = 0; e < 12; e++) { | ||
| 264 | if ((edge_slice(e) != 0 && edge_slice(arr->ep[e]) == 0) || | ||
| 265 | (edge_slice(e) == 0 && edge_slice(arr->ep[e]) != 0)) | ||
| 266 | arr->eorl[e] = 1 - arr->eorl[e]; | ||
| 267 | if ((edge_slice(e) != 2 && edge_slice(arr->ep[e]) == 2) || | ||
| 268 | (edge_slice(e) == 2 && edge_slice(arr->ep[e]) != 2)) | ||
| 269 | arr->eoud[e] = 1 - arr->eoud[e]; | ||
| 270 | } | ||
| 271 | |||
| 272 | ret = arrays_to_cube(arr, pf_all); | ||
| 273 | free_cubearray(arr, pf_all); | ||
| 274 | |||
| 275 | return ret; | ||
| 276 | } | ||
| 277 | |||
| 278 | |||
| 279 | static Cube | ||
| 280 | antindex_eofb(uint64_t ind) | ||
| 281 | { | ||
| 282 | return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind }; | ||
| 283 | } | ||
| 284 | |||
| 285 | static Cube | ||
| 286 | antindex_eofbepos(uint64_t ind) | ||
| 287 | { | ||
| 288 | static bool initialized = false; | ||
| 289 | static Cube admissible_ee_aux[POW2TO11*BINOM12ON4]; | ||
| 290 | static Cube c1; | ||
| 291 | static int k; | ||
| 292 | static uint64_t ui; | ||
| 293 | |||
| 294 | if (!initialized) { | ||
| 295 | for (ui = 0; ui < POW2TO11*BINOM12ON4; ui++) { | ||
| 296 | k = (ui / POW2TO11) * 24; | ||
| 297 | c1 = admissible_ep((Cube){ .epose = k }, pf_e); | ||
| 298 | c1.eofb = ui % POW2TO11; | ||
| 299 | c1 = admissible_eos_from_eofbepos(c1); | ||
| 300 | admissible_ee_aux[ui] = c1; | ||
| 301 | } | ||
| 302 | |||
| 303 | initialized = true; | ||
| 304 | } | ||
| 305 | |||
| 306 | return admissible_ee_aux[ind]; | ||
| 307 | } | ||
| 308 | |||
| 309 | static Cube | ||
| 310 | antindex_epud(uint64_t ind) | ||
| 311 | { | ||
| 312 | static bool initialized = false; | ||
| 313 | static Cube epud_aux[FACTORIAL8]; | ||
| 314 | int a[12]; | ||
| 315 | uint64_t ui; | ||
| 316 | CubeArray arr; | ||
| 317 | |||
| 318 | if (!initialized) { | ||
| 319 | a[FR] = FR; | ||
| 320 | a[FL] = FL; | ||
| 321 | a[BL] = BL; | ||
| 322 | a[BR] = BR; | ||
| 323 | for (ui = 0; ui < FACTORIAL8; ui++) { | ||
| 324 | index_to_perm(ui, 8, a); | ||
| 325 | arr.ep = a; | ||
| 326 | epud_aux[ui] = arrays_to_cube(&arr, pf_ep); | ||
| 327 | } | ||
| 328 | |||
| 329 | initialized = true; | ||
| 330 | } | ||
| 331 | |||
| 332 | return epud_aux[ind]; | ||
| 333 | } | ||
| 334 | |||
| 335 | static Cube | ||
| 336 | antindex_coud(uint64_t ind) | ||
| 337 | { | ||
| 338 | return (Cube){ .coud = ind, .corl = ind, .cofb = ind }; | ||
| 339 | } | ||
| 340 | |||
| 341 | static Cube | ||
| 342 | antindex_corners(uint64_t ind) | ||
| 343 | { | ||
| 344 | Cube c = {0}; | ||
| 345 | |||
| 346 | c.coud = ind / FACTORIAL8; | ||
| 347 | c.cp = ind % FACTORIAL8; | ||
| 348 | |||
| 349 | return c; | ||
| 350 | } | ||
| 351 | |||
| 352 | static Cube | ||
| 353 | antindex_cp(uint64_t ind) | ||
| 354 | { | ||
| 355 | Cube c = {0}; | ||
| 356 | |||
| 357 | c.cp = ind; | ||
| 358 | |||
| 359 | return c; | ||
| 360 | } | ||
| 361 | |||
| 362 | static Cube | ||
| 363 | antindex_cornershtr(uint64_t ind) | ||
| 364 | { | ||
| 365 | Cube c = anti_cphtr(ind % (BINOM8ON4 * 6)); | ||
| 366 | |||
| 367 | c.coud = ind / (BINOM8ON4 * 6); | ||
| 368 | |||
| 369 | return c; | ||
| 370 | } | ||
| 371 | |||
| 372 | /* TODO: admissible eos and cos */ | ||
| 373 | /* DONE: temporary fix, make it better */ | ||
| 374 | /* Or maybe it's ok like this? */ | ||
| 375 | static Cube | ||
| 376 | antindex_drud(uint64_t ind) | ||
| 377 | { | ||
| 378 | uint64_t epos, eofb; | ||
| 379 | Cube c; | ||
| 380 | |||
| 381 | eofb = ind % POW2TO11; | ||
| 382 | epos = ind / (POW2TO11 * POW3TO7); | ||
| 383 | c = antindex_eofbepos(eofb + POW2TO11 * epos); | ||
| 384 | |||
| 385 | c.coud = (ind / POW2TO11) % POW3TO7; | ||
| 386 | c.corl = c.coud; | ||
| 387 | c.cofb = c.coud; | ||
| 388 | |||
| 389 | return c; | ||
| 390 | } | ||
| 391 | |||
| 392 | static Cube | ||
| 393 | antindex_drud_eofb(uint64_t ind) | ||
| 394 | { | ||
| 395 | return antindex_drud(ind * POW2TO11); | ||
| 396 | } | ||
| 397 | |||
| 398 | static Cube | ||
| 399 | antindex_coud_sym16(uint64_t ind) | ||
| 400 | { | ||
| 401 | return sd_coud_16.rep[ind]; | ||
| 402 | } | ||
| 403 | |||
| 404 | static Cube | ||
| 405 | antindex_cp_sym16(uint64_t ind) | ||
| 406 | { | ||
| 407 | return sd_cp_16.rep[ind]; | ||
| 408 | } | ||
| 409 | |||
| 410 | static Cube | ||
| 411 | antindex_eofbepos_sym16(uint64_t ind) | ||
| 412 | { | ||
| 413 | return sd_eofbepos_16.rep[ind]; | ||
| 414 | } | ||
| 415 | |||
| 416 | static Cube | ||
| 417 | antindex_drud_sym16(uint64_t ind) | ||
| 418 | { | ||
| 419 | Cube c; | ||
| 420 | |||
| 421 | c = sd_eofbepos_16.rep[ind/POW3TO7]; | ||
| 422 | c.coud = ind % POW3TO7; | ||
| 423 | c.cofb = c.coud; | ||
| 424 | c.corl = c.coud; | ||
| 425 | |||
| 426 | return c; | ||
| 427 | } | ||
| 428 | |||
| 429 | static Cube | ||
| 430 | antindex_drudfin_noE_sym16(uint64_t ind) | ||
| 431 | { | ||
| 432 | Cube c1, c2; | ||
| 433 | |||
| 434 | c1 = antindex_epud(ind % FACTORIAL8); | ||
| 435 | c2 = sd_cp_16.rep[ind/FACTORIAL8]; | ||
| 436 | c1.cp = c2.cp; | ||
| 437 | |||
| 438 | return c1; | ||
| 439 | } | ||
| 440 | |||
| 441 | static Cube | ||
| 442 | antindex_htrfin(uint64_t ind) | ||
| 443 | { | ||
| 444 | Cube ret = {0}; | ||
| 445 | uint64_t cp1, cp2; | ||
| 446 | |||
| 447 | static bool initialized = false; | ||
| 448 | static int i, j, k, c[8], c1[4], c2[4], cp[24][24]; | ||
| 449 | static int c1solved[4] = {UFR, UBL, DFL, DBR}; | ||
| 450 | static int c2solved[4] = {UFL, UBR, DFR, DBL}; | ||
| 451 | |||
| 452 | if (!initialized) { | ||
| 453 | for (i = 0; i < 24; i++) { | ||
| 454 | for (j = 0; j < 24; j++) { | ||
| 455 | index_to_perm(i, 4, c1); | ||
| 456 | index_to_perm(j, 4, c2); | ||
| 457 | for (k = 0; k < 8; k++) | ||
| 458 | if (k == UFR || k == UBL || | ||
| 459 | k == DFL || k == DBR) | ||
| 460 | c[k] = c1[c1solved[k/2]]; | ||
| 461 | else | ||
| 462 | c[k] = c2[c2solved[k/2]]; | ||
| 463 | |||
| 464 | cp[i][j] = perm_to_index(c, 8); | ||
| 465 | } | ||
| 466 | } | ||
| 467 | |||
| 468 | initialized = true; | ||
| 469 | } | ||
| 470 | |||
| 471 | cp2 = ind % 24; | ||
| 472 | ind /= 24; | ||
| 473 | cp1 = ind % 24; | ||
| 474 | ret.cp = cp[cp1][cp2]; | ||
| 475 | |||
| 476 | ind /= 24; | ||
| 477 | ret.eposm = ind % 24; | ||
| 478 | ind /= 24; | ||
| 479 | ret.eposs = ind % 24; | ||
| 480 | ret.epose = ind / 24; | ||
| 481 | |||
| 482 | return ret; | ||
| 483 | } | ||
| 484 | |||
| 485 | static Cube | ||
| 486 | antindex_khuge(uint64_t ind) | ||
| 487 | { | ||
| 488 | Cube c; | ||
| 489 | |||
| 490 | c = sd_eofbepos_16.rep[ind/(FACTORIAL4*POW3TO7)]; | ||
| 491 | c.epose = ((c.epose / 24) * 24) + ((ind/POW3TO7) % 24); | ||
| 492 | c.coud = ind % POW3TO7; | ||
| 493 | |||
| 494 | return c; | ||
| 495 | } | ||
| 496 | |||
| 497 | bool | ||
| 498 | check_centers(Cube cube) | ||
| 499 | { | ||
| 500 | return cube.cpos == 0; | ||
| 501 | } | ||
| 502 | |||
| 503 | bool | ||
| 504 | check_corners(Cube cube) | ||
| 505 | { | ||
| 506 | return cube.cp == 0 && cube.coud == 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | bool | ||
| 510 | check_cp(Cube cube) | ||
| 511 | { | ||
| 512 | return cube.cp == 0; | ||
| 513 | } | ||
| 514 | |||
| 515 | bool | ||
| 516 | check_cornershtr(Cube cube) | ||
| 517 | { | ||
| 518 | return cube.coud == 0 && cphtr(cube) == 0; /* TODO: use array cphtrcosets*/ | ||
| 519 | } | ||
| 520 | |||
| 521 | bool | ||
| 522 | check_coud(Cube cube) | ||
| 523 | { | ||
| 524 | return cube.coud == 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | bool | ||
| 528 | check_drud(Cube cube) | ||
| 529 | { | ||
| 530 | return cube.eofb == 0 && cube.eorl == 0 && cube.coud == 0; | ||
| 531 | } | ||
| 532 | |||
| 533 | bool | ||
| 534 | check_htr(Cube cube) | ||
| 535 | { | ||
| 536 | return check_cornershtr(cube) && | ||
| 537 | cube.eofb == 0 && cube.eorl == 0 && cube.eoud == 0; | ||
| 538 | } | ||
| 539 | |||
| 540 | bool | ||
| 541 | check_htrfin(Cube cube) | ||
| 542 | { | ||
| 543 | return cube.cp == 0 && | ||
| 544 | cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0; | ||
| 545 | } | ||
| 546 | |||
| 547 | bool | ||
| 548 | check_drudfin_noE(Cube cube) | ||
| 549 | { | ||
| 550 | return cube.eposs == 0 && cube.eposm == 0 && cube.cp == 0; | ||
| 551 | } | ||
| 552 | |||
| 553 | bool | ||
| 554 | check_eofb(Cube cube) | ||
| 555 | { | ||
| 556 | return cube.eofb == 0; | ||
| 557 | } | ||
| 558 | |||
| 559 | bool | ||
| 560 | check_eofbepos(Cube cube) | ||
| 561 | { | ||
| 562 | return cube.eofb == 0 && cube.epose / 24 == 0; | ||
| 563 | } | ||
| 564 | |||
| 565 | bool | ||
| 566 | check_epose(Cube cube) | ||
| 567 | { | ||
| 568 | return cube.epose == 0; | ||
| 569 | } | ||
| 570 | |||
| 571 | bool | ||
| 572 | check_ep(Cube cube) | ||
| 573 | { | ||
| 574 | return cube.epose == 0 && cube.eposs == 0 && cube.eposm == 0; | ||
| 575 | } | ||
| 576 | |||
| 577 | bool | ||
| 578 | check_khuge(Cube cube) | ||
| 579 | { | ||
| 580 | return check_drud(cube) && cube.epose % 24 == 0; | ||
| 581 | } | ||
| 582 | |||
| 583 | bool | ||
| 584 | check_nothing(Cube cube) | ||
| 585 | { | ||
| 586 | return is_admissible(cube); /*TODO: maybe change?*/ | ||
| 587 | } | ||
| 588 | |||
| 589 | static int | ||
| 590 | epos_dependent_pos(int poss, int pose) | ||
| 591 | { | ||
| 592 | static int epe_solved[4] = {FR, FL, BL, BR}; | ||
| 593 | static int eps_solved[4] = {UL, UR, DL, DR}; | ||
| 594 | int ep[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; | ||
| 595 | int ep8[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | ||
| 596 | int i, j; | ||
| 597 | |||
| 598 | epos_to_partial_ep(poss*FACTORIAL4, ep, eps_solved); | ||
| 599 | epos_to_partial_ep(pose*FACTORIAL4, ep, epe_solved); | ||
| 600 | |||
| 601 | for (i = 0, j = 0; i < 12; i++) | ||
| 602 | if (edge_slice(ep[i]) != 0) | ||
| 603 | ep8[j++] = (edge_slice(ep[i]) == 1) ? 1 : 0; | ||
| 604 | |||
| 605 | swap(&ep8[1], &ep8[4]); | ||
| 606 | swap(&ep8[3], &ep8[6]); | ||
| 607 | |||
| 608 | return subset_to_index(ep8, 8, 4); | ||
| 609 | } | ||
| 610 | |||
| 611 | static void | ||
| 612 | gensym(SymData *sd) | ||
| 613 | { | ||
| 614 | uint64_t i, in, nreps = 0; | ||
| 615 | int j; | ||
| 616 | Cube c, d; | ||
| 617 | |||
| 618 | if (sd->generated) | ||
| 619 | return; | ||
| 620 | |||
| 621 | sd->class = malloc(sd->coord->max * sizeof(uint64_t)); | ||
| 622 | sd->rep = malloc(sd->coord->max * sizeof(Cube)); | ||
| 623 | sd->transtorep = malloc(sd->coord->max * sizeof(Trans)); | ||
| 624 | |||
| 625 | if (read_symdata_file(sd)) { | ||
| 626 | sd->generated = true; | ||
| 627 | return; | ||
| 628 | } | ||
| 629 | |||
| 630 | fprintf(stderr, "Cannot load %s, generating it\n", sd->filename); | ||
| 631 | |||
| 632 | for (i = 0; i < sd->coord->max; i++) | ||
| 633 | sd->class[i] = sd->coord->max + 1; | ||
| 634 | |||
| 635 | for (i = 0; i < sd->coord->max; i++) { | ||
| 636 | if (sd->class[i] == sd->coord->max + 1) { | ||
| 637 | c = sd->coord->cube(i); | ||
| 638 | sd->rep[nreps] = c; | ||
| 639 | for (j = 0; j < sd->ntrans; j++) { | ||
| 640 | d = apply_trans(sd->trans[j], c); | ||
| 641 | in = sd->coord->index(d); | ||
| 642 | |||
| 643 | if (sd->class[in] == sd->coord->max + 1) { | ||
| 644 | sd->class[in] = nreps; | ||
| 645 | sd->transtorep[in] = | ||
| 646 | inverse_trans(sd->trans[j]); | ||
| 647 | } | ||
| 648 | } | ||
| 649 | nreps++; | ||
| 650 | } | ||
| 651 | } | ||
| 652 | |||
| 653 | sd->sym_coord->max = nreps; | ||
| 654 | sd->rep = realloc(sd->rep, nreps * sizeof(Cube)); | ||
| 655 | sd->generated = true; | ||
| 656 | |||
| 657 | fprintf(stderr, "Found %lu classes\n", nreps); | ||
| 658 | |||
| 659 | if (!write_symdata_file(sd)) | ||
| 660 | fprintf(stderr, "Error writing SymData file\n"); | ||
| 661 | |||
| 662 | return; | ||
| 663 | } | ||
| 664 | |||
| 665 | static uint64_t | ||
| 666 | index_eofb(Cube cube) | ||
| 667 | { | ||
| 668 | return cube.eofb; | ||
| 669 | } | ||
| 670 | |||
| 671 | static uint64_t | ||
| 672 | index_eofbepos(Cube cube) | ||
| 673 | { | ||
| 674 | return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb; | ||
| 675 | } | ||
| 676 | |||
| 677 | static uint64_t | ||
| 678 | index_epud(Cube cube) | ||
| 679 | { | ||
| 680 | uint64_t ret; | ||
| 681 | CubeArray *arr = new_cubearray(cube, pf_ep); | ||
| 682 | |||
| 683 | ret = perm_to_index(arr->ep, 8); | ||
| 684 | free_cubearray(arr, pf_ep); | ||
| 685 | |||
| 686 | return ret; | ||
| 687 | } | ||
| 688 | |||
| 689 | static uint64_t | ||
| 690 | index_coud(Cube cube) | ||
| 691 | { | ||
| 692 | return cube.coud; | ||
| 693 | } | ||
| 694 | |||
| 695 | static uint64_t | ||
| 696 | index_corners(Cube cube) | ||
| 697 | { | ||
| 698 | return cube.coud * FACTORIAL8 + cube.cp; | ||
| 699 | } | ||
| 700 | |||
| 701 | static uint64_t | ||
| 702 | index_cp(Cube cube) | ||
| 703 | { | ||
| 704 | return cube.cp; | ||
| 705 | } | ||
| 706 | |||
| 707 | static uint64_t | ||
| 708 | index_cornershtr(Cube cube) | ||
| 709 | { | ||
| 710 | return cube.coud * BINOM8ON4 * 6 + cphtr(cube); | ||
| 711 | } | ||
| 712 | |||
| 713 | static uint64_t | ||
| 714 | index_drud(Cube cube) | ||
| 715 | { | ||
| 716 | uint64_t a, b, c; | ||
| 717 | |||
| 718 | a = cube.eofb; | ||
| 719 | b = cube.coud; | ||
| 720 | c = cube.epose / FACTORIAL4; | ||
| 721 | |||
| 722 | b *= POW2TO11; | ||
| 723 | c *= POW2TO11 * POW3TO7; | ||
| 724 | |||
| 725 | return a + b + c; | ||
| 726 | } | ||
| 727 | |||
| 728 | static uint64_t | ||
| 729 | index_drud_eofb(Cube cube) | ||
| 730 | { | ||
| 731 | return index_drud(cube) / POW2TO11; | ||
| 732 | } | ||
| 733 | |||
| 734 | static uint64_t | ||
| 735 | index_coud_sym16(Cube cube) | ||
| 736 | { | ||
| 737 | return sd_coud_16.class[index_coud(cube)]; | ||
| 738 | } | ||
| 739 | |||
| 740 | static uint64_t | ||
| 741 | index_cp_sym16(Cube cube) | ||
| 742 | { | ||
| 743 | return sd_cp_16.class[index_cp(cube)]; | ||
| 744 | } | ||
| 745 | |||
| 746 | static uint64_t | ||
| 747 | index_drud_sym16(Cube cube) | ||
| 748 | { | ||
| 749 | Trans t; | ||
| 750 | Cube c; | ||
| 751 | |||
| 752 | t = sd_eofbepos_16.transtorep[index_eofbepos(cube)]; | ||
| 753 | c = apply_trans(t, cube); | ||
| 754 | |||
| 755 | return index_eofbepos_sym16(c) * POW3TO7 + c.coud; | ||
| 756 | } | ||
| 757 | |||
| 758 | static uint64_t | ||
| 759 | index_drudfin_noE_sym16(Cube cube) | ||
| 760 | { | ||
| 761 | Trans t; | ||
| 762 | Cube c; | ||
| 763 | |||
| 764 | t = sd_cp_16.transtorep[index_cp(cube)]; | ||
| 765 | c = apply_trans(t, cube); | ||
| 766 | |||
| 767 | return index_cp_sym16(c) * FACTORIAL8 + index_epud(c); | ||
| 768 | } | ||
| 769 | |||
| 770 | static uint64_t | ||
| 771 | index_htrfin(Cube cube) | ||
| 772 | { | ||
| 773 | uint64_t epe, eps, epm, cp, ep; | ||
| 774 | |||
| 775 | static bool initialized = false; | ||
| 776 | static uint64_t cp1[FACTORIAL8], cp2[FACTORIAL8]; | ||
| 777 | static unsigned int i; | ||
| 778 | static int j, n1, n2, c[8], c1[4], c2[4]; | ||
| 779 | |||
| 780 | if (!initialized) { | ||
| 781 | for (i = 0; i < FACTORIAL8; i++) { | ||
| 782 | index_to_perm(i, 8, c); | ||
| 783 | n1 = 0; | ||
| 784 | n2 = 0; | ||
| 785 | for (j = 0; j < 8; j++) | ||
| 786 | if (c[j] == UFR || c[j] == UBL || | ||
| 787 | c[j] == DFL || c[j] == DBR) | ||
| 788 | c1[n1++] = c[j] / 2; | ||
| 789 | else | ||
| 790 | c2[n2++] = c[j] / 2; | ||
| 791 | |||
| 792 | cp1[i] = perm_to_index(c1, 4); | ||
| 793 | cp2[i] = perm_to_index(c2, 4); | ||
| 794 | } | ||
| 795 | |||
| 796 | initialized = true; | ||
| 797 | } | ||
| 798 | |||
| 799 | epe = cube.epose % 24; | ||
| 800 | eps = cube.eposs % 24; | ||
| 801 | epm = cube.eposm % 24; | ||
| 802 | |||
| 803 | cp = cp1[cube.cp] * 24 + cp2[cube.cp]; | ||
| 804 | ep = (epe * 24 + eps) *24 + epm; | ||
| 805 | |||
| 806 | return ep * 24 * 24 + cp; | ||
| 807 | } | ||
| 808 | |||
| 809 | static uint64_t | ||
| 810 | index_eofbepos_sym16(Cube cube) | ||
| 811 | { | ||
| 812 | return sd_eofbepos_16.class[index_eofbepos(cube)]; | ||
| 813 | } | ||
| 814 | |||
| 815 | static uint64_t | ||
| 816 | index_khuge(Cube cube) | ||
| 817 | { | ||
| 818 | Trans t; | ||
| 819 | Cube c; | ||
| 820 | uint64_t a; | ||
| 821 | |||
| 822 | t = sd_eofbepos_16.transtorep[index_eofbepos(cube)]; | ||
| 823 | c = apply_trans(t, cube); | ||
| 824 | a = (index_eofbepos_sym16(c) * 24) + (c.epose % 24); | ||
| 825 | |||
| 826 | return a * POW3TO7 + c.coud; | ||
| 827 | } | ||
| 828 | |||
| 829 | static bool | ||
| 830 | read_symdata_file(SymData *sd) | ||
| 831 | { | ||
| 832 | init_env(); | ||
| 833 | |||
| 834 | FILE *f; | ||
| 835 | char fname[strlen(tabledir)+100]; | ||
| 836 | uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max; | ||
| 837 | bool r = true; | ||
| 838 | |||
| 839 | strcpy(fname, tabledir); | ||
| 840 | strcat(fname, "/"); | ||
| 841 | strcat(fname, sd->filename); | ||
| 842 | |||
| 843 | if ((f = fopen(fname, "rb")) == NULL) | ||
| 844 | return false; | ||
| 845 | |||
| 846 | r = r && fread(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; | ||
| 847 | r = r && fread(sd->rep, sizeof(Cube), *sn, f) == *sn; | ||
| 848 | r = r && fread(sd->class, sizeof(uint64_t), n, f) == n; | ||
| 849 | r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n; | ||
| 850 | |||
| 851 | fclose(f); | ||
| 852 | return r; | ||
| 853 | } | ||
| 854 | |||
| 855 | static bool | ||
| 856 | write_symdata_file(SymData *sd) | ||
| 857 | { | ||
| 858 | init_env(); | ||
| 859 | |||
| 860 | FILE *f; | ||
| 861 | char fname[strlen(tabledir)+100]; | ||
| 862 | uint64_t n = sd->coord->max, *sn = &sd->sym_coord->max; | ||
| 863 | bool r = true; | ||
| 864 | |||
| 865 | strcpy(fname, tabledir); | ||
| 866 | strcat(fname, "/"); | ||
| 867 | strcat(fname, sd->filename); | ||
| 868 | |||
| 869 | if ((f = fopen(fname, "wb")) == NULL) | ||
| 870 | return false; | ||
| 871 | |||
| 872 | r = r && fwrite(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; | ||
| 873 | r = r && fwrite(sd->rep, sizeof(Cube), *sn, f) == *sn; | ||
| 874 | r = r && fwrite(sd->class, sizeof(uint64_t), n, f) == n; | ||
| 875 | r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n; | ||
| 876 | |||
| 877 | fclose(f); | ||
| 878 | return r; | ||
| 879 | } | ||
| 880 | |||
| 881 | /* Init functions implementation *********************************************/ | ||
| 882 | |||
| 883 | /* | ||
| 884 | * There is certainly a bette way to do this, but for now I just use | ||
| 885 | * a "graph coloring" algorithm to compute the left cosets, and I compose | ||
| 886 | * with every possible cp to get the right cosets (it is possible that I am | ||
| 887 | * mixing up left and right). | ||
| 888 | * | ||
| 889 | * For doing it better "Mathematically", we need 3 things: | ||
| 890 | * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other | ||
| 891 | * This is easy and it is done in the commented function cphtr_cp(). | ||
| 892 | * - Check that there is no ep/cp parity | ||
| 893 | * - Check that we are not in the "3c" case; this is the part I don't | ||
| 894 | * know how to do. | ||
| 895 | */ | ||
| 896 | static void | ||
| 897 | init_cphtr_cosets() | ||
| 898 | { | ||
| 899 | unsigned int i; | ||
| 900 | int c = 0, d = 0; | ||
| 901 | |||
| 902 | for (i = 0; i < FACTORIAL8; i++) { | ||
| 903 | cphtr_left_cosets[i] = -1; | ||
| 904 | cphtr_right_cosets[i] = -1; | ||
| 905 | } | ||
| 906 | |||
| 907 | /* First we compute left cosets with a bfs */ | ||
| 908 | for (i = 0; i < FACTORIAL8; i++) | ||
| 909 | if (cphtr_left_cosets[i] == -1) | ||
| 910 | init_cphtr_left_cosets_bfs(i, c++); | ||
| 911 | |||
| 912 | /* Then we compute right cosets using compose() */ | ||
| 913 | for (i = 0; i < FACTORIAL8; i++) | ||
| 914 | if (cphtr_right_cosets[i] == -1) | ||
| 915 | init_cphtr_right_cosets_color(i, d++); | ||
| 916 | } | ||
| 917 | |||
| 918 | static void | ||
| 919 | init_cphtr_left_cosets_bfs(int i, int c) | ||
| 920 | { | ||
| 921 | int j, jj, k, next[FACTORIAL8], next2[FACTORIAL8], n, n2; | ||
| 922 | Move moves[6] = {U2, D2, R2, L2, F2, B2}; | ||
| 923 | |||
| 924 | n = 1; | ||
| 925 | next[0] = i; | ||
| 926 | cphtr_left_cosets[i] = c; | ||
| 927 | |||
| 928 | while (n != 0) { | ||
| 929 | for (j = 0, n2 = 0; j < n; j++) { | ||
| 930 | for (k = 0; k < 6; k++) { | ||
| 931 | /*jj = cp_mtable[moves[k]][next[j]];*/ | ||
| 932 | /* TODO fix formatting */ | ||
| 933 | jj = apply_move(moves[k], (Cube){.cp=next[j]}).cp; | ||
| 934 | if (cphtr_left_cosets[jj] == -1) { | ||
| 935 | cphtr_left_cosets[jj] = c; | ||
| 936 | next2[n2++] = jj; | ||
| 937 | } | ||
| 938 | } | ||
| 939 | } | ||
| 940 | |||
| 941 | for (j = 0; j < n2; j++) | ||
| 942 | next[j] = next2[j]; | ||
| 943 | n = n2; | ||
| 944 | } | ||
| 945 | } | ||
| 946 | |||
| 947 | static void | ||
| 948 | init_cphtr_right_cosets_color(int i, int d) | ||
| 949 | { | ||
| 950 | int cp; | ||
| 951 | unsigned int j; | ||
| 952 | |||
| 953 | cphtr_right_rep[d] = i; | ||
| 954 | for (j = 0; j < FACTORIAL8; j++) { | ||
| 955 | if (cphtr_left_cosets[j] == 0) { | ||
| 956 | /* TODO: use antindexer, it's nicer */ | ||
| 957 | cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp; | ||
| 958 | cphtr_right_cosets[cp] = d; | ||
| 959 | } | ||
| 960 | } | ||
| 961 | } | ||
| 962 | |||
| 963 | static void | ||
| 964 | init_symdata() | ||
| 965 | { | ||
| 966 | int i; | ||
| 967 | |||
| 968 | for (i = 0; i < n_all_symdata; i++) | ||
| 969 | gensym(all_sd[i]); | ||
| 970 | } | ||
| 971 | |||
| 972 | /*TODO maybe move the next two */ | ||
| 973 | uint64_t | ||
| 974 | cphtr(Cube cube) | ||
| 975 | { | ||
| 976 | return cphtr_right_cosets[cube.cp]; | ||
| 977 | } | ||
| 978 | |||
| 979 | Cube | ||
| 980 | anti_cphtr(uint64_t ind) | ||
| 981 | { | ||
| 982 | return (Cube) { .cp = cphtr_right_rep[ind] }; | ||
| 983 | } | ||
| 984 | |||
| 985 | uint64_t | ||
| 986 | epos_dependent(Cube c) | ||
| 987 | { | ||
| 988 | static int initialized = false; | ||
| 989 | static int aux[BINOM12ON4][BINOM12ON4]; | ||
| 990 | static uint64_t ui, uj; | ||
| 991 | |||
| 992 | if (!initialized) { | ||
| 993 | for (ui = 0; ui < BINOM12ON4; ui++) | ||
| 994 | for (uj = 0; uj < BINOM12ON4; uj++) | ||
| 995 | aux[ui][uj] = epos_dependent_pos(ui, uj); | ||
| 996 | |||
| 997 | initialized = true; | ||
| 998 | } | ||
| 999 | |||
| 1000 | return aux[c.eposs/FACTORIAL4][c.epose/FACTORIAL4]; | ||
| 1001 | } | ||
| 1002 | |||
| 1003 | void | ||
| 1004 | init_coord() | ||
| 1005 | { | ||
| 1006 | static bool initialized = false; | ||
| 1007 | if (initialized) | ||
| 1008 | return; | ||
| 1009 | initialized = true; | ||
| 1010 | |||
| 1011 | init_cphtr_cosets(); | ||
| 1012 | init_symdata(); | ||
| 1013 | } | ||
| 1014 | |||
