aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--TODO.md47
-rwxr-xr-xnissybin327640 -> 327792 bytes
-rw-r--r--src/commands.c28
-rw-r--r--src/coord.c560
-rw-r--r--src/coord.h5
-rw-r--r--src/cube.c30
-rw-r--r--src/cube.h3
-rw-r--r--src/cubetypes.h7
-rw-r--r--src/pruning.c32
-rw-r--r--src/symcoord.c344
-rw-r--r--www/download/index.html4
12 files changed, 610 insertions, 451 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cd57588
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
nissy
diff --git a/TODO.md b/TODO.md
index ae09a01..4fe3a5d 100644
--- a/TODO.md
+++ b/TODO.md
@@ -5,24 +5,46 @@ It's more of a personal reminder than anything else.
5 5
6## For version 2.1 6## For version 2.1
7### Moving coordinates 7### Moving coordinates
8* Implement coord->move to apply moves directly on coordinates 8* general cleanup
9* add transformer to transform coordinate (optional, only for sym coordinates) 9### Changes to Step and Solve
10* For each coordinate, manually disallow "bad" moves, or just ignore the error 10* add a list of "helper" coordinates to every step
11 (probably better to check: low performance cost, detect problems that I might 11* Probably nicer: instead of passing a cube pass a structure "cube description"
12 be overlooking) 12 which can contain coordinates and one or more cubes.
13* remove selsims, do this directly inside transfinder 13 This can also be used to avoid using index_epud too much in drfin
14* change genptable where needed 14 (it is slow because it goes through cubearray).
15* Remove coord->cube (and edit README.md accordingly) 15* add a step->move(Cube) function, which may apply moves to the cube or just to
16* Remove sym_data->rep (but keep transtorep)? 16 the coordinates
17* Use this to improve solver: add 2 or 3 helper coordinates to optimal solver, 17* optimal solver: move the coordinates for the 3 orientations, but also the
18 to avoid transforming every time. We still need to transform when checking 18 cube so we can check the inverse
19 inverse scramble, though. 19### Tables management
20* Check files in tables directory, add command to remove old / extraneous files
21* Add checksum to check that tables are generated / downloaded correctly
20### Documentation 22### Documentation
23* Fix README.md with new coordinate system
21* Write an examples.md file 24* Write an examples.md file
22* More screenshots! 25* More screenshots!
23### More 26### More
24* Anything quick and easy from the sections below 27* Anything quick and easy from the sections below
25 28
29## Refactor
30### Coordinates
31* Text (README.md) description of coordinate system with 3 (or 4) types of
32 coordinates: basic (+ fundamental), sym, composite (consisting of at most
33 one sym + one or more basic)
34* Use this to restructure the coordinate part; maybe fundamental coordinates
35 do not need to exist???
36* Add also "transform" for every coordinate. For example, for EO and similar
37 only allow transformations that fix the EO axis.
38* Also: "basic" symcoord do not allow trans, composite coordinates assume
39 the transformation fixes the basic sumcoord
40* For each coordinate, manually disallow "bad" moves, or just ignore the error
41 (probably better to check: low performance cost, detect problems that I might
42 be overlooking)
43### Loading at startup vs dynamically
44* Consider moving more things to the initial loading phase (i.e. remove
45 many of the "initialized" parts)
46
47
26## Commands 48## Commands
27 49
28### Commands that are available in nissy 1.0, but not in this version (yet): 50### Commands that are available in nissy 1.0, but not in this version (yet):
@@ -34,6 +56,7 @@ including e.g. solutions that were not shown because -c)
34 56
35### More steps for `solve` 57### More steps for `solve`
36* QTM optimal solving 58* QTM optimal solving
59* 5-side solve (for robots)
37* Block-building steps (cross, roux blocks, ...) 60* Block-building steps (cross, roux blocks, ...)
38* Other common steps (LSE, ...) 61* Other common steps (LSE, ...)
39 62
diff --git a/nissy b/nissy
index a92453e..ac2e2c0 100755
--- a/nissy
+++ b/nissy
Binary files differ
diff --git a/src/commands.c b/src/commands.c
index e704d7a..ed3d46a 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -410,9 +410,11 @@ static void
410scramble_exec(CommandArgs *args) 410scramble_exec(CommandArgs *args)
411{ 411{
412 Cube cube; 412 Cube cube;
413 CubeArray *arr;
413 Alg *scr, *ruf, *aux; 414 Alg *scr, *ruf, *aux;
414 int i, j, eo, ep, co, cp, a[12]; 415 int i, j, eo, ep, co, cp, a[12];
415 uint64_t ui, uj; 416 int eparr[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 };
417 uint64_t ui, uj, uk;
416 418
417 init_all_movesets(); 419 init_all_movesets();
418 init_symcoord(); 420 init_symcoord();
@@ -429,17 +431,29 @@ scramble_exec(CommandArgs *args)
429 * Moreover we again need to fix parity after * 431 * Moreover we again need to fix parity after *
430 * generating epose manually */ 432 * generating epose manually */
431 do { 433 do {
432 ui = rand() % coord_drudfin_noE_sym16.max; 434 ui = rand() % FACTORIAL8;
433 uj = rand() % FACTORIAL4; 435 uj = rand() % FACTORIAL8;
434 cube = coord_drudfin_noE_sym16.cube(ui); 436 uk = rand() % FACTORIAL4;
435 cube.epose += uj; 437
438 index_to_perm(ui, 12, a);
439 arr = malloc(sizeof(CubeArray));
440 arr->ep = eparr;
441 cube = arrays_to_cube(arr, pf_ep);
442 free(arr);
443
444 cube.cp = uj;
445 cube.epose += uk;
436 } while (!is_admissible(cube)); 446 } while (!is_admissible(cube));
437 } else if (!strcmp(args->scrtype, "htr")) { 447 } else if (!strcmp(args->scrtype, "htr")) {
438 /* antindex_htrfin() returns a consistent * 448 /* antindex_htrfin() returns a consistent *
439 * cube, except possibly for parity */ 449 * cube, except possibly for parity */
440 do { 450 do {
441 ui = rand() % coord_htrfin.max; 451 ui = rand() % (24*24/6);
442 cube = coord_htrfin.cube(ui); 452 cube = (Cube){0};
453 cube.cp = cornershtrfin_ant[ui];
454 cube.epose = rand() % 24;
455 cube.eposs = rand() % 24;
456 cube.eposm = rand() % 24;
443 } while (!is_admissible(cube)); 457 } while (!is_admissible(cube));
444 } else { 458 } else {
445 eo = rand() % POW2TO11; 459 eo = rand() % POW2TO11;
diff --git a/src/coord.c b/src/coord.c
index 3bbda22..abfa1b9 100644
--- a/src/coord.c
+++ b/src/coord.c
@@ -1,20 +1,5 @@
1#include "coord.h" 1#include "coord.h"
2 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);
16static Cube antindex_cpud_separate(uint64_t ind);
17
18static uint64_t index_eofb(Cube cube); 3static uint64_t index_eofb(Cube cube);
19static uint64_t index_eofbepos(Cube cube); 4static uint64_t index_eofbepos(Cube cube);
20static uint64_t index_epud(Cube cube); 5static uint64_t index_epud(Cube cube);
@@ -30,10 +15,27 @@ static uint64_t index_htr_drud(Cube cube);
30static uint64_t index_htrfin(Cube cube); 15static uint64_t index_htrfin(Cube cube);
31static uint64_t index_cpud_separate(Cube cube); 16static uint64_t index_cpud_separate(Cube cube);
32 17
18static uint64_t move_eofb(Move m, uint64_t ind);
19static uint64_t move_eofbepos(Move m, uint64_t ind);
20static uint64_t move_epud(Move m, uint64_t ind);
21static uint64_t move_coud(Move m, uint64_t ind);
22static uint64_t move_corners(Move m, uint64_t ind);
23static uint64_t move_cp(Move m, uint64_t ind);
24static uint64_t move_cphtr(Move m, uint64_t ind);
25static uint64_t move_cornershtr(Move m, uint64_t ind);
26static uint64_t move_cornershtrfin(Move m, uint64_t ind);
27static uint64_t move_drud(Move m, uint64_t ind);
28static uint64_t move_drud_eofb(Move m, uint64_t ind);
29static uint64_t move_htr_drud(Move m, uint64_t ind);
30static uint64_t move_htrfin(Move m, uint64_t ind);
31static uint64_t move_cpud_separate(Move m, uint64_t ind);
32
33static void init_cphtr_cosets(); 33static void init_cphtr_cosets();
34static void init_cphtr_left_cosets_bfs(int i, int c); 34static void init_cphtr_left_cosets_bfs(int i, int c);
35static void init_cphtr_right_cosets_color(int i, int c); 35static void init_cphtr_right_cosets_color(int i, int c);
36static void init_cpud_separate();
36static void init_cornershtrfin(); 37static void init_cornershtrfin();
38static void init_htr_eposs();
37 39
38 40
39/* All sorts of useful costants and tables **********************************/ 41/* All sorts of useful costants and tables **********************************/
@@ -41,497 +43,408 @@ static void init_cornershtrfin();
41static int cphtr_left_cosets[FACTORIAL8]; 43static int cphtr_left_cosets[FACTORIAL8];
42static int cphtr_right_cosets[FACTORIAL8]; 44static int cphtr_right_cosets[FACTORIAL8];
43static int cphtr_right_rep[BINOM8ON4*6]; 45static int cphtr_right_rep[BINOM8ON4*6];
46int cpud_separate_ind[FACTORIAL8];
47int cpud_separate_ant[BINOM8ON4];
44static int cornershtrfin_ind[FACTORIAL8]; 48static int cornershtrfin_ind[FACTORIAL8];
45static int cornershtrfin_ant[24*24/6]; 49int cornershtrfin_ant[24*24/6];
50static int htr_eposs_ind[BINOM12ON4];
51static int htr_eposs_ant[BINOM8ON4];
46 52
47/* Coordinates and their implementation **************************************/ 53/* Coordinates and their implementation **************************************/
48 54
49Coordinate 55Coordinate
50coord_eofb = { 56coord_eofb = {
51 .index = index_eofb, 57 .index = index_eofb,
52 .cube = antindex_eofb,
53 .max = POW2TO11, 58 .max = POW2TO11,
59 .move = move_eofb,
54}; 60};
55 61
56Coordinate 62Coordinate
57coord_eofbepos = { 63coord_eofbepos = {
58 .index = index_eofbepos, 64 .index = index_eofbepos,
59 .cube = antindex_eofbepos,
60 .max = POW2TO11 * BINOM12ON4, 65 .max = POW2TO11 * BINOM12ON4,
66 .move = move_eofbepos,
61}; 67};
62 68
63Coordinate 69Coordinate
64coord_coud = { 70coord_coud = {
65 .index = index_coud, 71 .index = index_coud,
66 .cube = antindex_coud,
67 .max = POW3TO7, 72 .max = POW3TO7,
73 .move = move_coud,
68}; 74};
69 75
70Coordinate 76Coordinate
71coord_corners = { 77coord_corners = {
72 .index = index_corners, 78 .index = index_corners,
73 .cube = antindex_corners,
74 .max = POW3TO7 * FACTORIAL8, 79 .max = POW3TO7 * FACTORIAL8,
80 .move = move_corners,
75}; 81};
76 82
77Coordinate 83Coordinate
78coord_cp = { 84coord_cp = {
79 .index = index_cp, 85 .index = index_cp,
80 .cube = antindex_cp,
81 .max = FACTORIAL8, 86 .max = FACTORIAL8,
87 .move = move_cp,
82}; 88};
83 89
84Coordinate 90Coordinate
85coord_cphtr = { 91coord_cphtr = {
86 .index = index_cphtr, 92 .index = index_cphtr,
87 .cube = antindex_cphtr,
88 .max = BINOM8ON4 * 6, 93 .max = BINOM8ON4 * 6,
94 .move = move_cphtr,
89}; 95};
90 96
91Coordinate 97Coordinate
92coord_cornershtr = { 98coord_cornershtr = {
93 .index = index_cornershtr, 99 .index = index_cornershtr,
94 .cube = antindex_cornershtr,
95 .max = POW3TO7 * BINOM8ON4 * 6, 100 .max = POW3TO7 * BINOM8ON4 * 6,
101 .move = move_cornershtr,
96}; 102};
97 103
98Coordinate 104Coordinate
99coord_cornershtrfin = { 105coord_cornershtrfin = {
100 .index = index_cornershtrfin, 106 .index = index_cornershtrfin,
101 .cube = antindex_cornershtrfin,
102 .max = 24*24/6, 107 .max = 24*24/6,
108 .move = move_cornershtrfin,
103}; 109};
104 110
105Coordinate 111Coordinate
106coord_epud = { 112coord_epud = {
107 .index = index_epud, 113 .index = index_epud,
108 .cube = antindex_epud,
109 .max = FACTORIAL8, 114 .max = FACTORIAL8,
115 .move = move_epud,
110}; 116};
111 117
112Coordinate 118Coordinate
113coord_drud = { 119coord_drud = {
114 .index = index_drud, 120 .index = index_drud,
115 .cube = antindex_drud,
116 .max = POW2TO11 * POW3TO7 * BINOM12ON4, 121 .max = POW2TO11 * POW3TO7 * BINOM12ON4,
122 .move = move_drud,
117}; 123};
118 124
119Coordinate 125Coordinate
120coord_htr_drud = { 126coord_htr_drud = {
121 .index = index_htr_drud, 127 .index = index_htr_drud,
122 .cube = antindex_htr_drud,
123 .max = BINOM8ON4 * 6 * BINOM8ON4, 128 .max = BINOM8ON4 * 6 * BINOM8ON4,
129 .move = move_htr_drud,
124}; 130};
125 131
126Coordinate 132Coordinate
127coord_htrfin = { 133coord_htrfin = {
128 .index = index_htrfin, 134 .index = index_htrfin,
129 .cube = antindex_htrfin,
130 .max = 24 * 24 * 24 *24 * 24 / 6, /* should be /12 but it's ok */ 135 .max = 24 * 24 * 24 *24 * 24 / 6, /* should be /12 but it's ok */
136 .move = move_htrfin,
131}; 137};
132 138
133Coordinate 139Coordinate
134coord_drud_eofb = { 140coord_drud_eofb = {
135 .index = index_drud_eofb, 141 .index = index_drud_eofb,
136 .cube = antindex_drud_eofb,
137 .max = POW3TO7 * BINOM12ON4, 142 .max = POW3TO7 * BINOM12ON4,
143 .move = move_drud_eofb,
138}; 144};
139 145
140Coordinate 146Coordinate
141coord_cpud_separate = { 147coord_cpud_separate = {
142 .index = index_cpud_separate, 148 .index = index_cpud_separate,
143 .cube = antindex_cpud_separate,
144 .max = BINOM8ON4, 149 .max = BINOM8ON4,
150 .move = move_cpud_separate,
145}; 151};
146 152
147/* Antindexers ***************************************************************/ 153/* Indexers ******************************************************************/
148 154
149static Cube 155static uint64_t
150antindex_eofb(uint64_t ind) 156index_eofb(Cube cube)
151{ 157{
152 /* The returned cube is consistent */ 158 return cube.eofb;
153 Cube ret = {0};
154
155 ret.eofb = ind;
156 ret.eorl = ind;
157 ret.eoud = ind;
158
159 return ret;
160} 159}
161 160
162static Cube 161static uint64_t
163antindex_eofbepos(uint64_t ind) 162index_eofbepos(Cube cube)
164{ 163{
165 /* The returned cube is NOT consistent: eoud can be wrong */ 164 return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb;
166 Cube ret = {0}; 165}
167
168 /* We need eorl for sym16 coordinate */
169 static int initialized = false;
170 static uint64_t eorl_a[POW2TO11][BINOM12ON4];
171 static int eo_aux[12], ep_aux[12];
172 unsigned int i, j, k;
173
174 if (!initialized) {
175 for (i = 0; i < POW2TO11; i++) {
176 for (j = 0; j < BINOM12ON4; j++) {
177 int_to_sum_zero_array(i, 2, 12, eo_aux);
178 index_to_subset(j, 12, 4, ep_aux);
179 for (k = 0; k < 12; k++)
180 if ((ep_aux[k] && k < FR) ||
181 (!ep_aux[k] && k >= FR))
182 eo_aux[k] = 1 - eo_aux[k];
183 eorl_a[i][j] = digit_array_to_int(eo_aux,11,2);
184 }
185 }
186 166
187 initialized = true; 167static uint64_t
188 } 168index_epud(Cube cube)
169{
170 uint64_t ret;
171 CubeArray *arr = new_cubearray(cube, pf_ep);
189 172
190 ret.eofb = ind % POW2TO11; 173 ret = perm_to_index(arr->ep, 8);
191 ret.epose = (ind / POW2TO11) * 24; 174 free_cubearray(arr, pf_ep);
192 ret.eorl = eorl_a[ret.eofb][ret.epose/24];
193 175
194 return ret; 176 return ret;
195} 177}
196 178
197static Cube 179static uint64_t
198antindex_epud(uint64_t ind) 180index_coud(Cube cube)
199{ 181{
200 /* The returned cube is consistent */ 182 return cube.coud;
201 static bool initialized = false;
202 static Cube epud_aux[FACTORIAL8];
203 int a[12];
204 uint64_t ui;
205 CubeArray arr;
206
207 if (!initialized) {
208 a[FR] = FR;
209 a[FL] = FL;
210 a[BL] = BL;
211 a[BR] = BR;
212 for (ui = 0; ui < FACTORIAL8; ui++) {
213 index_to_perm(ui, 8, a);
214 arr.ep = a;
215 epud_aux[ui] = arrays_to_cube(&arr, pf_ep);
216 }
217
218 initialized = true;
219 }
220
221 return epud_aux[ind];
222} 183}
223 184
224static Cube 185static uint64_t
225antindex_coud(uint64_t ind) 186index_corners(Cube cube)
226{ 187{
227 /* The returned cube is consistent */ 188 return cube.coud * FACTORIAL8 + cube.cp;
228 Cube ret = {0};
229
230 ret.coud = ind;
231 ret.corl = ind;
232 ret.cofb = ind;
233
234 return ret;
235} 189}
236 190
237static Cube 191static uint64_t
238antindex_corners(uint64_t ind) 192index_cp(Cube cube)
239{ 193{
240 /* The returned cube is NOT consistent: corl and cofb can be wrong */ 194 return cube.cp;
241 /* TODO: remember to make this consistent if I use this for symcoord */
242 Cube ret = {0};
243
244 ret.coud = ind / FACTORIAL8;
245 ret.cp = ind % FACTORIAL8;
246
247 return ret;
248} 195}
249 196
250static Cube 197static uint64_t
251antindex_cp(uint64_t ind) 198index_cphtr(Cube cube)
252{ 199{
253 /* The returned cube is NOT consistent: co can be wrong in all axes */ 200 return cphtr_right_cosets[cube.cp];
254 Cube ret = {0}; 201}
255 202
256 ret.cp = ind; 203static uint64_t
204index_cornershtr(Cube cube)
205{
206 return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube);
207}
257 208
258 return ret; 209static uint64_t
210index_cornershtrfin(Cube cube)
211{
212 return cornershtrfin_ind[cube.cp];
259} 213}
260 214
261static Cube 215static uint64_t
262antindex_cphtr(uint64_t ind) 216index_drud(Cube cube)
263{ 217{
264 /* The returned cube is NOT consistent: co can be wrong in all axes */ 218 uint64_t a, b, c;
265 Cube ret = {0};
266 219
267 ret.cp = cphtr_right_rep[ind]; 220 a = cube.eofb;
221 b = cube.coud;
222 c = cube.epose / FACTORIAL4;
268 223
269 return ret; 224 b *= POW2TO11;
225 c *= POW2TO11 * POW3TO7;
226
227 return a + b + c;
270} 228}
271 229
272static Cube 230static uint64_t
273antindex_cornershtr(uint64_t ind) 231index_drud_eofb(Cube cube)
274{ 232{
275 /* The returned cube is NOT consistent: corl and cofb can be wrong */ 233 return index_drud(cube) / POW2TO11;
276 Cube ret = antindex_cphtr(ind % (BINOM8ON4 * 6));
277
278 ret.coud = ind / (BINOM8ON4 * 6);
279
280 return ret;
281} 234}
282 235
283static Cube 236static uint64_t
284antindex_cornershtrfin(uint64_t ind) 237index_htr_drud(Cube cube)
285{ 238{
286 /* The returned cube is consistent */ 239 uint64_t a, b;
287 Cube ret = {0};
288 240
289 ret.cp = cornershtrfin_ant[ind]; 241 a = index_cphtr(cube);
242 b = htr_eposs_ind[cube.eposs/24];
290 243
291 return ret; 244 return a * BINOM8ON4 + b;
292} 245}
293 246
294static Cube 247static uint64_t
295antindex_drud(uint64_t ind) 248index_htrfin(Cube cube)
296{ 249{
297 /* The returned cube is NOT consistent in the same way as eofbepos */ 250 uint64_t epe, eps, epm, cp, ep;
298 /* (see above). It works with sym16 coordinates */
299 uint64_t epos, eofb;
300 Cube ret = {0};
301
302 eofb = ind % POW2TO11;
303 epos = ind / (POW2TO11 * POW3TO7);
304 ret = antindex_eofbepos(eofb + POW2TO11 * epos);
305 251
306 ret.coud = (ind / POW2TO11) % POW3TO7; 252 epe = cube.epose % 24;
307 ret.corl = ret.coud; 253 eps = cube.eposs % 24;
308 ret.cofb = ret.coud; 254 epm = cube.eposm % 24;
255 ep = (epe * 24 + eps) *24 + epm;
256 cp = index_cornershtrfin(cube);
309 257
310 return ret; 258 return cp * 24 * 24 * 24 + ep;
311} 259}
312 260
313static Cube 261static uint64_t
314antindex_drud_eofb(uint64_t ind) 262index_cpud_separate(Cube cube)
315{ 263{
316 /* The returned cube is NOT consistent (see antindex_drud) */ 264 return cpud_separate_ind[cube.cp];
317 return antindex_drud(ind * POW2TO11);
318} 265}
319 266
320static Cube 267/* Coordinate movers *********************************************************/
321antindex_htr_drud(uint64_t ind)
322{
323 /* The returned cube is NOT consistent: corl and cofb can be wrong */
324 /* (see cphtr) and eposm can be wrong too (not epose because dr). */
325 Cube ret = {0};
326 static bool initialized = false;
327 static int aux[BINOM8ON4], ep[12], ep2[12];
328 static int eps_solved[4] = {UL, UR, DL, DR};
329 unsigned int i, j, k;
330 268
331 if (!initialized) { 269static uint64_t
332 for (i = 0; i < BINOM8ON4; i++) { 270move_eofb(Move m, uint64_t ind)
333 for (j = 0; j < 12; j++) 271{
334 ep[j] = ep2[j] = 0; 272 return eofb_mtable[m][ind];
335 index_to_subset(i, 8, 4, ep);
336 for (j = 0, k = 0; j < 8; j++)
337 ep2[j] = ep[j/2+4*(j%2)] ? eps_solved[k++] : 0;
338 aux[i] = array_ep_to_epos(ep2, eps_solved);
339 }
340
341 initialized = true;
342 }
343
344 ret = antindex_cphtr(ind / BINOM8ON4);
345 ret.epose = 0;
346 ret.eposs = aux[ind % BINOM8ON4];
347
348 return ret;
349} 273}
350 274
351static Cube 275static uint64_t
352antindex_htrfin(uint64_t ind) 276move_eofbepos(Move m, uint64_t ind)
353{ 277{
354 /* The returned cube is consistent */ 278 uint64_t a, b;
355 Cube ret = {0};
356
357 ret = antindex_cornershtrfin(ind/(24*24*24));
358 279
359 ret.eposm = ind % 24; 280 a = epose_mtable[m][(ind / POW2TO11)*24];
360 ind /= 24; 281 b = eofb_mtable[m][ind % POW2TO11];
361 ret.eposs = ind % 24;
362 ind /= 24;
363 ret.epose = ind % 24;
364 282
365 return ret; 283 return a/24 + b;
366} 284}
367 285
368static Cube 286static uint64_t
369antindex_cpud_separate(uint64_t ind) 287move_epud(Move m, uint64_t ind)
370{ 288{
371 /* Not consistent because of side corner orientations and cp */ 289 /* TODO: save to file? */
372 unsigned int ui;
373 int i, co[8], cp[8];
374 Corner u, d;
375
376 static Cube aux[BINOM8ON4];
377 static bool initialized = false; 290 static bool initialized = false;
291 static int a[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 };
292 static int shortlist[NMOVES] = {
293 [U] = 0, [U2] = 1, [U3] = 2, [D] = 3, [D2] = 4, [D3] = 5,
294 [R2] = 6, [L2] = 7, [F2] = 8, [B2] = 9
295 };
296 static uint64_t aux[10][FACTORIAL8];
297 uint64_t ui;
298 int j;
299 Move mj;
300 Cube c;
301 CubeArray *arr, *auxarr;
302
303 if (!moveset_drud.allowed(m)) {
304 fprintf(stderr, "Move not allowed for epud\n"
305 "This is a bug, please report\n");
306 return coord_epud.max;
307 }
378 308
379 if (!initialized) { 309 if (!initialized) {
380 for (ui = 0; ui < BINOM8ON4; ui++) { 310 auxarr = malloc(sizeof(CubeArray));
381 index_to_subset(ui, 8, 4, co); 311 auxarr->ep = a;
382 for (i = 0, u = UFR, d = DFR; i < 8; i++) 312 for (ui = 0; ui < coord_epud.max; ui++) {
383 cp[i] = co[i] ? d++ : u++; 313 index_to_perm(ui, 8, a);
384 aux[ui] = (Cube){.cp = perm_to_index(cp, 8)}; 314 c = arrays_to_cube(auxarr, pf_ep);
315 for (j = 0; moveset_drud.sorted_moves[j] != NULLMOVE;
316 j++) {
317 mj = moveset_drud.sorted_moves[j];
318 arr = new_cubearray(apply_move(mj, c), pf_ep);
319 aux[shortlist[mj]][ui] =
320 perm_to_index(arr->ep, 8);
321 free_cubearray(arr, pf_ep);
322 }
385 } 323 }
324 free(auxarr);
386 325
387 initialized = true; 326 initialized = true;
388 } 327 }
389 328
390 return aux[ind]; 329 return aux[shortlist[m]][ind];
391}
392
393/* Indexers ******************************************************************/
394
395static uint64_t
396index_eofb(Cube cube)
397{
398 return cube.eofb;
399} 330}
400 331
401static uint64_t 332static uint64_t
402index_eofbepos(Cube cube) 333move_coud(Move m, uint64_t ind)
403{ 334{
404 return (cube.epose / FACTORIAL4) * POW2TO11 + cube.eofb; 335 return coud_mtable[m][ind];
405} 336}
406 337
407static uint64_t 338static uint64_t
408index_epud(Cube cube) 339move_corners(Move m, uint64_t ind)
409{ 340{
410 uint64_t ret; 341 uint64_t a, b;
411 CubeArray *arr = new_cubearray(cube, pf_ep);
412 342
413 ret = perm_to_index(arr->ep, 8); 343 a = coud_mtable[m][ind / FACTORIAL8];
414 free_cubearray(arr, pf_ep); 344 b = cp_mtable[m][ind % FACTORIAL8];
415 345
416 return ret; 346 return a * FACTORIAL8 + b;
417} 347}
418 348
419static uint64_t 349static uint64_t
420index_coud(Cube cube) 350move_cp(Move m, uint64_t ind)
421{ 351{
422 return cube.coud; 352 return cp_mtable[m][ind];
423} 353}
424 354
425static uint64_t 355static uint64_t
426index_corners(Cube cube) 356move_cphtr(Move m, uint64_t ind)
427{ 357{
428 return cube.coud * FACTORIAL8 + cube.cp; 358 static bool initialized = false;
429} 359 static uint64_t aux[NMOVES][BINOM8ON4*6];
360 uint64_t ui;
361 Move j;
430 362
431static uint64_t 363 if (!initialized) {
432index_cp(Cube cube) 364 for (ui = 0; ui < BINOM8ON4*6; ui++)
433{ 365 for (j = U; j < NMOVES; j++)
434 return cube.cp; 366 aux[j][ui] =
435} 367 cp_mtable[j][cphtr_right_rep[ind]];
436 368
437static uint64_t 369 initialized = true;
438index_cphtr(Cube cube) 370 }
439{ 371
440 return cphtr_right_cosets[cube.cp]; 372 return aux[m][ind];
441} 373}
442 374
443static uint64_t 375static uint64_t
444index_cornershtr(Cube cube) 376move_cornershtr(Move m, uint64_t ind)
445{ 377{
446 return cube.coud * BINOM8ON4 * 6 + index_cphtr(cube); 378 uint64_t a, b;
379
380 a = coud_mtable[m][ind/(BINOM8ON4 * 6)];
381 b = move_cphtr(m, ind % (BINOM8ON4 * 6));
382
383 return a * BINOM8ON4 * 6 + b;
447} 384}
448 385
449static uint64_t 386static uint64_t
450index_cornershtrfin(Cube cube) 387move_cornershtrfin(Move m, uint64_t ind)
451{ 388{
452 return cornershtrfin_ind[cube.cp]; 389 int a;
390
391 a = cp_mtable[m][cornershtrfin_ant[ind]];
392
393 return cornershtrfin_ind[a];
453} 394}
454 395
455static uint64_t 396static uint64_t
456index_drud(Cube cube) 397move_drud(Move m, uint64_t ind)
457{ 398{
458 uint64_t a, b, c; 399 uint64_t a, b, c;
459 400
460 a = cube.eofb; 401 a = eofb_mtable[m][ind % POW2TO11];
461 b = cube.coud; 402 b = coud_mtable[m][(ind / POW2TO11) % POW3TO7];
462 c = cube.epose / FACTORIAL4; 403 c = epose_mtable[m][ind / (POW2TO11 * POW3TO7)];
463
464 b *= POW2TO11;
465 c *= POW2TO11 * POW3TO7;
466 404
467 return a + b + c; 405 return a + (b + c * POW3TO7) * POW2TO11;
468} 406}
469 407
470static uint64_t 408static uint64_t
471index_drud_eofb(Cube cube) 409move_drud_eofb(Move m, uint64_t ind)
472{ 410{
473 return index_drud(cube) / POW2TO11; 411 uint64_t a, b;
412
413 a = coud_mtable[m][ind % POW3TO7];
414 b = epose_mtable[m][ind / POW3TO7];
415
416 return a + b * POW3TO7;
474} 417}
475 418
476static uint64_t 419static uint64_t
477index_htr_drud(Cube cube) 420move_htr_drud(Move m, uint64_t ind)
478{ 421{
479 static bool initialized = false; 422 uint64_t a, b;
480 static int aux[BINOM12ON4], ep[12], ep2[12];
481 static int eps_solved[4] = {UL, UR, DL, DR};
482 unsigned int i, j;
483 423
484 if (!initialized) { 424 a = move_cphtr(m, ind/BINOM8ON4);
485 for (i = 0; i < BINOM12ON4; i++) { 425 b = eposs_mtable[m][htr_eposs_ant[ind%BINOM8ON4]];
486 for (j = 0; j < 12; j++)
487 ep[j] = ep2[j] = 0;
488 epos_to_partial_ep(i*24, ep, eps_solved);
489 for (j = 0; j < 8; j++)
490 ep2[j/2 + 4*(j%2)] = ep[j] ? 1 : 0;
491 aux[i] = subset_to_index(ep2, 8, 4);
492 }
493 426
494 initialized = true; 427 return a*BINOM8ON4 + htr_eposs_ind[b/24];
495 }
496
497 return index_cphtr(cube) * BINOM8ON4 + aux[cube.eposs/24];
498} 428}
499 429
500static uint64_t 430static uint64_t
501index_htrfin(Cube cube) 431move_htrfin(Move m, uint64_t ind)
502{ 432{
503 uint64_t epe, eps, epm, cp, ep; 433 uint64_t a, b, bm, bs, be;
504 434
505 epe = cube.epose % 24; 435 a = move_cornershtrfin(m, ind % (24*24*24));
506 eps = cube.eposs % 24; 436 bm = eposm_mtable[m][ind%24] % 24;
507 epm = cube.eposm % 24; 437 bs = eposs_mtable[m][(ind/24)%24] % 24;
508 ep = (epe * 24 + eps) *24 + epm; 438 be = epose_mtable[m][ind/(24*24)] % 24;
509 cp = index_cornershtrfin(cube); 439 b = (be * 24 + bs) * 24 + bm;
510 440
511 return cp * 24 * 24 * 24 + ep; 441 return a * (24*24*24) + b;
512} 442}
513 443
514static uint64_t 444static uint64_t
515index_cpud_separate(Cube cube) 445move_cpud_separate(Move m, uint64_t ind)
516{ 446{
517 unsigned int ui; 447 return cpud_separate_ind[cp_mtable[m][cpud_separate_ant[ind]]];
518 int i, co[8];
519
520 static int aux[FACTORIAL8];
521 static bool initialized = false;
522
523 if (!initialized) {
524 for (ui = 0; ui < FACTORIAL8; ui++) {
525 for (i = 0; i < 8; i++)
526 co[i] = what_corner_at((Cube){.cp=ui},i)>UBR ?
527 1 : 0;
528 aux[ui] = subset_to_index(co, 8, 4);
529 }
530
531 initialized = true;
532 }
533
534 return aux[cube.cp];
535} 448}
536 449
537/* Init functions implementation *********************************************/ 450/* Init functions implementation *********************************************/
@@ -618,6 +531,20 @@ init_cphtr_right_cosets_color(int i, int d)
618} 531}
619 532
620static void 533static void
534init_cpud_separate()
535{
536 unsigned int ui;
537 int i, co[8];
538
539 for (ui = 0; ui < FACTORIAL8; ui++) {
540 for (i = 0; i < 8; i++)
541 co[i] = what_corner_at((Cube){.cp=ui},i)>UBR ? 1 : 0;
542 cpud_separate_ind[ui] = subset_to_index(co, 8, 4);
543 cpud_separate_ant[cpud_separate_ind[ui]] = ui;
544 }
545}
546
547static void
621init_cornershtrfin() 548init_cornershtrfin()
622{ 549{
623 unsigned int i, j; 550 unsigned int i, j;
@@ -649,28 +576,21 @@ init_cornershtrfin()
649} 576}
650 577
651void 578void
652test_coord(Coordinate *coord) 579init_htr_eposs()
653{ 580{
654 bool passed; 581 int ep[12], ep2[12];
655 uint64_t ui, failcount; 582 int eps_solved[4] = {UL, UR, DL, DR};
656 583 unsigned int i, j;
657 if (!(passed = (coord->index((Cube){0}) == 0))) {
658 printf("Failed: coordinate of solved cube is "
659 "%" PRIu64 "\n", coord->index((Cube){0}));
660 }
661 584
662 printf("Testing %" PRIu64 " coordinates\n", coord->max); 585 for (i = 0; i < BINOM12ON4; i++) {
663 for (failcount = 0, ui = 0; ui < coord->max; ui++) { 586 for (j = 0; j < 12; j++)
664 if (!(passed = (coord->index(coord->cube(ui)) == ui))) { 587 ep[j] = ep2[j] = 0;
665 printf("Failed at %" PRIu64 "\n", ui); 588 epos_to_partial_ep(i*24, ep, eps_solved);
666 failcount++; 589 for (j = 0; j < 8; j++)
667 } 590 ep2[j/2 + 4*(j%2)] = ep[j] ? 1 : 0;
591 htr_eposs_ind[i] = subset_to_index(ep2, 8, 4);
592 htr_eposs_ant[htr_eposs_ind[i]] = i*24;
668 } 593 }
669
670 if (passed)
671 printf("Ok\n");
672 else
673 printf("Test failed in %" PRIu64 " cases\n", failcount);
674} 594}
675 595
676void 596void
@@ -685,5 +605,7 @@ init_coord()
685 605
686 init_cphtr_cosets(); 606 init_cphtr_cosets();
687 init_cornershtrfin(); 607 init_cornershtrfin();
608 init_htr_eposs();
609 init_cpud_separate();
688} 610}
689 611
diff --git a/src/coord.h b/src/coord.h
index 81e5866..61398a4 100644
--- a/src/coord.h
+++ b/src/coord.h
@@ -18,7 +18,10 @@ extern Coordinate coord_htr_drud;
18extern Coordinate coord_htrfin; 18extern Coordinate coord_htrfin;
19extern Coordinate coord_cpud_separate; 19extern Coordinate coord_cpud_separate;
20 20
21void test_coord(Coordinate *coord); 21extern int cpud_separate_ant[BINOM8ON4];
22extern int cpud_separate_ind[FACTORIAL8];
23extern int cornershtrfin_ant[24*24/6];
24
22void init_coord(); 25void init_coord();
23 26
24#endif 27#endif
diff --git a/src/cube.c b/src/cube.c
index 0ed862f..aae3a6e 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -2,8 +2,6 @@
2 2
3/* Local functions ***********************************************************/ 3/* Local functions ***********************************************************/
4 4
5static void fix_eorleoud(CubeArray *arr);
6static void fix_cofbcorl(CubeArray *arr);
7static void init_inverse(); 5static void init_inverse();
8static bool read_invtables_file(); 6static bool read_invtables_file();
9static bool write_invtables_file(); 7static bool write_invtables_file();
@@ -126,6 +124,30 @@ cube_to_arrays(Cube cube, CubeArray *arr, PieceFilter f)
126} 124}
127 125
128void 126void
127epos_to_compatible_ep(int epos, int *ep, int *ss)
128{
129 int i, j, k, other[8];
130 bool flag;
131
132 for (i = 0; i < 12; i++)
133 ep[i] = -1;
134
135 epos_to_partial_ep(epos, ep, ss);
136
137 for (i = 0, j = 0; i < 12; i++) {
138 flag = false;
139 for (k = 0; k < 4; k++)
140 flag = flag || (i == ss[k]);
141 if (!flag)
142 other[j++] = i;
143 }
144
145 for (i = 0, j = 0; i < 12; i++)
146 if (ep[i] == -1)
147 ep[i] = other[j++];
148}
149
150void
129epos_to_partial_ep(int epos, int *ep, int *ss) 151epos_to_partial_ep(int epos, int *ep, int *ss)
130{ 152{
131 int i, is, eposs[12], eps[4]; 153 int i, is, eposs[12], eps[4];
@@ -141,7 +163,7 @@ epos_to_partial_ep(int epos, int *ep, int *ss)
141 ep[i] = ss[eps[is++]]; 163 ep[i] = ss[eps[is++]];
142} 164}
143 165
144static void 166void
145fix_eorleoud(CubeArray *arr) 167fix_eorleoud(CubeArray *arr)
146{ 168{
147 int i; 169 int i;
@@ -163,7 +185,7 @@ fix_eorleoud(CubeArray *arr)
163 } 185 }
164} 186}
165 187
166static void 188void
167fix_cofbcorl(CubeArray *arr) 189fix_cofbcorl(CubeArray *arr)
168{ 190{
169 int i; 191 int i;
diff --git a/src/cube.h b/src/cube.h
index 8e04839..483a89a 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -23,6 +23,9 @@ bool is_solved_center(Cube cube, Center c);
23bool is_solved_corner(Cube cube, Corner c); 23bool is_solved_corner(Cube cube, Corner c);
24bool is_solved_edge(Cube cube, Edge e); 24bool is_solved_edge(Cube cube, Edge e);
25void epos_to_partial_ep(int epos, int *ep, int *ss); 25void epos_to_partial_ep(int epos, int *ep, int *ss);
26void epos_to_compatible_ep(int epos, int *ep, int *ss);
27void fix_eorleoud(CubeArray *arr);
28void fix_cofbcorl(CubeArray *arr);
26Cube fourval_to_cube(int eofb, int ep, int coud, int cp); 29Cube fourval_to_cube(int eofb, int ep, int coud, int cp);
27void free_cubearray(CubeArray *arr, PieceFilter f); 30void free_cubearray(CubeArray *arr, PieceFilter f);
28Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf); 31Cube move_via_arrays(CubeArray *arr, Cube c, PieceFilter pf);
diff --git a/src/cubetypes.h b/src/cubetypes.h
index 518c727..3ba667c 100644
--- a/src/cubetypes.h
+++ b/src/cubetypes.h
@@ -168,11 +168,10 @@ struct
168coordinate 168coordinate
169{ 169{
170 Indexer index; 170 Indexer index;
171 AntiIndexer cube;
172 uint64_t max; 171 uint64_t max;
173 TransFinder transfind;
174 CoordMover move; 172 CoordMover move;
175 CoordTransformer transform; 173 CoordTransformer transform;
174 SymData * sd;
176}; 175};
177 176
178struct 177struct
@@ -324,8 +323,10 @@ symdata
324 int ntrans; 323 int ntrans;
325 Trans * trans; 324 Trans * trans;
326 uint64_t * class; 325 uint64_t * class;
327 Cube * rep; 326 uint64_t * unsym;
328 Trans * transtorep; 327 Trans * transtorep;
328 uint64_t * selfsim;
329 CoordTransformer transform; /* TODO: remove, use that of base coord */
329}; 330};
330 331
331struct 332struct
diff --git a/src/pruning.c b/src/pruning.c
index 2dea797..36445b7 100644
--- a/src/pruning.c
+++ b/src/pruning.c
@@ -258,25 +258,25 @@ genptable_compress(PruneData *pd)
258static void 258static void
259genptable_fixnasty(PruneData *pd, int d) 259genptable_fixnasty(PruneData *pd, int d)
260{ 260{
261 uint64_t i; 261 uint64_t i, ii, mask;
262 int j, n; 262 Trans t;
263 Cube c, cc;
264 Trans t[NTRANS];
265 263
266 if (pd->coord->transfind == NULL) 264 if (pd->coord->sd == NULL)
267 return; 265 return;
268 266
269 for (i = 0; i < pd->coord->max; i++) { 267 for (i = 0; i < pd->coord->max; i++) {
270 if (ptableval_index(pd, i) == d) { 268 if (ptableval_index(pd, i) == d) {
271 n = pd->coord->transfind(i, t); 269 mask = pd->coord->sd->selfsim[i];
272 if (n == 1) 270 if (mask == (1 << uf))
273 continue; 271 continue;
274 272
275 c = pd->coord->cube(i); 273 for (t = 0; t < NTRANS; t++) {
276 for (j = 0; j < n; j++) { 274 if (!((1 << t) & mask))
277 cc = apply_trans(t[j], c); 275 continue;
278 if (ptableval(pd, cc) > d) { 276
279 ptable_update(pd, cc, d); 277 ii = pd->coord->transform(t, i);
278 if (ptableval_index(pd, ii) > d) {
279 ptable_update_index(pd, ii, d);
280 pd->n++; 280 pd->n++;
281 } 281 }
282 } 282 }
@@ -306,7 +306,6 @@ instance_bfs(void *arg)
306 ThreadDataGenpt *td; 306 ThreadDataGenpt *td;
307 uint64_t i, ii, blocksize, rmin, rmax, updated; 307 uint64_t i, ii, blocksize, rmin, rmax, updated;
308 int j, pval, ichunk; 308 int j, pval, ichunk;
309 Cube c, cc;
310 Move *ms; 309 Move *ms;
311 310
312 td = (ThreadDataGenpt *)arg; 311 td = (ThreadDataGenpt *)arg;
@@ -324,15 +323,14 @@ instance_bfs(void *arg)
324 pval = ptableval_index(td->pd, i); 323 pval = ptableval_index(td->pd, i);
325 pthread_mutex_unlock(td->mutex[ichunk]); 324 pthread_mutex_unlock(td->mutex[ichunk]);
326 if (pval == td->d) { 325 if (pval == td->d) {
327 c = td->pd->coord->cube(i);
328 for (j = 0; ms[j] != NULLMOVE; j++) { 326 for (j = 0; ms[j] != NULLMOVE; j++) {
329 cc = apply_move(ms[j], c); 327 ii = td->pd->coord->move(ms[j], i);
330 ii = td->pd->coord->index(cc);
331 ichunk = findchunk(td->pd, td->nchunks, ii); 328 ichunk = findchunk(td->pd, td->nchunks, ii);
332 pthread_mutex_lock(td->mutex[ichunk]); 329 pthread_mutex_lock(td->mutex[ichunk]);
333 pval = ptableval_index(td->pd, ii); 330 pval = ptableval_index(td->pd, ii);
334 if (pval > td->d+1) { 331 if (pval > td->d+1) {
335 ptable_update(td->pd, cc, td->d+1); 332 ptable_update_index(td->pd,
333 ii, td->d+1);
336 updated++; 334 updated++;
337 } 335 }
338 pthread_mutex_unlock(td->mutex[ichunk]); 336 pthread_mutex_unlock(td->mutex[ichunk]);
diff --git a/src/symcoord.c b/src/symcoord.c
index 38e13c6..83fba0a 100644
--- a/src/symcoord.c
+++ b/src/symcoord.c
@@ -4,27 +4,43 @@
4#define CLASSES_CP_16 2768 4#define CLASSES_CP_16 2768
5#define CLASSES_EOFBEPOS_16 64430 5#define CLASSES_EOFBEPOS_16 64430
6 6
7static Cube antindex_cp_sym16(uint64_t ind);
8static Cube antindex_eofbepos_sym16(uint64_t ind);
9static Cube antindex_drud_sym16(uint64_t ind);
10static Cube antindex_drudfin_noE_sym16(uint64_t ind);
11static Cube antindex_nxopt31(uint64_t ind);
12
13static uint64_t index_cp_sym16(Cube cube); 7static uint64_t index_cp_sym16(Cube cube);
14static uint64_t index_eofbepos_sym16(Cube cube); 8static uint64_t index_eofbepos_sym16(Cube cube);
15static uint64_t index_drud_sym16(Cube cube); 9static uint64_t index_drud_sym16(Cube cube);
16static uint64_t index_drudfin_noE_sym16(Cube cube); 10static uint64_t index_drudfin_noE_sym16(Cube cube);
17static uint64_t index_nxopt31(Cube cube); 11static uint64_t index_nxopt31(Cube cube);
18 12
19static int transfinder_drud_sym16(uint64_t ind, Trans *ret); 13static uint64_t move_cp_sym16(Move m, uint64_t ind);
20static int transfinder_drudfin_noE_sym16(uint64_t ind, Trans *ret); 14static uint64_t move_eofbepos_sym16(Move m, uint64_t ind);
21static int transfinder_nxopt31(uint64_t ind, Trans *ret); 15static uint64_t move_drud_sym16(Move m, uint64_t ind);
16static uint64_t move_drudfin_noE_sym16(Move m, uint64_t ind);
17static uint64_t move_nxopt31(Move m, uint64_t ind);
18
19static uint64_t transform_cp(Trans t, uint64_t ind);
20static uint64_t transform_eofbepos(Trans t, uint64_t ind);
21static uint64_t transform_drud_sym16(Trans t, uint64_t ind);
22static uint64_t transform_drudfin_noE_sym16(Trans t, uint64_t ind);
23static uint64_t transform_nxopt31(Trans t, uint64_t ind);
22 24
23static void gensym(SymData *sd); 25static void gensym(SymData *sd);
26static void init_symc_moves();
27static void init_symc_trans();
24static bool read_symdata_file(SymData *sd); 28static bool read_symdata_file(SymData *sd);
25static int selfsims(SymData *sd, uint64_t ind, Trans *ret);
26static bool write_symdata_file(SymData *sd); 29static bool write_symdata_file(SymData *sd);
27 30
31/* Some tables ***************************************************************/
32
33static uint64_t move_cp_16[NMOVES][CLASSES_CP_16];
34static uint64_t move_eofbepos_16[NMOVES][CLASSES_EOFBEPOS_16];
35
36static int trans_eofbepos[NTRANS][POW2TO11*BINOM12ON4];
37static int trans_epud[NTRANS][FACTORIAL8];
38static int trans_cpud_separate[NTRANS][BINOM8ON4];
39
40static Trans ttrep_move_cp_16[NMOVES][CLASSES_CP_16];
41static Trans ttrep_move_eofbepos_16[NMOVES][CLASSES_EOFBEPOS_16];
42
43
28/* Transformation groups and symmetry data ***********************************/ 44/* Transformation groups and symmetry data ***********************************/
29 45
30static Trans 46static Trans
@@ -37,20 +53,22 @@ trans_group_udfix[16] = {
37 53
38static SymData 54static SymData
39sd_cp_16 = { 55sd_cp_16 = {
40 .filename = "sd_cp_16", 56 .filename = "sd_cp_16_new",
41 .coord = &coord_cp, 57 .coord = &coord_cp,
42 .sym_coord = &coord_cp_sym16, 58 .sym_coord = &coord_cp_sym16,
43 .ntrans = 16, 59 .ntrans = 16,
44 .trans = trans_group_udfix 60 .trans = trans_group_udfix,
61 .transform = transform_cp,
45}; 62};
46 63
47static SymData 64static SymData
48sd_eofbepos_16 = { 65sd_eofbepos_16 = {
49 .filename = "sd_eofbepos_16", 66 .filename = "sd_eofbepos_16_new",
50 .coord = &coord_eofbepos, 67 .coord = &coord_eofbepos,
51 .sym_coord = &coord_eofbepos_sym16, 68 .sym_coord = &coord_eofbepos_sym16,
52 .ntrans = 16, 69 .ntrans = 16,
53 .trans = trans_group_udfix 70 .trans = trans_group_udfix,
71 .transform = transform_eofbepos,
54}; 72};
55 73
56SymData * all_sd[] = { 74SymData * all_sd[] = {
@@ -65,90 +83,44 @@ SymData * all_sd[] = {
65Coordinate 83Coordinate
66coord_eofbepos_sym16 = { 84coord_eofbepos_sym16 = {
67 .index = index_eofbepos_sym16, 85 .index = index_eofbepos_sym16,
68 .cube = antindex_eofbepos_sym16, 86 .move = move_eofbepos_sym16,
69}; 87};
70 88
71Coordinate 89Coordinate
72coord_cp_sym16 = { 90coord_cp_sym16 = {
73 .index = index_cp_sym16, 91 .index = index_cp_sym16,
74 .cube = antindex_cp_sym16, 92 .move = move_cp_sym16,
75}; 93};
76 94
77Coordinate 95Coordinate
78coord_drud_sym16 = { 96coord_drud_sym16 = {
79 .index = index_drud_sym16, 97 .index = index_drud_sym16,
80 .cube = antindex_drud_sym16, 98 .move = move_drud_sym16,
81 .max = POW3TO7 * CLASSES_EOFBEPOS_16, 99 .max = POW3TO7 * CLASSES_EOFBEPOS_16,
82 .transfind = transfinder_drud_sym16, 100 .transform = transform_drud_sym16,
101 .sd = &sd_cp_16,
83}; 102};
84 103
85Coordinate 104Coordinate
86coord_drudfin_noE_sym16 = { 105coord_drudfin_noE_sym16 = {
87 .index = index_drudfin_noE_sym16, 106 .index = index_drudfin_noE_sym16,
88 .cube = antindex_drudfin_noE_sym16, 107 .move = move_drudfin_noE_sym16,
89 .max = FACTORIAL8 * CLASSES_CP_16, 108 .max = FACTORIAL8 * CLASSES_CP_16,
90 .transfind = transfinder_drudfin_noE_sym16, 109 .transform = transform_drudfin_noE_sym16,
110 .sd = &sd_eofbepos_16,
91}; 111};
92 112
93Coordinate 113Coordinate
94coord_nxopt31 = { 114coord_nxopt31 = {
95 .index = index_nxopt31, 115 .index = index_nxopt31,
96 .cube = antindex_nxopt31, 116 .move = move_nxopt31,
97 .max = POW3TO7 * BINOM8ON4 * CLASSES_EOFBEPOS_16, 117 .max = POW3TO7 * BINOM8ON4 * CLASSES_EOFBEPOS_16,
98 .transfind = transfinder_nxopt31, 118 .transform = transform_nxopt31,
119 .sd = &sd_eofbepos_16,
99}; 120};
100 121
101/* Functions *****************************************************************/ 122/* Functions *****************************************************************/
102 123
103static Cube
104antindex_cp_sym16(uint64_t ind)
105{
106 return sd_cp_16.rep[ind];
107}
108
109static Cube
110antindex_eofbepos_sym16(uint64_t ind)
111{
112 return sd_eofbepos_16.rep[ind];
113}
114
115static Cube
116antindex_drud_sym16(uint64_t ind)
117{
118 Cube c;
119
120 c = antindex_eofbepos_sym16(ind/POW3TO7);
121 c.coud = ind % POW3TO7;
122 c.cofb = c.coud;
123 c.corl = c.coud;
124
125 return c;
126}
127
128static Cube
129antindex_drudfin_noE_sym16(uint64_t ind)
130{
131 Cube c1, c2;
132
133 c1 = coord_epud.cube(ind % FACTORIAL8);
134 c2 = antindex_cp_sym16(ind/FACTORIAL8);
135 c1.cp = c2.cp;
136
137 return c1;
138}
139
140static Cube
141antindex_nxopt31(uint64_t ind)
142{
143 Cube c;
144
145 c = antindex_eofbepos_sym16(ind/(BINOM8ON4*POW3TO7));
146 c.cp = coord_cpud_separate.cube(ind % BINOM8ON4).cp;
147 c.coud = (ind / BINOM8ON4) % POW3TO7;
148
149 return c;
150}
151
152static uint64_t 124static uint64_t
153index_cp_sym16(Cube cube) 125index_cp_sym16(Cube cube)
154{ 126{
@@ -198,6 +170,116 @@ index_nxopt31(Cube cube)
198 return a * BINOM8ON4 + coord_cpud_separate.index((Cube){.cp = cp}); 170 return a * BINOM8ON4 + coord_cpud_separate.index((Cube){.cp = cp});
199} 171}
200 172
173static uint64_t
174move_cp_sym16(Move m, uint64_t ind)
175{
176 return move_cp_16[m][ind];
177}
178
179static uint64_t
180move_eofbepos_sym16(Move m, uint64_t ind)
181{
182 return move_eofbepos_16[m][ind];
183}
184
185static uint64_t
186move_drud_sym16(Move m, uint64_t ind)
187{
188 uint64_t coud, eofbepos;
189 Trans ttr;
190
191 eofbepos = move_eofbepos_16[m][ind / POW3TO7];
192 ttr = ttrep_move_eofbepos_16[m][ind / POW3TO7];
193 coud = coud_mtable[m][ind % POW3TO7];
194 coud = co_ttable[ttr][coud]; /* Source is always coud */
195
196 return eofbepos * POW3TO7 + coud;
197}
198
199static uint64_t
200move_drudfin_noE_sym16(Move m, uint64_t ind)
201{
202 uint64_t cp, epud;
203 Trans ttr;
204
205 cp = move_cp_16[m][ind / FACTORIAL8];
206 ttr = ttrep_move_cp_16[m][ind / FACTORIAL8];
207 epud = coord_epud.move(m, ind % FACTORIAL8);
208 epud = trans_epud[ttr][epud];
209
210 return cp * FACTORIAL8 + epud;
211}
212
213static uint64_t
214move_nxopt31(Move m, uint64_t ind)
215{
216 uint64_t eofbepos, cpsep, coud;
217 Trans ttr;
218
219 eofbepos = ind / (POW3TO7 * BINOM8ON4);
220 coud = (ind / BINOM8ON4) % POW3TO7;
221 cpsep = ind % BINOM8ON4;
222
223 eofbepos = move_eofbepos_16[m][eofbepos];
224 ttr = ttrep_move_eofbepos_16[m][eofbepos];
225 coud = coud_mtable[m][coud];
226 coud = co_ttable[ttr][coud]; /* Source is always coud */
227 cpsep = coord_cpud_separate.move(m, cpsep);
228 cpsep = trans_cpud_separate[ttr][cpsep];
229
230 return (eofbepos * POW3TO7 + coud) * BINOM8ON4 + cpsep;
231}
232
233static uint64_t
234transform_cp(Trans t, uint64_t ind)
235{
236 return cp_ttable[t][ind];
237}
238
239static uint64_t
240transform_eofbepos(Trans t, uint64_t ind)
241{
242 return trans_eofbepos[t][ind];
243}
244
245static uint64_t
246transform_drud_sym16(Trans t, uint64_t ind)
247{
248 uint64_t coud, eofbepos;
249
250 eofbepos = ind / POW3TO7; /* Assum trans fixes eofbepos */
251 coud = co_ttable[t][ind % POW3TO7]; /* Source is always coud */
252
253 return eofbepos * POW3TO7 + coud;
254}
255
256static uint64_t
257transform_drudfin_noE_sym16(Trans t, uint64_t ind)
258{
259 uint64_t cp, epud;
260
261 cp = ind / FACTORIAL8; /* Assume trans fixes eofbepos */
262 epud = trans_epud[t][ind % FACTORIAL8];
263
264 return cp * FACTORIAL8 + epud;
265}
266
267static uint64_t
268transform_nxopt31(Trans t, uint64_t ind)
269{
270 uint64_t eofbepos, cpsep, coud;
271
272 eofbepos = ind / (POW3TO7 * BINOM8ON4);
273 coud = (ind / BINOM8ON4) % POW3TO7;
274 cpsep = ind % BINOM8ON4;
275
276 coud = co_ttable[t][coud]; /* Source is always coud */
277 cpsep = trans_cpud_separate[t][cpsep];
278
279 return (eofbepos * POW3TO7 + coud) * BINOM8ON4 + cpsep;
280}
281
282/*
201static int 283static int
202transfinder_drud_sym16(uint64_t ind, Trans *ret) 284transfinder_drud_sym16(uint64_t ind, Trans *ret)
203{ 285{
@@ -264,6 +346,8 @@ transfinder_nxopt31(uint64_t ind, Trans *ret)
264 return naux[trueind]; 346 return naux[trueind];
265} 347}
266 348
349*/
350
267/* Other functions ***********************************************************/ 351/* Other functions ***********************************************************/
268 352
269void 353void
@@ -271,7 +355,7 @@ free_sd(SymData *sd)
271{ 355{
272 if (sd->generated) { 356 if (sd->generated) {
273 free(sd->class); 357 free(sd->class);
274 free(sd->rep); 358 free(sd->unsym);
275 free(sd->transtorep); 359 free(sd->transtorep);
276 } 360 }
277 361
@@ -282,15 +366,16 @@ static void
282gensym(SymData *sd) 366gensym(SymData *sd)
283{ 367{
284 uint64_t i, in, nreps = 0; 368 uint64_t i, in, nreps = 0;
369 Trans t;
285 int j; 370 int j;
286 Cube c, d;
287 371
288 if (sd->generated) 372 if (sd->generated)
289 return; 373 return;
290 374
291 sd->class = malloc(sd->coord->max * sizeof(uint64_t)); 375 sd->class = malloc(sd->coord->max * sizeof(uint64_t));
292 sd->rep = malloc(sd->coord->max * sizeof(Cube)); 376 sd->unsym = malloc(sd->coord->max * sizeof(uint64_t));
293 sd->transtorep = malloc(sd->coord->max * sizeof(Trans)); 377 sd->transtorep = malloc(sd->coord->max * sizeof(Trans));
378 sd->selfsim = malloc(sd->coord->max * sizeof(uint64_t));
294 379
295 if (read_symdata_file(sd)) { 380 if (read_symdata_file(sd)) {
296 sd->generated = true; 381 sd->generated = true;
@@ -304,16 +389,17 @@ gensym(SymData *sd)
304 389
305 for (i = 0; i < sd->coord->max; i++) { 390 for (i = 0; i < sd->coord->max; i++) {
306 if (sd->class[i] == sd->coord->max + 1) { 391 if (sd->class[i] == sd->coord->max + 1) {
307 c = sd->coord->cube(i); 392 sd->unsym[nreps] = i;
308 sd->rep[nreps] = c; 393 sd->selfsim[nreps] = 0;
309 for (j = 0; j < sd->ntrans; j++) { 394 for (j = 0; j < sd->ntrans; j++) {
310 d = apply_trans(sd->trans[j], c); 395 t = sd->trans[j];
311 in = sd->coord->index(d); 396 in = sd->transform(t, i);
312 397 sd->class[in] = nreps;
313 if (sd->class[in] == sd->coord->max + 1) { 398 if (in == i) {
314 sd->class[in] = nreps; 399 sd->selfsim[nreps] |= (1 << t);
315 sd->transtorep[in] = 400 sd->transtorep[in] = uf;
316 inverse_trans(sd->trans[j]); 401 } else {
402 sd->transtorep[in] = inverse_trans(t);
317 } 403 }
318 } 404 }
319 nreps++; 405 nreps++;
@@ -321,7 +407,8 @@ gensym(SymData *sd)
321 } 407 }
322 408
323 sd->sym_coord->max = nreps; 409 sd->sym_coord->max = nreps;
324 sd->rep = realloc(sd->rep, nreps * sizeof(Cube)); 410 sd->unsym = realloc(sd->unsym, nreps * sizeof(uint64_t));
411 sd->selfsim = realloc(sd->selfsim, nreps * sizeof(uint64_t));
325 sd->generated = true; 412 sd->generated = true;
326 413
327 fprintf(stderr, "Found %" PRIu64 " classes\n", nreps); 414 fprintf(stderr, "Found %" PRIu64 " classes\n", nreps);
@@ -350,7 +437,8 @@ read_symdata_file(SymData *sd)
350 return false; 437 return false;
351 438
352 r = r && fread(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; 439 r = r && fread(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1;
353 r = r && fread(sd->rep, sizeof(Cube), *sn, f) == *sn; 440 r = r && fread(sd->unsym, sizeof(uint64_t), *sn, f) == *sn;
441 r = r && fread(sd->selfsim, sizeof(uint64_t), *sn, f) == *sn;
354 r = r && fread(sd->class, sizeof(uint64_t), n, f) == n; 442 r = r && fread(sd->class, sizeof(uint64_t), n, f) == n;
355 r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n; 443 r = r && fread(sd->transtorep, sizeof(Trans), n, f) == n;
356 444
@@ -358,6 +446,7 @@ read_symdata_file(SymData *sd)
358 return r; 446 return r;
359} 447}
360 448
449/*
361static int 450static int
362selfsims(SymData *sd, uint64_t ind, Trans *ret) 451selfsims(SymData *sd, uint64_t ind, Trans *ret)
363{ 452{
@@ -376,6 +465,7 @@ selfsims(SymData *sd, uint64_t ind, Trans *ret)
376 465
377 return n; 466 return n;
378} 467}
468*/
379 469
380static bool 470static bool
381write_symdata_file(SymData *sd) 471write_symdata_file(SymData *sd)
@@ -395,7 +485,8 @@ write_symdata_file(SymData *sd)
395 return false; 485 return false;
396 486
397 r = r && fwrite(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1; 487 r = r && fwrite(&sd->sym_coord->max, sizeof(uint64_t), 1, f) == 1;
398 r = r && fwrite(sd->rep, sizeof(Cube), *sn, f) == *sn; 488 r = r && fwrite(sd->unsym, sizeof(uint64_t), *sn, f) == *sn;
489 r = r && fwrite(sd->selfsim, sizeof(uint64_t), *sn, f) == *sn;
399 r = r && fwrite(sd->class, sizeof(uint64_t), n, f) == n; 490 r = r && fwrite(sd->class, sizeof(uint64_t), n, f) == n;
400 r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n; 491 r = r && fwrite(sd->transtorep, sizeof(Trans), n, f) == n;
401 492
@@ -403,6 +494,83 @@ write_symdata_file(SymData *sd)
403 return r; 494 return r;
404} 495}
405 496
497static void
498init_symc_moves()
499{
500 uint64_t i, ii;
501 Move j;
502
503 for (i = 0; i < CLASSES_CP_16; i++) {
504 ii = sd_cp_16.unsym[i];
505 for (j = 0; j < NMOVES; j++) {
506 move_cp_16[j][i] = sd_cp_16.coord->move(j, ii);
507 ttrep_move_cp_16[j][i] = sd_cp_16.transtorep[ii];
508 }
509 }
510
511 for (i = 0; i < CLASSES_EOFBEPOS_16; i++) {
512 ii = sd_eofbepos_16.unsym[i];
513 for (j = 0; j < NMOVES; j++) {
514 move_eofbepos_16[j][i] =
515 sd_eofbepos_16.coord->move(j, ii);
516 ttrep_move_eofbepos_16[j][i] =
517 sd_eofbepos_16.transtorep[ii];
518 }
519 }
520}
521
522void
523init_symc_trans()
524{
525 uint64_t i;
526 int j, cp;
527 int epe[4] = {FR, FL, BL, BR};
528 int a[12] = { [8] = 8, [9] = 9, [10] = 10, [11] = 11 };
529 Cube c;
530 CubeArray *arr, *aux;
531 Trans t;
532
533 for (i = 0; i < POW2TO11*BINOM12ON4; i++) {
534 for (j = 0; j < 16; j++) {
535 t = trans_group_udfix[j];
536
537 arr = new_cubearray((Cube){0}, pf_edges);
538 int_to_sum_zero_array(i/BINOM12ON4, 2, 12, arr->eofb);
539 epos_to_compatible_ep((i%BINOM12ON4)*24, arr->ep, epe);
540 fix_eorleoud(arr);
541 c = arrays_to_cube(arr, pf_edges);
542 free_cubearray(arr, pf_edges);
543
544 c = apply_trans(t, c);
545 trans_eofbepos[t][i] =
546 c.eofb * BINOM12ON4 + (c.epose / 24);
547 }
548 }
549
550 aux = malloc(sizeof(CubeArray));
551 aux->ep = a;
552 for (i = 0; i < FACTORIAL8; i++) {
553 index_to_perm(i, 8, a);
554 c = arrays_to_cube(aux, pf_ep);
555 for (j = 0; j < 16; j++) {
556 t = trans_group_udfix[j];
557 arr = new_cubearray(apply_trans(t, c), pf_ep);
558 trans_epud[t][i] = perm_to_index(arr->ep, 8);
559 free_cubearray(arr, pf_ep);
560 }
561 }
562 free(aux);
563
564 for (i = 0; i < BINOM8ON4; i++) {
565 cp = cpud_separate_ant[i];
566 for (j = 0; j < 16; j++) {
567 t = trans_group_udfix[j];
568 trans_cpud_separate[j][i] =
569 cpud_separate_ind[cp_ttable[t][cp]];
570 }
571 }
572}
573
406void 574void
407init_symcoord() 575init_symcoord()
408{ 576{
@@ -415,7 +583,11 @@ init_symcoord()
415 583
416 init_coord(); 584 init_coord();
417 585
586 init_symc_trans();
587
418 for (i = 0; all_sd[i] != NULL; i++) 588 for (i = 0; all_sd[i] != NULL; i++)
419 gensym(all_sd[i]); 589 gensym(all_sd[i]);
590
591 init_symc_moves();
420} 592}
421 593
diff --git a/www/download/index.html b/www/download/index.html
index 2618719..ff824f8 100644
--- a/www/download/index.html
+++ b/www/download/index.html
@@ -98,7 +98,7 @@ followed by
98</p> 98</p>
99<pre><code>make install</code></pre> 99<pre><code>make install</code></pre>
100<p> 100<p>
101Then ollow the instructions below to install the pruning tables. 101Then follow the instructions below to install the pruning tables.
102</p> 102</p>
103 103
104<h3>Tables</h3> 104<h3>Tables</h3>
@@ -114,7 +114,7 @@ Then ollow the instructions below to install the pruning tables.
114</table> 114</table>
115<p> 115<p>
116<strong>Note:</strong> the version 2.0 at the end of the file name is 116<strong>Note:</strong> the version 2.0 at the end of the file name is
117only indicative. Later versionw will use the same tables, unless 117only indicative. Later versions will use the same tables, unless
118otherwise specified. 118otherwise specified.
119</p> 119</p>
120 120

Generated with cgit - Back to sebastiano.tronto.net