diff options
Diffstat (limited to 'src/solvers/h48')
| -rw-r--r-- | src/solvers/h48/h48.h | 1 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 100 | ||||
| -rw-r--r-- | src/solvers/h48/stats.h | 100 |
3 files changed, 101 insertions, 100 deletions
diff --git a/src/solvers/h48/h48.h b/src/solvers/h48/h48.h index 4edc5ac..18153d1 100644 --- a/src/solvers/h48/h48.h +++ b/src/solvers/h48/h48.h | |||
| @@ -2,4 +2,5 @@ | |||
| 2 | #include "map.h" | 2 | #include "map.h" |
| 3 | #include "gendata_cocsep.h" | 3 | #include "gendata_cocsep.h" |
| 4 | #include "gendata_h48.h" | 4 | #include "gendata_h48.h" |
| 5 | #include "stats.h" | ||
| 5 | #include "solve.h" | 6 | #include "solve.h" |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 4bf55ca..b67aedc 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -16,16 +16,6 @@ typedef struct { | |||
| 16 | uint8_t premoves[MAXLEN]; | 16 | uint8_t premoves[MAXLEN]; |
| 17 | } dfsarg_solveh48_t; | 17 | } dfsarg_solveh48_t; |
| 18 | 18 | ||
| 19 | typedef struct { | ||
| 20 | cube_t cube; | ||
| 21 | int8_t nmoves; | ||
| 22 | int8_t depth; | ||
| 23 | uint8_t moves[MAXLEN]; | ||
| 24 | uint32_t *cocsepdata; | ||
| 25 | uint8_t *h48data; | ||
| 26 | char *s; | ||
| 27 | } dfsarg_solveh48stats_t; | ||
| 28 | |||
| 29 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); | 19 | STATIC uint32_t allowednextmove_h48(uint8_t *, uint8_t, uint32_t); |
| 30 | 20 | ||
| 31 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); | 21 | STATIC void solve_h48_appendsolution(dfsarg_solveh48_t *); |
| @@ -33,9 +23,6 @@ STATIC_INLINE bool solve_h48_stop(dfsarg_solveh48_t *); | |||
| 33 | STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); | 23 | STATIC int64_t solve_h48_dfs(dfsarg_solveh48_t *); |
| 34 | STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); | 24 | STATIC int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, const void *, char *); |
| 35 | 25 | ||
| 36 | STATIC int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | ||
| 37 | STATIC int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | ||
| 38 | |||
| 39 | STATIC uint32_t | 26 | STATIC uint32_t |
| 40 | allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) | 27 | allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) |
| 41 | { | 28 | { |
| @@ -215,90 +202,3 @@ solve_h48( | |||
| 215 | 202 | ||
| 216 | return nsols; | 203 | return nsols; |
| 217 | } | 204 | } |
| 218 | |||
| 219 | /* | ||
| 220 | The h48stats solver computes how many moves it takes to solve to | ||
| 221 | each of the 12 h48 coordinates, one for each value of h from 0 to 11. | ||
| 222 | The solutions array is filled with the length of the solutions. The | ||
| 223 | solution array is therefore not a printable string. | ||
| 224 | */ | ||
| 225 | STATIC int64_t | ||
| 226 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) | ||
| 227 | { | ||
| 228 | const int64_t limit = 11; | ||
| 229 | |||
| 230 | int8_t bound, u; | ||
| 231 | uint8_t m; | ||
| 232 | uint32_t d; | ||
| 233 | int64_t coord, h; | ||
| 234 | dfsarg_solveh48stats_t nextarg; | ||
| 235 | |||
| 236 | /* Check cocsep lower bound (corners only) */ | ||
| 237 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); | ||
| 238 | if (bound + arg->nmoves > arg->depth) | ||
| 239 | return 0; | ||
| 240 | |||
| 241 | /* Check h48 lower bound for h=0 (esep, but no eo) */ | ||
| 242 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); | ||
| 243 | bound = get_h48_bound(arg->cube, d, 0, 4, arg->h48data); | ||
| 244 | if (bound + arg->nmoves > arg->depth) | ||
| 245 | return 0; | ||
| 246 | |||
| 247 | /* Update all other values, if solved */ | ||
| 248 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); | ||
| 249 | for (h = 0; h <= limit; h++) { | ||
| 250 | u = coord >> (11-h) == 0 && arg->s[h] == 99; | ||
| 251 | arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h]; | ||
| 252 | } | ||
| 253 | |||
| 254 | if (arg->s[limit] != 99) | ||
| 255 | return 0; | ||
| 256 | |||
| 257 | nextarg = *arg; | ||
| 258 | nextarg.nmoves = arg->nmoves + 1; | ||
| 259 | for (m = 0; m < 18; m++) { | ||
| 260 | nextarg.moves[arg->nmoves] = m; | ||
| 261 | if (!allowednextmove(nextarg.moves, nextarg.nmoves)) { | ||
| 262 | /* If a move is not allowed, neither are its 180 | ||
| 263 | * and 270 degree variations */ | ||
| 264 | m += 2; | ||
| 265 | continue; | ||
| 266 | } | ||
| 267 | nextarg.cube = move(arg->cube, m); | ||
| 268 | solve_h48stats_dfs(&nextarg); | ||
| 269 | } | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | STATIC int64_t | ||
| 275 | solve_h48stats( | ||
| 276 | cube_t cube, | ||
| 277 | int8_t maxmoves, | ||
| 278 | const void *data, | ||
| 279 | char solutions[static 12] | ||
| 280 | ) | ||
| 281 | { | ||
| 282 | int i; | ||
| 283 | dfsarg_solveh48stats_t arg; | ||
| 284 | |||
| 285 | arg = (dfsarg_solveh48stats_t) { | ||
| 286 | .cube = cube, | ||
| 287 | .cocsepdata = get_cocsepdata_ptr(data), | ||
| 288 | .h48data = get_h48data_ptr(data), | ||
| 289 | .s = solutions | ||
| 290 | }; | ||
| 291 | |||
| 292 | for (i = 0; i < 12; i++) | ||
| 293 | solutions[i] = (char)99; | ||
| 294 | |||
| 295 | for (arg.depth = 0; | ||
| 296 | arg.depth <= maxmoves && solutions[11] == 99; | ||
| 297 | arg.depth++) | ||
| 298 | { | ||
| 299 | arg.nmoves = 0; | ||
| 300 | solve_h48stats_dfs(&arg); | ||
| 301 | } | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
diff --git a/src/solvers/h48/stats.h b/src/solvers/h48/stats.h new file mode 100644 index 0000000..6e78ab5 --- /dev/null +++ b/src/solvers/h48/stats.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /* | ||
| 2 | The h48stats solver computes how many moves it takes to solve to | ||
| 3 | each of the 12 h48 coordinates, one for each value of h from 0 to 11. | ||
| 4 | The solutions array is filled with the length of the solutions. The | ||
| 5 | solutions array is therefore not a printable string. | ||
| 6 | */ | ||
| 7 | |||
| 8 | typedef struct { | ||
| 9 | cube_t cube; | ||
| 10 | int8_t nmoves; | ||
| 11 | int8_t depth; | ||
| 12 | uint8_t moves[MAXLEN]; | ||
| 13 | uint32_t *cocsepdata; | ||
| 14 | uint8_t *h48data; | ||
| 15 | char *s; | ||
| 16 | } dfsarg_solveh48stats_t; | ||
| 17 | |||
| 18 | STATIC int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | ||
| 19 | STATIC int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | ||
| 20 | |||
| 21 | STATIC int64_t | ||
| 22 | solve_h48stats_dfs(dfsarg_solveh48stats_t *arg) | ||
| 23 | { | ||
| 24 | const int64_t limit = 11; | ||
| 25 | |||
| 26 | int8_t bound, u; | ||
| 27 | uint8_t m; | ||
| 28 | uint32_t d; | ||
| 29 | int64_t coord, h; | ||
| 30 | dfsarg_solveh48stats_t nextarg; | ||
| 31 | |||
| 32 | /* Check cocsep lower bound (corners only) */ | ||
| 33 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d); | ||
| 34 | if (bound + arg->nmoves > arg->depth) | ||
| 35 | return 0; | ||
| 36 | |||
| 37 | /* Check h48 lower bound for h=0 (esep, but no eo) */ | ||
| 38 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0); | ||
| 39 | bound = get_h48_bound(arg->cube, d, 0, 4, arg->h48data); | ||
| 40 | if (bound + arg->nmoves > arg->depth) | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | /* Update all other values, if solved */ | ||
| 44 | coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11); | ||
| 45 | for (h = 0; h <= limit; h++) { | ||
| 46 | u = coord >> (11-h) == 0 && arg->s[h] == 99; | ||
| 47 | arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h]; | ||
| 48 | } | ||
| 49 | |||
| 50 | if (arg->s[limit] != 99) | ||
| 51 | return 0; | ||
| 52 | |||
| 53 | nextarg = *arg; | ||
| 54 | nextarg.nmoves = arg->nmoves + 1; | ||
| 55 | for (m = 0; m < 18; m++) { | ||
| 56 | nextarg.moves[arg->nmoves] = m; | ||
| 57 | if (!allowednextmove(nextarg.moves, nextarg.nmoves)) { | ||
| 58 | /* If a move is not allowed, neither are its 180 | ||
| 59 | * and 270 degree variations */ | ||
| 60 | m += 2; | ||
| 61 | continue; | ||
| 62 | } | ||
| 63 | nextarg.cube = move(arg->cube, m); | ||
| 64 | solve_h48stats_dfs(&nextarg); | ||
| 65 | } | ||
| 66 | |||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 70 | STATIC int64_t | ||
| 71 | solve_h48stats( | ||
| 72 | cube_t cube, | ||
| 73 | int8_t maxmoves, | ||
| 74 | const void *data, | ||
| 75 | char solutions[static 12] | ||
| 76 | ) | ||
| 77 | { | ||
| 78 | int i; | ||
| 79 | dfsarg_solveh48stats_t arg; | ||
| 80 | |||
| 81 | arg = (dfsarg_solveh48stats_t) { | ||
| 82 | .cube = cube, | ||
| 83 | .cocsepdata = get_cocsepdata_ptr(data), | ||
| 84 | .h48data = get_h48data_ptr(data), | ||
| 85 | .s = solutions | ||
| 86 | }; | ||
| 87 | |||
| 88 | for (i = 0; i < 12; i++) | ||
| 89 | solutions[i] = (char)99; | ||
| 90 | |||
| 91 | for (arg.depth = 0; | ||
| 92 | arg.depth <= maxmoves && solutions[11] == 99; | ||
| 93 | arg.depth++) | ||
| 94 | { | ||
| 95 | arg.nmoves = 0; | ||
| 96 | solve_h48stats_dfs(&arg); | ||
| 97 | } | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | } | ||
