aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/h48')
-rw-r--r--src/solvers/h48/gendata_h48.h86
-rw-r--r--src/solvers/h48/solve.h15
2 files changed, 49 insertions, 52 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index c8673fa..0d7fada 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -3,10 +3,10 @@
3#define H48_DIV(k) ((size_t)8 / (size_t)(k)) 3#define H48_DIV(k) ((size_t)8 / (size_t)(k))
4#define H48_TABLESIZE(h, k) DIV_ROUND_UP((size_t)H48_COORDMAX((h)), H48_DIV(k)) 4#define H48_TABLESIZE(h, k) DIV_ROUND_UP((size_t)H48_COORDMAX((h)), H48_DIV(k))
5 5
6#define H48_COEFF(k) (UINT32_C(32) / (uint32_t)(k)) 6#define H48_COEFF(k) (INT64_C(8) / (int64_t)(k))
7#define H48_INDEX(i, k) ((uint32_t)(i) / H48_COEFF(k)) 7#define H48_INDEX(i, k) ((i) / H48_COEFF(k))
8#define H48_SHIFT(i, k) ((uint32_t)(k) * ((uint32_t)(i) % H48_COEFF(k))) 8#define H48_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % H48_COEFF(k)))
9#define H48_MASK(i, k) ((UINT32_BIT(k) - (uint32_t)(1)) << H48_SHIFT(i, k)) 9#define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k))
10 10
11#define MAXLEN 20 11#define MAXLEN 20
12 12
@@ -52,7 +52,7 @@ typedef struct {
52typedef struct { 52typedef struct {
53 uint8_t depth; 53 uint8_t depth;
54 uint32_t *cocsepdata; 54 uint32_t *cocsepdata;
55 uint32_t *buf32; 55 uint8_t *table;
56 uint64_t *selfsim; 56 uint64_t *selfsim;
57 int64_t done; 57 int64_t done;
58 cube_t *crep; 58 cube_t *crep;
@@ -65,14 +65,15 @@ typedef struct {
65 uint8_t base; 65 uint8_t base;
66 uint8_t shortdepth; 66 uint8_t shortdepth;
67 uint32_t *cocsepdata; 67 uint32_t *cocsepdata;
68 uint32_t *buf32; 68 uint8_t *table;
69 uint64_t *selfsim; 69 uint64_t *selfsim;
70 cube_t *crep; 70 cube_t *crep;
71 h48map_t *shortcubes; 71 h48map_t *shortcubes;
72} h48k2_dfs_arg_t; 72} h48k2_dfs_arg_t;
73 73
74STATIC_INLINE uint8_t get_esep_pval(const uint32_t *, int64_t, uint8_t); 74STATIC_INLINE uint8_t get_h48_pval(const uint8_t *, int64_t, uint8_t);
75STATIC_INLINE void set_esep_pval(uint32_t *, int64_t, uint8_t, uint8_t); 75STATIC_INLINE void set_h48_pval(uint8_t *, int64_t, uint8_t, uint8_t);
76STATIC_INLINE uint8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint8_t, uint8_t *);
76 77
77STATIC uint64_t gen_h48short(gendata_h48short_arg_t *); 78STATIC uint64_t gen_h48short(gendata_h48short_arg_t *);
78STATIC size_t gendata_h48(gendata_h48_arg_t *); 79STATIC size_t gendata_h48(gendata_h48_arg_t *);
@@ -85,8 +86,6 @@ STATIC_INLINE void gendata_h48k2_mark(cube_t, int8_t, h48k2_dfs_arg_t *);
85STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *); 86STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *);
86STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); 87STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
87 88
88STATIC_INLINE int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint8_t, uint32_t *);
89
90STATIC uint64_t 89STATIC uint64_t
91gen_h48short(gendata_h48short_arg_t *arg) 90gen_h48short(gendata_h48short_arg_t *arg)
92{ 91{
@@ -178,9 +177,10 @@ generating fixed table with h=0, k=4
178STATIC size_t 177STATIC size_t
179gendata_h48h0k4(gendata_h48_arg_t *arg) 178gendata_h48h0k4(gendata_h48_arg_t *arg)
180{ 179{
181 uint32_t j, *buf32; 180 uint32_t j;
181 uint8_t *table;
182 h48h0k4_bfs_arg_t bfsarg; 182 h48h0k4_bfs_arg_t bfsarg;
183 int64_t sc, cc, esep_max; 183 int64_t sc, cc, h48max;
184 184
185 if (arg->buf == NULL) 185 if (arg->buf == NULL)
186 goto gendata_h48h0k4_return_size; 186 goto gendata_h48h0k4_return_size;
@@ -198,25 +198,25 @@ gendata_h48h0k4(gendata_h48_arg_t *arg)
198 .next = 0, 198 .next = 0,
199 }; 199 };
200 200
201 buf32 = (uint32_t *)((char *)arg->h48buf + INFOSIZE); 201 table = (uint8_t *)arg->h48buf + INFOSIZE;
202 memset(buf32, 0xFF, H48_TABLESIZE(0, 4)); 202 memset(table, 0xFF, H48_TABLESIZE(0, 4));
203 203
204 esep_max = (int64_t)H48_COORDMAX(0); 204 h48max = (int64_t)H48_COORDMAX(0);
205 sc = coord_h48(SOLVED_CUBE, arg->cocsepdata, 0); 205 sc = coord_h48(SOLVED_CUBE, arg->cocsepdata, 0);
206 set_esep_pval(buf32, sc, 4, 0); 206 set_h48_pval(table, sc, 4, 0);
207 arg->info.distribution[0] = 1; 207 arg->info.distribution[0] = 1;
208 bfsarg = (h48h0k4_bfs_arg_t) { 208 bfsarg = (h48h0k4_bfs_arg_t) {
209 .cocsepdata = arg->cocsepdata, 209 .cocsepdata = arg->cocsepdata,
210 .buf32 = buf32, 210 .table = table,
211 .selfsim = arg->selfsim, 211 .selfsim = arg->selfsim,
212 .crep = arg->crep 212 .crep = arg->crep
213 }; 213 };
214 for ( 214 for (
215 bfsarg.done = 1, bfsarg.depth = 1, cc = 0; 215 bfsarg.done = 1, bfsarg.depth = 1, cc = 0;
216 bfsarg.done < esep_max && bfsarg.depth <= arg->maxdepth; 216 bfsarg.done < h48max && bfsarg.depth <= arg->maxdepth;
217 bfsarg.depth++ 217 bfsarg.depth++
218 ) { 218 ) {
219 LOG("esep: generating depth %" PRIu8 "\n", bfsarg.depth); 219 LOG("h48: generating depth %" PRIu8 "\n", bfsarg.depth);
220 cc = gendata_h48h0k4_bfs(&bfsarg); 220 cc = gendata_h48h0k4_bfs(&bfsarg);
221 bfsarg.done += cc; 221 bfsarg.done += cc;
222 arg->info.distribution[bfsarg.depth] = cc; 222 arg->info.distribution[bfsarg.depth] = cc;
@@ -257,20 +257,19 @@ gendata_h48h0k4_bfs_fromdone(h48h0k4_bfs_arg_t *arg)
257 cube_t cube, moved; 257 cube_t cube, moved;
258 258
259 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) { 259 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) {
260//LOG("getting esep val for %" PRId64 "\n", i); 260 c = get_h48_pval(arg->table, i, 4);
261 c = get_esep_pval(arg->buf32, i, 4);
262 if (c != arg->depth - 1) 261 if (c != arg->depth - 1)
263 continue; 262 continue;
264 cube = invcoord_h48(i, arg->crep, 0); 263 cube = invcoord_h48(i, arg->crep, 0);
265 for (m = 0; m < 18; m++) { 264 for (m = 0; m < 18; m++) {
266 moved = move(cube, m); 265 moved = move(cube, m);
267 j = coord_h48(moved, arg->cocsepdata, 0); 266 j = coord_h48(moved, arg->cocsepdata, 0);
268 if (get_esep_pval(arg->buf32, j, 4) <= arg->depth) 267 if (get_h48_pval(arg->table, j, 4) <= arg->depth)
269 continue; 268 continue;
270 FOREACH_H48SIM(moved, arg->cocsepdata, arg->selfsim, 269 FOREACH_H48SIM(moved, arg->cocsepdata, arg->selfsim,
271 k = coord_h48(moved, arg->cocsepdata, 0); 270 k = coord_h48(moved, arg->cocsepdata, 0);
272 x = get_esep_pval(arg->buf32, k, 4); 271 x = get_h48_pval(arg->table, k, 4);
273 set_esep_pval(arg->buf32, k, 4, arg->depth); 272 set_h48_pval(arg->table, k, 4, arg->depth);
274 cc += x != arg->depth; 273 cc += x != arg->depth;
275 ) 274 )
276 } 275 }
@@ -288,20 +287,20 @@ gendata_h48h0k4_bfs_fromnew(h48h0k4_bfs_arg_t *arg)
288 cube_t cube, moved; 287 cube_t cube, moved;
289 288
290 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) { 289 for (i = 0, cc = 0; i < (int64_t)H48_COORDMAX(0); i++) {
291 c = get_esep_pval(arg->buf32, i, 4); 290 c = get_h48_pval(arg->table, i, 4);
292 if (c != 0xF) 291 if (c != 0xF)
293 continue; 292 continue;
294 cube = invcoord_h48(i, arg->crep, 0); 293 cube = invcoord_h48(i, arg->crep, 0);
295 for (m = 0; m < 18; m++) { 294 for (m = 0; m < 18; m++) {
296 moved = move(cube, m); 295 moved = move(cube, m);
297 j = coord_h48(moved, arg->cocsepdata, 0); 296 j = coord_h48(moved, arg->cocsepdata, 0);
298 x = get_esep_pval(arg->buf32, j, 4); 297 x = get_h48_pval(arg->table, j, 4);
299 if (x >= arg->depth) 298 if (x >= arg->depth)
300 continue; 299 continue;
301 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, 300 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim,
302 j = coord_h48(cube, arg->cocsepdata, 0); 301 j = coord_h48(cube, arg->cocsepdata, 0);
303 x = get_esep_pval(arg->buf32, j, 4); 302 x = get_h48_pval(arg->table, j, 4);
304 set_esep_pval(arg->buf32, j, 4, arg->depth); 303 set_h48_pval(arg->table, j, 4, arg->depth);
305 cc += x == 0xF; 304 cc += x == 0xF;
306 ) 305 )
307 break; /* Enough to find one, skip the rest */ 306 break; /* Enough to find one, skip the rest */
@@ -332,8 +331,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
332 [11] = 10 331 [11] = 10
333 }; 332 };
334 333
335 uint8_t t, selectedbase; 334 uint8_t t, selectedbase, *table;
336 uint32_t *buf32;
337 int64_t j; 335 int64_t j;
338 uint64_t nshort, i, ii; 336 uint64_t nshort, i, ii;
339 h48map_t shortcubes; 337 h48map_t shortcubes;
@@ -344,9 +342,9 @@ gendata_h48k2(gendata_h48_arg_t *arg)
344 if (arg->buf == NULL) 342 if (arg->buf == NULL)
345 goto gendata_h48k2_return_size; 343 goto gendata_h48k2_return_size;
346 344
347 buf32 = (uint32_t *)((char *)arg->h48buf + INFOSIZE); 345 table = (uint8_t *)arg->h48buf + INFOSIZE;
348 if (arg->buf != NULL) 346 if (arg->buf != NULL)
349 memset(buf32, 0xFF, H48_TABLESIZE(arg->h, arg->k)); 347 memset(table, 0xFF, H48_TABLESIZE(arg->h, arg->k));
350 348
351 LOG("Computing depth <=%" PRIu8 "\n", shortdepth) 349 LOG("Computing depth <=%" PRIu8 "\n", shortdepth)
352 h48map_create(&shortcubes, capacity, randomizer); 350 h48map_create(&shortcubes, capacity, randomizer);
@@ -382,7 +380,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
382 .base = selectedbase, 380 .base = selectedbase,
383 .shortdepth = shortdepth, 381 .shortdepth = shortdepth,
384 .cocsepdata = arg->cocsepdata, 382 .cocsepdata = arg->cocsepdata,
385 .buf32 = buf32, 383 .table = table,
386 .selfsim = arg->selfsim, 384 .selfsim = arg->selfsim,
387 .crep = arg->crep, 385 .crep = arg->crep,
388 .shortcubes = &shortcubes 386 .shortcubes = &shortcubes
@@ -403,7 +401,7 @@ gendata_h48k2(gendata_h48_arg_t *arg)
403 401
404 arg->info.base = selectedbase; 402 arg->info.base = selectedbase;
405 for (j = 0; j < H48_COORDMAX(arg->h); j++) { 403 for (j = 0; j < H48_COORDMAX(arg->h); j++) {
406 t = get_esep_pval(buf32, j, 2); 404 t = get_h48_pval(table, j, 2);
407 arg->info.distribution[t]++; 405 arg->info.distribution[t]++;
408 } 406 }
409 407
@@ -481,9 +479,9 @@ gendata_h48k2_mark(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
481 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, 479 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim,
482 fullcoord = coord_h48(cube, arg->cocsepdata, 11); 480 fullcoord = coord_h48(cube, arg->cocsepdata, 11);
483 coord = fullcoord >> (int64_t)(11 - arg->h); 481 coord = fullcoord >> (int64_t)(11 - arg->h);
484 oldval = get_esep_pval(arg->buf32, coord, arg->k); 482 oldval = get_h48_pval(arg->table, coord, arg->k);
485 newval = (uint8_t)MAX(depth, 0); 483 newval = (uint8_t)MAX(depth, 0);
486 set_esep_pval(arg->buf32, coord, arg->k, MIN(oldval, newval)); 484 set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval));
487 ) 485 )
488} 486}
489 487
@@ -498,7 +496,7 @@ gendata_h48k2_dfs_stop(cube_t cube, uint8_t depth, h48k2_dfs_arg_t *arg)
498 /* We are in the "real coordinate" case, we can stop 496 /* We are in the "real coordinate" case, we can stop
499 if this coordinate has already been visited */ 497 if this coordinate has already been visited */
500 coord = coord_h48(cube, arg->cocsepdata, arg->h); 498 coord = coord_h48(cube, arg->cocsepdata, arg->h);
501 oldval = get_esep_pval(arg->buf32, coord, arg->k); 499 oldval = get_h48_pval(arg->table, coord, arg->k);
502 return oldval <= depth; 500 return oldval <= depth;
503 } else { 501 } else {
504 /* With 0 < k < 11 we do not have a "real coordinate". 502 /* With 0 < k < 11 we do not have a "real coordinate".
@@ -511,23 +509,23 @@ gendata_h48k2_dfs_stop(cube_t cube, uint8_t depth, h48k2_dfs_arg_t *arg)
511} 509}
512 510
513STATIC_INLINE uint8_t 511STATIC_INLINE uint8_t
514get_esep_pval(const uint32_t *buf32, int64_t i, uint8_t k) 512get_h48_pval(const uint8_t *table, int64_t i, uint8_t k)
515{ 513{
516 return (buf32[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k); 514 return (table[H48_INDEX(i, k)] & H48_MASK(i, k)) >> H48_SHIFT(i, k);
517} 515}
518 516
519STATIC_INLINE void 517STATIC_INLINE void
520set_esep_pval(uint32_t *buf32, int64_t i, uint8_t k, uint8_t val) 518set_h48_pval(uint8_t *table, int64_t i, uint8_t k, uint8_t val)
521{ 519{
522 buf32[H48_INDEX(i, k)] = (buf32[H48_INDEX(i, k)] & (~H48_MASK(i, k))) 520 table[H48_INDEX(i, k)] = (table[H48_INDEX(i, k)] & (~H48_MASK(i, k)))
523 | (val << H48_SHIFT(i, k)); 521 | (val << H48_SHIFT(i, k));
524} 522}
525 523
526STATIC_INLINE int8_t 524STATIC_INLINE uint8_t
527get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint8_t k, uint32_t *h48data) 525get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint8_t k, uint8_t *table)
528{ 526{
529 int64_t coord; 527 int64_t coord;
530 528
531 coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h); 529 coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h);
532 return get_esep_pval(h48data, coord, k); 530 return get_h48_pval(table, coord, k);
533} 531}
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 88c5a1e..1c9328b 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -9,7 +9,7 @@ typedef struct {
9 uint8_t h; 9 uint8_t h;
10 uint8_t k; 10 uint8_t k;
11 uint32_t *cocsepdata; 11 uint32_t *cocsepdata;
12 uint32_t *h48data; 12 uint8_t *h48data;
13 char **nextsol; 13 char **nextsol;
14 uint8_t nissbranch; 14 uint8_t nissbranch;
15 int8_t npremoves; 15 int8_t npremoves;
@@ -22,7 +22,7 @@ typedef struct {
22 int8_t depth; 22 int8_t depth;
23 uint8_t moves[MAXLEN]; 23 uint8_t moves[MAXLEN];
24 uint32_t *cocsepdata; 24 uint32_t *cocsepdata;
25 uint32_t *h48data; 25 uint8_t *h48data;
26 char *s; 26 char *s;
27} dfsarg_solveh48stats_t; 27} dfsarg_solveh48stats_t;
28 28
@@ -105,7 +105,6 @@ solve_h48_stop(dfsarg_solveh48_t *arg)
105 return true; 105 return true;
106 106
107 bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data); 107 bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data);
108 // LOG("Using pval %" PRId8 "\n", bound);
109 if (bound + arg->nmoves + arg->npremoves > arg->depth) 108 if (bound + arg->nmoves + arg->npremoves > arg->depth)
110 return true; 109 return true;
111 if (bound + arg->nmoves + arg->npremoves == arg->depth) 110 if (bound + arg->nmoves + arg->npremoves == arg->depth)
@@ -193,8 +192,8 @@ solve_h48(
193 .maxsolutions = maxsolutions, 192 .maxsolutions = maxsolutions,
194 .h = h, 193 .h = h,
195 .k = k, 194 .k = k,
196 .cocsepdata = (uint32_t *)data, 195 .cocsepdata = (uint32_t *)((char *)data + INFOSIZE),
197 .h48data = ((uint32_t *)data) + COCSEP_FULLSIZE / 4, 196 .h48data = (uint8_t *)data + COCSEP_FULLSIZE,
198 .nextsol = &solutions 197 .nextsol = &solutions
199 }; 198 };
200 199
@@ -237,7 +236,7 @@ solve_h48stats_dfs(dfsarg_solveh48stats_t *arg)
237 236
238 /* Check h48 lower bound for h=0 (esep, but no eo) */ 237 /* Check h48 lower bound for h=0 (esep, but no eo) */
239 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); 238 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0);
240 bound = get_esep_pval(arg->h48data, coord, 4); 239 bound = get_h48_bound(arg->cube, d, 0, 4, arg->h48data);
241 if (bound + arg->nmoves > arg->depth) 240 if (bound + arg->nmoves > arg->depth)
242 return 0; 241 return 0;
243 242
@@ -284,8 +283,8 @@ solve_h48stats(
284 283
285 arg = (dfsarg_solveh48stats_t) { 284 arg = (dfsarg_solveh48stats_t) {
286 .cube = cube, 285 .cube = cube,
287 .cocsepdata = (uint32_t *)data, 286 .cocsepdata = (uint32_t *)((char *)data + INFOSIZE),
288 .h48data = ((uint32_t *)data) + (cocsepsize/4), 287 .h48data = (uint8_t *)data + cocsepsize,
289 .s = solutions 288 .s = solutions
290 }; 289 };
291 290

Generated with cgit - Back to sebastiano.tronto.net