aboutsummaryrefslogtreecommitdiff
path: root/src/coord.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/coord.c522
1 files changed, 522 insertions, 0 deletions
diff --git a/src/coord.c b/src/coord.c
new file mode 100644
index 0000000..8c978bc
--- /dev/null
+++ b/src/coord.c
@@ -0,0 +1,522 @@
1#include "coord.h"
2
3static Cube antindex_eofb(uint64_t ind);
4static Cube antindex_eofbepos(uint64_t ind);
5static Cube antindex_epud(uint64_t ind);
6static Cube antindex_coud(uint64_t ind);
7static Cube antindex_corners(uint64_t ind);
8static Cube antindex_cp(uint64_t ind);
9static Cube antindex_cphtr(uint64_t);
10static Cube antindex_cornershtr(uint64_t ind);
11static Cube antindex_cornershtrfin(uint64_t ind);
12static Cube antindex_drud(uint64_t ind);
13static Cube antindex_drud_eofb(uint64_t ind);
14static Cube antindex_htr_drud(uint64_t ind);
15static Cube antindex_htrfin(uint64_t ind);
16
17static uint64_t index_eofb(Cube cube);
18static uint64_t index_eofbepos(Cube cube);
19static uint64_t index_epud(Cube cube);
20static uint64_t index_coud(Cube cube);
21static uint64_t index_corners(Cube cube);
22static uint64_t index_cp(Cube cube);
23static uint64_t index_cphtr(Cube cube);
24static uint64_t index_cornershtr(Cube cube);
25static uint64_t index_cornershtrfin(Cube cube);
26static uint64_t index_drud(Cube cube);
27static uint64_t index_drud_eofb(Cube cube);
28static uint64_t index_htr_drud(Cube cube);
29static uint64_t index_htrfin(Cube cube);
30
31static void init_cphtr_cosets();
32static void init_cphtr_left_cosets_bfs(int i, int c);
33static void init_cphtr_right_cosets_color(int i, int c);
34static void init_cornershtrfin();
35
36
37/* All sorts of useful costants and tables **********************************/
38
39static int cphtr_left_cosets[FACTORIAL8];
40static int cphtr_right_cosets[FACTORIAL8];
41static int cphtr_right_rep[BINOM8ON4*6];
42static int cornershtrfin_ind[FACTORIAL8];
43static int cornershtrfin_ant[24*24/6];
44
45/* Coordinates and their implementation **************************************/
46
47Coordinate
48coord_eofb = {
49 .index = index_eofb,
50 .cube = antindex_eofb,
51 .max = POW2TO11,
52 .ntrans = 1,
53};
54
55Coordinate
56coord_eofbepos = {
57 .index = index_eofbepos,
58 .cube = antindex_eofbepos,
59 .max = POW2TO11 * BINOM12ON4,
60 .ntrans = 1,
61};
62
63Coordinate
64coord_coud = {
65 .index = index_coud,
66 .cube = antindex_coud,
67 .max = POW3TO7,
68 .ntrans = 1,
69};
70
71Coordinate
72coord_corners = {
73 .index = index_corners,
74 .cube = antindex_corners,
75 .max = POW3TO7 * FACTORIAL8,
76 .ntrans = 1,
77};
78
79Coordinate
80coord_cp = {
81 .index = index_cp,
82 .cube = antindex_cp,
83 .max = FACTORIAL8,
84 .ntrans = 1,
85};
86
87Coordinate
88coord_cphtr = {
89 .index = index_cphtr,
90 .cube = antindex_cphtr,
91 .max = BINOM8ON4 * 6,
92 .ntrans = 1,
93};
94
95Coordinate
96coord_cornershtr = {
97 .index = index_cornershtr,
98 .cube = antindex_cornershtr,
99 .max = POW3TO7 * BINOM8ON4 * 6,
100 .ntrans = 1,
101};
102
103Coordinate
104coord_cornershtrfin = {
105 .index = index_cornershtrfin,
106 .cube = antindex_cornershtrfin,
107 .max = 24*24/6,
108 .ntrans = 1,
109};
110
111Coordinate
112coord_epud = {
113 .index = index_epud,
114 .cube = antindex_epud,
115 .max = FACTORIAL8,
116 .ntrans = 1,
117};
118
119Coordinate
120coord_drud = {
121 .index = index_drud,
122 .cube = antindex_drud,
123 .max = POW2TO11 * POW3TO7 * BINOM12ON4,
124 .ntrans = 1,
125};
126
127Coordinate
128coord_htr_drud = {
129 .index = index_htr_drud,
130 .cube = antindex_htr_drud,
131 .max = BINOM8ON4 * 6 * BINOM8ON4,
132 .ntrans = 1,
133};
134
135Coordinate
136coord_htrfin = {
137 .index = index_htrfin,
138 .cube = antindex_htrfin,
139 .max = 24 * 24 * 24 *24 * 24 / 6, /* should be /12 but it's ok */
140 .ntrans = 1,
141};
142
143Coordinate
144coord_drud_eofb = {
145 .index = index_drud_eofb,
146 .cube = antindex_drud_eofb,
147 .max = POW3TO7 * BINOM12ON4,
148 .ntrans = 1,
149};
150
151/* Functions *****************************************************************/
152
153static Cube
154antindex_eofb(uint64_t ind)
155{
156 return (Cube){ .eofb = ind, .eorl = ind, .eoud = ind };
157}
158
159static Cube
160antindex_eofbepos(uint64_t ind)
161{
162 Cube ret = {0};
163
164 ret.eofb = ind % POW2TO11;
165 ret.epose = (ind / POW2TO11) * 24;
166
167 return ret;
168}
169
170static Cube
171antindex_epud(uint64_t ind)
172{
173 static bool initialized = false;
174 static Cube epud_aux[FACTORIAL8];
175 int a[12];
176 uint64_t ui;
177 CubeArray arr;
178
179 if (!initialized) {
180 a[FR] = FR;
181 a[FL] = FL;
182 a[BL] = BL;
183 a[BR] = BR;
184 for (ui = 0; ui < FACTORIAL8; ui++) {
185 index_to_perm(ui, 8, a);
186 arr.ep = a;
187 epud_aux[ui] = arrays_to_cube(&arr, pf_ep);
188 }
189
190 initialized = true;
191 }
192
193 return epud_aux[ind];
194}
195
196static Cube
197antindex_coud(uint64_t ind)
198{
199 return (Cube){ .coud = ind, .corl = ind, .cofb = ind };
200}
201
202static Cube
203antindex_corners(uint64_t ind)
204{
205 Cube c = {0};
206
207 c.coud = ind / FACTORIAL8;
208 c.cp = ind % FACTORIAL8;
209
210 return c;
211}
212
213static Cube
214antindex_cp(uint64_t ind)
215{
216 Cube c = {0};
217
218 c.cp = ind;
219
220 return c;
221}
222
223static Cube
224antindex_cphtr(uint64_t ind)
225{
226 return (Cube) { .cp = cphtr_right_rep[ind] };
227}
228
229static Cube
230antindex_cornershtr(uint64_t ind)
231{
232 Cube c = antindex_cphtr(ind % (BINOM8ON4 * 6));
233
234 c.coud = ind / (BINOM8ON4 * 6);
235
236 return c;
237}
238
239static Cube
240antindex_cornershtrfin(uint64_t ind)
241{
242 return (Cube){ .cp = cornershtrfin_ant[ind] };
243}
244
245static Cube
246antindex_drud(uint64_t ind)
247{
248 uint64_t epos, eofb;
249 Cube c;
250
251 eofb = ind % POW2TO11;
252 epos = ind / (POW2TO11 * POW3TO7);
253 c = antindex_eofbepos(eofb + POW2TO11 * epos);
254
255 c.coud = (ind / POW2TO11) % POW3TO7;
256
257 return c;
258}
259
260static Cube
261antindex_drud_eofb(uint64_t ind)
262{
263 return antindex_drud(ind * POW2TO11);
264}
265
266static Cube
267antindex_htr_drud(uint64_t ind)
268{
269 Cube ret;
270
271 ret = antindex_cphtr(ind / BINOM8ON4);
272 ret.eposs = (ind % BINOM8ON4) * FACTORIAL4;
273
274 return ret;
275}
276
277static Cube
278antindex_htrfin(uint64_t ind)
279{
280 Cube ret;
281
282 ret = antindex_cornershtrfin(ind/(24*24*24));
283
284 ret.eposm = ind % 24;
285 ind /= 24;
286 ret.eposs = ind % 24;
287 ind /= 24;
288 ret.epose = ind % 24;
289
290 return ret;
291}
292
293static uint64_t
294index_eofb(Cube cube)
295{
296 return cube.eofb;
297}
298
299static uint64_t
300index_eofbepos(Cube cube)
301{
302 return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
303}
304
305static uint64_t
306index_epud(Cube cube)
307{
308 uint64_t ret;
309 CubeArray *arr = new_cubearray(cube, pf_ep);
310
311 ret = perm_to_index(arr->ep, 8);
312 free_cubearray(arr, pf_ep);
313
314 return ret;
315}
316
317static uint64_t
318index_coud(Cube cube)
319{
320 return cube.coud;
321}
322
323static uint64_t
324index_corners(Cube cube)
325{
326 return cube.coud * FACTORIAL8 + cube.cp;
327}
328
329static uint64_t
330index_cp(Cube cube)
331{
332 return cube.cp;
333}
334
335static uint64_t
336index_cphtr(Cube cube)
337{
338 return cphtr_right_cosets[cube.cp];
339}
340
341static uint64_t
342index_cornershtr(Cube cube)
343{
344 return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube);
345}
346
347static uint64_t
348index_cornershtrfin(Cube cube)
349{
350 return cornershtrfin_ind[cube.cp];
351}
352
353static uint64_t
354index_drud(Cube cube)
355{
356 uint64_t a, b, c;
357
358 a = cube.eofb;
359 b = cube.coud;
360 c = cube.epose / FACTORIAL4;
361
362 b *= POW2TO11;
363 c *= POW2TO11 * POW3TO7;
364
365 return a + b + c;
366}
367
368static uint64_t
369index_drud_eofb(Cube cube)
370{
371 return index_drud(cube) / POW2TO11;
372}
373
374static uint64_t
375index_htr_drud(Cube cube)
376{
377 return index_cphtr(cube) * BINOM8ON4 +
378 (cube.eposs / FACTORIAL4) % BINOM8ON4;
379}
380
381static uint64_t
382index_htrfin(Cube cube)
383{
384 uint64_t epe, eps, epm, cp, ep;
385
386 epe = cube.epose % 24;
387 eps = cube.eposs % 24;
388 epm = cube.eposm % 24;
389 ep = (epe * 24 + eps) *24 + epm;
390 cp = index_cornershtrfin(cube);
391
392 return cp * 24 * 24 * 24 + ep;
393}
394
395/* Init functions implementation *********************************************/
396
397/*
398 * There is certainly a better way to do this, but for now I just use
399 * a "graph coloring" algorithm to compute the left cosets, and I compose
400 * with every possible cp to get the right cosets (it is possible that I am
401 * mixing up left and right).
402 *
403 * For doing it better "Mathematically", we need 3 things:
404 * - Checking that cp separates the orbits (UFR,UBL,DFL,DBR) and the other
405 * This is easy and it is done in the commented function cphtr_cp().
406 * - Check that there is no ep/cp parity
407 * - Check that we are not in the "3c" case; this is the part I don't
408 * know how to do.
409 */
410static void
411init_cphtr_cosets()
412{
413 unsigned int i;
414 int c = 0, d = 0;
415
416 for (i = 0; i < FACTORIAL8; i++) {
417 cphtr_left_cosets[i] = -1;
418 cphtr_right_cosets[i] = -1;
419 }
420
421 /* First we compute left cosets with a bfs */
422 for (i = 0; i < FACTORIAL8; i++)
423 if (cphtr_left_cosets[i] == -1)
424 init_cphtr_left_cosets_bfs(i, c++);
425
426 /* Then we compute right cosets using compose() */
427 for (i = 0; i < FACTORIAL8; i++)
428 if (cphtr_right_cosets[i] == -1)
429 init_cphtr_right_cosets_color(i, d++);
430}
431
432static void
433init_cphtr_left_cosets_bfs(int i, int c)
434{
435 int j, jj, next[FACTORIAL8], next2[FACTORIAL8], n, n2;
436
437 Move k;
438
439 n = 1;
440 next[0] = i;
441 cphtr_left_cosets[i] = c;
442
443 while (n != 0) {
444 for (j = 0, n2 = 0; j < n; j++) {
445 for (k = U2; k < B3; k++) {
446 if (!moveset_htr(k))
447 continue;
448 jj = apply_move(k, (Cube){ .cp = next[j] }).cp;
449
450 if (cphtr_left_cosets[jj] == -1) {
451 cphtr_left_cosets[jj] = c;
452 next2[n2++] = jj;
453 }
454 }
455 }
456
457 for (j = 0; j < n2; j++)
458 next[j] = next2[j];
459 n = n2;
460 }
461}
462
463static void
464init_cphtr_right_cosets_color(int i, int d)
465{
466 int cp;
467 unsigned int j;
468
469 cphtr_right_rep[d] = i;
470 for (j = 0; j < FACTORIAL8; j++) {
471 if (cphtr_left_cosets[j] == 0) {
472 cp = compose((Cube){.cp = i}, (Cube){.cp = j}).cp;
473 cphtr_right_cosets[cp] = d;
474 }
475 }
476}
477
478static void
479init_cornershtrfin()
480{
481 unsigned int i, j;
482 int n, c;
483 Move m;
484
485 for (i = 0; i < FACTORIAL8; i++)
486 cornershtrfin_ind[i] = -1;
487 cornershtrfin_ind[0] = 0;
488
489 /* 10-pass, I think 5 is enough, but just in case */
490 n = 1;
491 for (i = 0; i < 10; i++) {
492 for (j = 0; j < FACTORIAL8; j++) {
493 if (cornershtrfin_ind[j] == -1)
494 continue;
495 for (m = U; m < NMOVES; m++) {
496 if (moveset_htr(m)) {
497 c = apply_move(m, (Cube){.cp = j}).cp;
498 if (cornershtrfin_ind[c] == -1) {
499 cornershtrfin_ind[c] = n;
500 cornershtrfin_ant[n] = c;
501 n++;
502 }
503 }
504 }
505 }
506 }
507}
508
509void
510init_coord()
511{
512 static bool initialized = false;
513 if (initialized)
514 return;
515 initialized = true;
516
517 init_trans();
518
519 init_cphtr_cosets();
520 init_cornershtrfin();
521}
522

Generated with cgit - Back to sebastiano.tronto.net