diff options
Diffstat (limited to '')
| -rw-r--r-- | src/nissy.c | 25 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_cocsep.h | 169 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_full.h (renamed from src/solvers/h48/gendata.h) | 294 | ||||
| -rw-r--r-- | src/solvers/h48/h48.h | 3 |
4 files changed, 283 insertions, 208 deletions
diff --git a/src/nissy.c b/src/nissy.c index 9df775c..fac7a20 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -164,22 +164,23 @@ nissy_gendata( | |||
| 164 | ) | 164 | ) |
| 165 | { | 165 | { |
| 166 | int64_t ret; | 166 | int64_t ret; |
| 167 | uint8_t maxdepth, h, i, j; | 167 | uint8_t i; |
| 168 | gendata_h48_arg_t arg; | ||
| 168 | 169 | ||
| 170 | arg.buf = data; | ||
| 169 | if (!strcmp(solver, "h48")) { | 171 | if (!strcmp(solver, "h48")) { |
| 170 | /* options are in the form "h;maxdepth" */ | 172 | /* options are in the form "h;k;maxdepth" */ |
| 173 | arg.h = atoi(options); | ||
| 171 | for (i = 0; options[i] != ';'; i++) ; | 174 | for (i = 0; options[i] != ';'; i++) ; |
| 172 | for (j = i; options[j]; j++) ; | 175 | arg.k = atoi(&options[i+1]); |
| 173 | h = atoi(options); | 176 | for (i = i+1; options[i] != ';'; i++) ; |
| 174 | if (h != 0) { | 177 | arg.maxdepth = atoi(&options[i+1]); |
| 175 | LOG("Temporarily only h=0 is supported\n"); | 178 | ret = gendata_h48(&arg); |
| 176 | ret = -1; | ||
| 177 | } else { | ||
| 178 | maxdepth = atoi(&options[i+1]); | ||
| 179 | ret = gendata_h48h0k4(data, maxdepth); | ||
| 180 | } | ||
| 181 | } else if (!strcmp(solver, "h48stats")) { | 179 | } else if (!strcmp(solver, "h48stats")) { |
| 182 | ret = gendata_h48h0k4(data, 20); | 180 | arg.h = 0; |
| 181 | arg.k = 4; | ||
| 182 | arg.maxdepth = 20; | ||
| 183 | ret = gendata_h48(&arg); | ||
| 183 | } else { | 184 | } else { |
| 184 | LOG("gendata: implemented only for h48 solver\n"); | 185 | LOG("gendata: implemented only for h48 solver\n"); |
| 185 | ret = -1; | 186 | ret = -1; |
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h new file mode 100644 index 0000000..13ce68b --- /dev/null +++ b/src/solvers/h48/gendata_cocsep.h | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | #define COCSEP_CLASSES ((size_t)3393) | ||
| 2 | #define COCSEP_TABLESIZE ((size_t)_3p7 << (size_t)7) | ||
| 3 | #define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + (size_t)7) / (size_t)8) | ||
| 4 | #define COCSEP_FULLSIZE ((size_t)4 * (COCSEP_TABLESIZE + (size_t)12)) | ||
| 5 | |||
| 6 | #define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8)) | ||
| 7 | #define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8))) | ||
| 8 | |||
| 9 | #define CBOUND_MASK UINT32_C(0xFF) | ||
| 10 | #define CBOUND(x) ((x) & CBOUND_MASK) | ||
| 11 | |||
| 12 | typedef struct { | ||
| 13 | cube_t cube; | ||
| 14 | uint8_t depth; | ||
| 15 | uint8_t maxdepth; | ||
| 16 | uint16_t *n; | ||
| 17 | uint32_t *buf32; | ||
| 18 | uint8_t *visited; | ||
| 19 | uint64_t *selfsim; | ||
| 20 | cube_t *rep; | ||
| 21 | } dfsarg_cocsep_t; | ||
| 22 | |||
| 23 | _static_inline bool get_visited(const uint8_t *, int64_t); | ||
| 24 | _static_inline void set_visited(uint8_t *, int64_t); | ||
| 25 | |||
| 26 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); | ||
| 27 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); | ||
| 28 | |||
| 29 | _static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *); | ||
| 30 | |||
| 31 | /* | ||
| 32 | Each element of the cocsep table is a uint32_t used as follows: | ||
| 33 | - Lowest 8-bit block: pruning value | ||
| 34 | - Second-lowest 8-bit block: "ttrep" (transformation to representative) | ||
| 35 | - Top 16-bit block: symcoord value | ||
| 36 | After the data as described above, more auxiliary information is appended: | ||
| 37 | - A uint32_t representing the number of symmetry classes | ||
| 38 | - A uint32_t representing the highest value of the pruning table | ||
| 39 | - One uint32_t for each "line" of the pruning table, representing the number | ||
| 40 | of positions having that pruning value. | ||
| 41 | */ | ||
| 42 | _static size_t | ||
| 43 | gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep) | ||
| 44 | { | ||
| 45 | uint32_t *buf32, *info, cc; | ||
| 46 | uint16_t n; | ||
| 47 | uint8_t i, j, visited[COCSEP_VISITEDSIZE]; | ||
| 48 | dfsarg_cocsep_t arg; | ||
| 49 | |||
| 50 | if (buf == NULL) | ||
| 51 | goto gendata_cocsep_return_size; | ||
| 52 | |||
| 53 | buf32 = (uint32_t *)buf; | ||
| 54 | info = buf32 + COCSEP_TABLESIZE; | ||
| 55 | memset(buf32, 0xFF, sizeof(uint32_t) * COCSEP_TABLESIZE); | ||
| 56 | if (selfsim != NULL) | ||
| 57 | memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); | ||
| 58 | |||
| 59 | arg = (dfsarg_cocsep_t) { | ||
| 60 | .cube = solved, | ||
| 61 | .n = &n, | ||
| 62 | .buf32 = buf32, | ||
| 63 | .visited = visited, | ||
| 64 | .selfsim = selfsim, | ||
| 65 | .rep = rep | ||
| 66 | }; | ||
| 67 | for (i = 0, n = 0, cc = 0; i < 10; i++) { | ||
| 68 | LOG("cocsep: generating depth %" PRIu8 "\n", i); | ||
| 69 | memset(visited, 0, COCSEP_VISITEDSIZE); | ||
| 70 | arg.depth = 0; | ||
| 71 | arg.maxdepth = i; | ||
| 72 | cc = gendata_cocsep_dfs(&arg); | ||
| 73 | info[i+2] = cc; | ||
| 74 | LOG("found %" PRIu32 "\n", cc); | ||
| 75 | } | ||
| 76 | |||
| 77 | info[0] = (uint32_t)n; | ||
| 78 | info[1] = 9; /* Known max pruning value */ | ||
| 79 | DBG_ASSERT(n == COCSEP_CLASSES, 0, | ||
| 80 | "cocsep: computed %" PRIu16 " symmetry classes, " | ||
| 81 | "expected %zu\n", n, COCSEP_CLASSES); | ||
| 82 | |||
| 83 | LOG("cocsep data computed\n"); | ||
| 84 | LOG("Symmetry classes: %" PRIu32 "\n", info[0]); | ||
| 85 | LOG("Maximum pruning value: %" PRIu32 "\n", info[1]); | ||
| 86 | LOG("Pruning value distribution:\n"); | ||
| 87 | for (j = 0; j < 10; j++) | ||
| 88 | LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]); | ||
| 89 | |||
| 90 | gendata_cocsep_return_size: | ||
| 91 | return COCSEP_FULLSIZE; | ||
| 92 | } | ||
| 93 | |||
| 94 | _static uint32_t | ||
| 95 | gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | ||
| 96 | { | ||
| 97 | uint8_t m; | ||
| 98 | uint32_t cc, class, ttrep, depth, olddepth, tinv; | ||
| 99 | uint64_t t; | ||
| 100 | int64_t i, j; | ||
| 101 | cube_t d; | ||
| 102 | dfsarg_cocsep_t nextarg; | ||
| 103 | |||
| 104 | i = coord_cocsep(arg->cube); | ||
| 105 | olddepth = (uint8_t)(arg->buf32[i] & 0xFF); | ||
| 106 | if (olddepth < arg->depth || get_visited(arg->visited, i)) | ||
| 107 | return 0; | ||
| 108 | set_visited(arg->visited, i); | ||
| 109 | |||
| 110 | if (arg->depth == arg->maxdepth) { | ||
| 111 | if ((arg->buf32[i] & 0xFF) != 0xFF) | ||
| 112 | return 0; | ||
| 113 | |||
| 114 | if (arg->rep != NULL) | ||
| 115 | arg->rep[*arg->n] = arg->cube; | ||
| 116 | for (t = 0, cc = 0; t < 48; t++) { | ||
| 117 | d = transform_corners(arg->cube, t); | ||
| 118 | j = coord_cocsep(d); | ||
| 119 | if (i == j && arg->selfsim != NULL) | ||
| 120 | arg->selfsim[*arg->n] |= UINT64_C(1) << t; | ||
| 121 | if (COCLASS(arg->buf32[j]) != UINT32_C(0xFFFF)) | ||
| 122 | continue; | ||
| 123 | set_visited(arg->visited, j); | ||
| 124 | tinv = inverse_trans(t); | ||
| 125 | olddepth = arg->buf32[j] & 0xFF; | ||
| 126 | cc += olddepth == 0xFF; | ||
| 127 | |||
| 128 | class = (uint32_t)(*arg->n) << UINT32_C(16); | ||
| 129 | ttrep = (uint32_t)tinv << UINT32_C(8); | ||
| 130 | depth = (uint32_t)arg->depth; | ||
| 131 | arg->buf32[j] = class | ttrep | depth; | ||
| 132 | } | ||
| 133 | (*arg->n)++; | ||
| 134 | |||
| 135 | return cc; | ||
| 136 | } | ||
| 137 | |||
| 138 | memcpy(&nextarg, arg, sizeof(dfsarg_cocsep_t)); | ||
| 139 | nextarg.depth++; | ||
| 140 | for (m = 0, cc = 0; m < 18; m++) { | ||
| 141 | nextarg.cube = move(arg->cube, m); | ||
| 142 | cc += gendata_cocsep_dfs(&nextarg); | ||
| 143 | } | ||
| 144 | |||
| 145 | return cc; | ||
| 146 | } | ||
| 147 | |||
| 148 | _static_inline bool | ||
| 149 | get_visited(const uint8_t *a, int64_t i) | ||
| 150 | { | ||
| 151 | return a[VISITED_IND(i)] & VISITED_MASK(i); | ||
| 152 | } | ||
| 153 | |||
| 154 | _static_inline void | ||
| 155 | set_visited(uint8_t *a, int64_t i) | ||
| 156 | { | ||
| 157 | a[VISITED_IND(i)] |= VISITED_MASK(i); | ||
| 158 | } | ||
| 159 | |||
| 160 | _static_inline int8_t | ||
| 161 | get_h48_cdata(cube_t cube, uint32_t *cocsepdata, uint32_t *cdata) | ||
| 162 | { | ||
| 163 | int64_t coord; | ||
| 164 | |||
| 165 | coord = coord_cocsep(cube); | ||
| 166 | *cdata = cocsepdata[coord]; | ||
| 167 | |||
| 168 | return CBOUND(*cdata); | ||
| 169 | } | ||
diff --git a/src/solvers/h48/gendata.h b/src/solvers/h48/gendata_full.h index d6bf85b..be234d9 100644 --- a/src/solvers/h48/gendata.h +++ b/src/solvers/h48/gendata_full.h | |||
| @@ -1,8 +1,3 @@ | |||
| 1 | #define COCSEP_CLASSES ((size_t)3393) | ||
| 2 | #define COCSEP_TABLESIZE ((size_t)_3p7 << (size_t)7) | ||
| 3 | #define COCSEP_VISITEDSIZE ((COCSEP_TABLESIZE + (size_t)7) / (size_t)8) | ||
| 4 | #define COCSEP_FULLSIZE ((size_t)4 * (COCSEP_TABLESIZE + (size_t)12)) | ||
| 5 | |||
| 6 | #define ESEP_NOEO (COCSEP_CLASSES * (size_t)_12c4 * (size_t)_8c4) | 1 | #define ESEP_NOEO (COCSEP_CLASSES * (size_t)_12c4 * (size_t)_8c4) |
| 7 | #define ESEP_MAX(h) (ESEP_NOEO << (size_t)(h)) | 2 | #define ESEP_MAX(h) (ESEP_NOEO << (size_t)(h)) |
| 8 | #define ESEP_TABLESIZE(h, k) (ESEP_MAX((h)) / ((size_t)8 / (size_t)(k))) | 3 | #define ESEP_TABLESIZE(h, k) (ESEP_MAX((h)) / ((size_t)8 / (size_t)(k))) |
| @@ -10,11 +5,6 @@ | |||
| 10 | #define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8)) | 5 | #define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8)) |
| 11 | #define ESEP_SHIFT(i) (UINT32_C(4) * ((uint32_t)(i) % UINT32_C(8))) | 6 | #define ESEP_SHIFT(i) (UINT32_C(4) * ((uint32_t)(i) % UINT32_C(8))) |
| 12 | #define ESEP_MASK(i) ((_bit_u32(4) - (uint32_t)(1)) << ESEP_SHIFT(i)) | 7 | #define ESEP_MASK(i) ((_bit_u32(4) - (uint32_t)(1)) << ESEP_SHIFT(i)) |
| 13 | #define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8)) | ||
| 14 | #define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8))) | ||
| 15 | |||
| 16 | #define CBOUND_MASK UINT32_C(0xFF) | ||
| 17 | #define CBOUND(x) ((x) & CBOUND_MASK) | ||
| 18 | 8 | ||
| 19 | #define MAXLEN 20 | 9 | #define MAXLEN 20 |
| 20 | 10 | ||
| @@ -38,25 +28,19 @@ _t by _ttrep). | |||
| 38 | } | 28 | } |
| 39 | 29 | ||
| 40 | typedef struct { | 30 | typedef struct { |
| 41 | cube_t cube; | 31 | uint8_t h; |
| 42 | uint8_t depth; | 32 | uint8_t k; |
| 43 | uint8_t maxdepth; | 33 | uint8_t maxdepth; |
| 44 | uint16_t *n; | 34 | void * buf; |
| 45 | uint32_t *buf32; | 35 | } gendata_h48_arg_t; |
| 46 | uint8_t *visited; | ||
| 47 | uint64_t *selfsim; | ||
| 48 | cube_t *rep; | ||
| 49 | } dfsarg_cocsep_t; | ||
| 50 | 36 | ||
| 51 | /* TODO keep or not? */ | ||
| 52 | typedef struct { | 37 | typedef struct { |
| 53 | cube_t cube; | 38 | uint8_t maxdepth; |
| 54 | int8_t nmoves; | 39 | const uint32_t *cocsepdata; |
| 55 | int8_t depth; | 40 | const cube_t *crep; |
| 56 | uint8_t moves[MAXLEN]; | 41 | const uint64_t *selfsim; |
| 57 | uint32_t *cocsepdata; | 42 | h48map_t *map; |
| 58 | h48map_t *visited; | 43 | } gendata_h48short_arg_t; |
| 59 | } dfsarg_genh48set_t; | ||
| 60 | 44 | ||
| 61 | typedef struct { | 45 | typedef struct { |
| 62 | uint8_t depth; | 46 | uint8_t depth; |
| @@ -67,148 +51,22 @@ typedef struct { | |||
| 67 | cube_t *crep; | 51 | cube_t *crep; |
| 68 | } bfsarg_esep_t; | 52 | } bfsarg_esep_t; |
| 69 | 53 | ||
| 70 | _static_inline bool get_visited(const uint8_t *, int64_t); | ||
| 71 | _static_inline void set_visited(uint8_t *, int64_t); | ||
| 72 | _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); | 54 | _static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); |
| 73 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); | 55 | _static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); |
| 74 | 56 | ||
| 75 | _static size_t gendata_cocsep(void *, uint64_t *, cube_t *); | 57 | _static uint64_t gen_h48short(gendata_h48short_arg_t *); |
| 76 | _static uint32_t gendata_cocsep_dfs(dfsarg_cocsep_t *); | 58 | _static size_t gendata_h48(gendata_h48_arg_t *); |
| 77 | _static uint64_t gen_h48short( | ||
| 78 | uint8_t, const uint32_t *, const cube_t *, const uint64_t *, h48map_t *); | ||
| 79 | _static size_t gendata_h48h0k4(void *, uint8_t); | 59 | _static size_t gendata_h48h0k4(void *, uint8_t); |
| 80 | _static int64_t gendata_h48h0k4_bfs(bfsarg_esep_t *); | 60 | _static int64_t gendata_h48h0k4_bfs(bfsarg_esep_t *); |
| 81 | _static int64_t gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *); | 61 | _static int64_t gendata_h48h0k4_bfs_fromdone(bfsarg_esep_t *); |
| 82 | _static int64_t gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *); | 62 | _static int64_t gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *); |
| 63 | _static size_t gendata_h48k2(void *, uint8_t, uint8_t); | ||
| 83 | 64 | ||
| 84 | _static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *); | ||
| 85 | _static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *); | 65 | _static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *); |
| 86 | 66 | ||
| 87 | /* | ||
| 88 | Each element of the cocsep table is a uint32_t used as follows: | ||
| 89 | - Lowest 8-bit block: pruning value | ||
| 90 | - Second-lowest 8-bit block: "ttrep" (transformation to representative) | ||
| 91 | - Top 16-bit block: symcoord value | ||
| 92 | After the data as described above, more auxiliary information is appended: | ||
| 93 | - A uint32_t representing the number of symmetry classes | ||
| 94 | - A uint32_t representing the highest value of the pruning table | ||
| 95 | - One uint32_t for each "line" of the pruning table, representing the number | ||
| 96 | of positions having that pruning value. | ||
| 97 | */ | ||
| 98 | _static size_t | ||
| 99 | gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep) | ||
| 100 | { | ||
| 101 | uint32_t *buf32, *info, cc; | ||
| 102 | uint16_t n; | ||
| 103 | uint8_t i, j, visited[COCSEP_VISITEDSIZE]; | ||
| 104 | dfsarg_cocsep_t arg; | ||
| 105 | |||
| 106 | if (buf == NULL) | ||
| 107 | goto gendata_cocsep_return_size; | ||
| 108 | |||
| 109 | buf32 = (uint32_t *)buf; | ||
| 110 | info = buf32 + COCSEP_TABLESIZE; | ||
| 111 | memset(buf32, 0xFF, sizeof(uint32_t) * COCSEP_TABLESIZE); | ||
| 112 | if (selfsim != NULL) | ||
| 113 | memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); | ||
| 114 | |||
| 115 | arg = (dfsarg_cocsep_t) { | ||
| 116 | .cube = solved, | ||
| 117 | .n = &n, | ||
| 118 | .buf32 = buf32, | ||
| 119 | .visited = visited, | ||
| 120 | .selfsim = selfsim, | ||
| 121 | .rep = rep | ||
| 122 | }; | ||
| 123 | for (i = 0, n = 0, cc = 0; i < 10; i++) { | ||
| 124 | LOG("cocsep: generating depth %" PRIu8 "\n", i); | ||
| 125 | memset(visited, 0, COCSEP_VISITEDSIZE); | ||
| 126 | arg.depth = 0; | ||
| 127 | arg.maxdepth = i; | ||
| 128 | cc = gendata_cocsep_dfs(&arg); | ||
| 129 | info[i+2] = cc; | ||
| 130 | LOG("found %" PRIu32 "\n", cc); | ||
| 131 | } | ||
| 132 | |||
| 133 | info[0] = (uint32_t)n; | ||
| 134 | info[1] = 9; /* Known max pruning value */ | ||
| 135 | DBG_ASSERT(n == COCSEP_CLASSES, 0, | ||
| 136 | "cocsep: computed %" PRIu16 " symmetry classes, " | ||
| 137 | "expected %zu\n", n, COCSEP_CLASSES); | ||
| 138 | |||
| 139 | LOG("cocsep data computed\n"); | ||
| 140 | LOG("Symmetry classes: %" PRIu32 "\n", info[0]); | ||
| 141 | LOG("Maximum pruning value: %" PRIu32 "\n", info[1]); | ||
| 142 | LOG("Pruning value distribution:\n"); | ||
| 143 | for (j = 0; j < 10; j++) | ||
| 144 | LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, info[j+2]); | ||
| 145 | |||
| 146 | gendata_cocsep_return_size: | ||
| 147 | return COCSEP_FULLSIZE; | ||
| 148 | } | ||
| 149 | |||
| 150 | _static uint32_t | ||
| 151 | gendata_cocsep_dfs(dfsarg_cocsep_t *arg) | ||
| 152 | { | ||
| 153 | uint8_t m; | ||
| 154 | uint32_t cc, class, ttrep, depth, olddepth, tinv; | ||
| 155 | uint64_t t; | ||
| 156 | int64_t i, j; | ||
| 157 | cube_t d; | ||
| 158 | dfsarg_cocsep_t nextarg; | ||
| 159 | |||
| 160 | i = coord_cocsep(arg->cube); | ||
| 161 | olddepth = (uint8_t)(arg->buf32[i] & 0xFF); | ||
| 162 | if (olddepth < arg->depth || get_visited(arg->visited, i)) | ||
| 163 | return 0; | ||
| 164 | set_visited(arg->visited, i); | ||
| 165 | |||
| 166 | if (arg->depth == arg->maxdepth) { | ||
| 167 | if ((arg->buf32[i] & 0xFF) != 0xFF) | ||
| 168 | return 0; | ||
| 169 | |||
| 170 | if (arg->rep != NULL) | ||
| 171 | arg->rep[*arg->n] = arg->cube; | ||
| 172 | for (t = 0, cc = 0; t < 48; t++) { | ||
| 173 | d = transform_corners(arg->cube, t); | ||
| 174 | j = coord_cocsep(d); | ||
| 175 | if (i == j && arg->selfsim != NULL) | ||
| 176 | arg->selfsim[*arg->n] |= UINT64_C(1) << t; | ||
| 177 | if (COCLASS(arg->buf32[j]) != UINT32_C(0xFFFF)) | ||
| 178 | continue; | ||
| 179 | set_visited(arg->visited, j); | ||
| 180 | tinv = inverse_trans(t); | ||
| 181 | olddepth = arg->buf32[j] & 0xFF; | ||
| 182 | cc += olddepth == 0xFF; | ||
| 183 | |||
| 184 | class = (uint32_t)(*arg->n) << UINT32_C(16); | ||
| 185 | ttrep = (uint32_t)tinv << UINT32_C(8); | ||
| 186 | depth = (uint32_t)arg->depth; | ||
| 187 | arg->buf32[j] = class | ttrep | depth; | ||
| 188 | } | ||
| 189 | (*arg->n)++; | ||
| 190 | |||
| 191 | return cc; | ||
| 192 | } | ||
| 193 | |||
| 194 | memcpy(&nextarg, arg, sizeof(dfsarg_cocsep_t)); | ||
| 195 | nextarg.depth++; | ||
| 196 | for (m = 0, cc = 0; m < 18; m++) { | ||
| 197 | nextarg.cube = move(arg->cube, m); | ||
| 198 | cc += gendata_cocsep_dfs(&nextarg); | ||
| 199 | } | ||
| 200 | |||
| 201 | return cc; | ||
| 202 | } | ||
| 203 | |||
| 204 | _static uint64_t | 67 | _static uint64_t |
| 205 | gen_h48short( | 68 | gen_h48short(gendata_h48short_arg_t *arg) |
| 206 | uint8_t n, | 69 | { |
| 207 | const uint32_t *cocsepdata, | ||
| 208 | const cube_t *crep, | ||
| 209 | const uint64_t *selfsim, | ||
| 210 | h48map_t *map | ||
| 211 | ) { | ||
| 212 | uint8_t i, m; | 70 | uint8_t i, m; |
| 213 | int64_t coord; | 71 | int64_t coord; |
| 214 | uint64_t j, oldn; | 72 | uint64_t j, oldn; |
| @@ -216,33 +74,48 @@ gen_h48short( | |||
| 216 | cube_t cube, d; | 74 | cube_t cube, d; |
| 217 | 75 | ||
| 218 | cube = solvedcube(); | 76 | cube = solvedcube(); |
| 219 | coord = coord_h48(cube, cocsepdata, 11); | 77 | coord = coord_h48(cube, arg->cocsepdata, 11); |
| 220 | h48map_insertmin(map, coord, 0); | 78 | h48map_insertmin(arg->map, coord, 0); |
| 221 | oldn = 0; | 79 | oldn = 0; |
| 222 | LOG("Short h48: generating depth 0\nfound %" PRIu8 "\n", map->n-oldn); | 80 | LOG("Short h48: depth 0\nfound %" PRIu8 "\n", arg->map->n-oldn); |
| 223 | for (i = 0; i < n; i++) { | 81 | for (i = 0; i < arg->maxdepth; i++) { |
| 224 | LOG("Short h48: generating depth %" PRIu8 "\n", i+1); | 82 | LOG("Short h48: depth %" PRIu8 "\n", i+1); |
| 225 | j = 0; | 83 | j = 0; |
| 226 | oldn = map->n; | 84 | oldn = arg->map->n; |
| 227 | for (kv = h48map_nextkvpair(map, &j); | 85 | for (kv = h48map_nextkvpair(arg->map, &j); |
| 228 | j != map->capacity; | 86 | j != arg->map->capacity; |
| 229 | kv = h48map_nextkvpair(map, &j) | 87 | kv = h48map_nextkvpair(arg->map, &j) |
| 230 | ) { | 88 | ) { |
| 231 | if (kv.val != i) | 89 | if (kv.val != i) |
| 232 | continue; | 90 | continue; |
| 233 | cube = invcoord_h48(kv.key, crep, 11); | 91 | cube = invcoord_h48(kv.key, arg->crep, 11); |
| 234 | for (m = 0; m < 18; m++) { | 92 | for (m = 0; m < 18; m++) { |
| 235 | d = move(cube, m); | 93 | d = move(cube, m); |
| 236 | _foreach_h48sim(d, cocsepdata, selfsim, 11, | 94 | _foreach_h48sim( |
| 237 | coord = coord_h48(d, cocsepdata, 11); | 95 | d, arg->cocsepdata, arg->selfsim, 11, |
| 238 | h48map_insertmin(map, coord, i+1); | 96 | coord = coord_h48(d, arg->cocsepdata, 11); |
| 97 | h48map_insertmin(arg->map, coord, i+1); | ||
| 239 | ) | 98 | ) |
| 240 | } | 99 | } |
| 241 | } | 100 | } |
| 242 | LOG("found %" PRIu8 "\n", map->n-oldn); | 101 | LOG("found %" PRIu8 "\n", arg->map->n-oldn); |
| 243 | } | 102 | } |
| 244 | 103 | ||
| 245 | return map->n; | 104 | return arg->map->n; |
| 105 | } | ||
| 106 | |||
| 107 | /* Generic function that dispatches to the data generators */ | ||
| 108 | _static size_t | ||
| 109 | gendata_h48(gendata_h48_arg_t *arg) | ||
| 110 | { | ||
| 111 | if (arg->h == 0 && arg->k == 4) { | ||
| 112 | return gendata_h48h0k4(arg->buf, arg->maxdepth); | ||
| 113 | } else if (arg->k == 2) { | ||
| 114 | return gendata_h48k2(arg->buf, arg->h, arg->maxdepth); | ||
| 115 | } | ||
| 116 | |||
| 117 | LOG("Cannot generate data for h = %" PRIu8 " and k = %" PRIu8 | ||
| 118 | " (not implemented yet)\n", arg->h, arg->k); | ||
| 246 | } | 119 | } |
| 247 | 120 | ||
| 248 | /* | 121 | /* |
| @@ -259,14 +132,13 @@ gendata_h48h0k4(void *buf, uint8_t maxdepth) | |||
| 259 | cube_t crep[COCSEP_CLASSES]; | 132 | cube_t crep[COCSEP_CLASSES]; |
| 260 | size_t cocsepsize, infosize; | 133 | size_t cocsepsize, infosize; |
| 261 | 134 | ||
| 135 | if (buf == NULL) | ||
| 136 | goto gendata_h48h0k4_return_size; | ||
| 137 | |||
| 262 | /* TODO: move info at start of tables (all tables!) */ | 138 | /* TODO: move info at start of tables (all tables!) */ |
| 263 | infosize = 4 * maxdepth; | ||
| 264 | cocsepsize = gendata_cocsep(buf, selfsim, crep); | 139 | cocsepsize = gendata_cocsep(buf, selfsim, crep); |
| 265 | infosize = 88; | 140 | infosize = 88; |
| 266 | 141 | ||
| 267 | if (buf == NULL) | ||
| 268 | goto gendata_h48h0k4_return_size; | ||
| 269 | |||
| 270 | esep_max = (int64_t)ESEP_MAX(0); | 142 | esep_max = (int64_t)ESEP_MAX(0); |
| 271 | cocsepdata = (uint32_t *)buf; | 143 | cocsepdata = (uint32_t *)buf; |
| 272 | buf32 = cocsepdata + cocsepsize / 4; | 144 | buf32 = cocsepdata + cocsepsize / 4; |
| @@ -379,16 +251,59 @@ gendata_h48h0k4_bfs_fromnew(bfsarg_esep_t *arg) | |||
| 379 | return cc; | 251 | return cc; |
| 380 | } | 252 | } |
| 381 | 253 | ||
| 382 | _static_inline bool | 254 | _static size_t |
| 383 | get_visited(const uint8_t *a, int64_t i) | 255 | gendata_h48k2(void *buf, uint8_t h, uint8_t maxdepth) |
| 384 | { | 256 | { |
| 385 | return a[VISITED_IND(i)] & VISITED_MASK(i); | 257 | static uint64_t capacity = 10000019; /* First prime after 1e8 */ |
| 386 | } | 258 | static uint64_t randomizer = 10000079; /* Second prime after 1e8 */ |
| 259 | static uint8_t base[] = { | ||
| 260 | [0] = 8, | ||
| 261 | [1] = 8, | ||
| 262 | [2] = 8, | ||
| 263 | [3] = 8, | ||
| 264 | [4] = 9, | ||
| 265 | [5] = 9, | ||
| 266 | [6] = 9, | ||
| 267 | [7] = 9, | ||
| 268 | [8] = 10, | ||
| 269 | [9] = 10, | ||
| 270 | [10] = 10, | ||
| 271 | [11] = 10 | ||
| 272 | }; | ||
| 387 | 273 | ||
| 388 | _static_inline void | 274 | uint64_t nshort; |
| 389 | set_visited(uint8_t *a, int64_t i) | 275 | uint32_t *buf32, *info, *cocsepdata; |
| 390 | { | 276 | h48map_t depth8cubes; |
| 391 | a[VISITED_IND(i)] |= VISITED_MASK(i); | 277 | gendata_h48short_arg_t shortarg; |
| 278 | uint64_t selfsim[COCSEP_CLASSES]; | ||
| 279 | cube_t crep[COCSEP_CLASSES]; | ||
| 280 | size_t cocsepsize, infosize; | ||
| 281 | |||
| 282 | DBG_ASSERT(base[h] == 8, 0, "Only implemented for h <= 3 (base 8)\n"); | ||
| 283 | |||
| 284 | if (buf == NULL) | ||
| 285 | goto gendata_h48k2_return_size; | ||
| 286 | |||
| 287 | cocsepdata = (uint32_t *)buf; | ||
| 288 | cocsepsize = gendata_cocsep(buf, selfsim, crep); | ||
| 289 | infosize = 88; | ||
| 290 | |||
| 291 | h48map_create(&depth8cubes, capacity, randomizer); | ||
| 292 | shortarg = (gendata_h48short_arg_t) { | ||
| 293 | .maxdepth = 8, | ||
| 294 | .cocsepdata = cocsepdata, | ||
| 295 | .crep = crep, | ||
| 296 | .selfsim = selfsim, | ||
| 297 | .map = &depth8cubes | ||
| 298 | }; | ||
| 299 | |||
| 300 | nshort = gen_h48short(&shortarg); | ||
| 301 | LOG("%" PRIu64 "\n", nshort); | ||
| 302 | |||
| 303 | h48map_destroy(&depth8cubes); | ||
| 304 | |||
| 305 | gendata_h48k2_return_size: | ||
| 306 | return cocsepsize + ESEP_TABLESIZE(h, 2) + infosize; | ||
| 392 | } | 307 | } |
| 393 | 308 | ||
| 394 | _static_inline uint8_t | 309 | _static_inline uint8_t |
| @@ -405,17 +320,6 @@ set_esep_pval(uint32_t *buf32, int64_t i, uint8_t val) | |||
| 405 | } | 320 | } |
| 406 | 321 | ||
| 407 | _static_inline int8_t | 322 | _static_inline int8_t |
| 408 | get_h48_cdata(cube_t cube, uint32_t *cocsepdata, uint32_t *cdata) | ||
| 409 | { | ||
| 410 | int64_t coord; | ||
| 411 | |||
| 412 | coord = coord_cocsep(cube); | ||
| 413 | *cdata = cocsepdata[coord]; | ||
| 414 | |||
| 415 | return CBOUND(*cdata); | ||
| 416 | } | ||
| 417 | |||
| 418 | _static_inline int8_t | ||
| 419 | get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint32_t *h48data) | 323 | get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint32_t *h48data) |
| 420 | { | 324 | { |
| 421 | int64_t coord; | 325 | int64_t coord; |
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h index d33ad63..d9e8af3 100644 --- a/src/solvers/h48/h48.h +++ b/src/solvers/h48/h48.h | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include "coordinate.h" | 1 | #include "coordinate.h" |
| 2 | #include "map.h" | 2 | #include "map.h" |
| 3 | #include "gendata.h" | 3 | #include "gendata_cocsep.h" |
| 4 | #include "gendata_full.h" | ||
| 4 | #include "solve.h" | 5 | #include "solve.h" |
