diff options
Diffstat (limited to 'src/solvers/coord/coord_solve.h')
| -rw-r--r-- | src/solvers/coord/coord_solve.h | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/src/solvers/coord/coord_solve.h b/src/solvers/coord/coord_solve.h index 1d7c036..317cb33 100644 --- a/src/solvers/coord/coord_solve.h +++ b/src/solvers/coord/coord_solve.h | |||
| @@ -1,3 +1,228 @@ | |||
| 1 | #include "coord_types_macros.h" | 1 | #include "coord_types_macros.h" |
| 2 | #include "common.h" | 2 | #include "common.h" |
| 3 | #include "gendata_coord.h" | 3 | #include "gendata_coord.h" |
| 4 | |||
| 5 | #define MAXLEN_COORDSOL 20 | ||
| 6 | |||
| 7 | typedef struct { | ||
| 8 | cube_t cube; | ||
| 9 | uint8_t depth; | ||
| 10 | uint8_t nmoves; | ||
| 11 | uint8_t moves[MAXLEN_COORDSOL]; | ||
| 12 | coord_t *coord; | ||
| 13 | const void *coord_data; | ||
| 14 | const uint8_t *ptable; | ||
| 15 | uint8_t trans; | ||
| 16 | int64_t *nsols; | ||
| 17 | int64_t maxsolutions; | ||
| 18 | int optimal; | ||
| 19 | uint8_t *shortest_sol; | ||
| 20 | uint64_t solutions_size; | ||
| 21 | uint64_t *solutions_used; | ||
| 22 | char **solutions; | ||
| 23 | } dfsarg_solve_coord_t; | ||
| 24 | |||
| 25 | STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t, | ||
| 26 | uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char); | ||
| 27 | STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t, | ||
| 28 | uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char); | ||
| 29 | STATIC bool solve_coord_appendchar(char *, uint64_t, uint64_t *, char); | ||
| 30 | STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *); | ||
| 31 | STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *); | ||
| 32 | |||
| 33 | STATIC int64_t | ||
| 34 | solve_coord_appendsolution(dfsarg_solve_coord_t *arg) | ||
| 35 | { | ||
| 36 | uint8_t i, t, tmoves[MAXLEN_COORDSOL]; | ||
| 37 | |||
| 38 | if (*arg->nsols >= arg->maxsolutions || | ||
| 39 | arg->nmoves > *arg->shortest_sol + arg->optimal) | ||
| 40 | return 0; | ||
| 41 | |||
| 42 | sortparallel(arg->moves, arg->nmoves); | ||
| 43 | |||
| 44 | t = inverse_trans(arg->trans); | ||
| 45 | for (i = 0; i < arg->nmoves; i++) | ||
| 46 | tmoves[i] = transform_move(arg->moves[i], t); | ||
| 47 | |||
| 48 | /* TODO append tmoves[] */ | ||
| 49 | |||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | |||
| 53 | STATIC bool | ||
| 54 | solve_coord_appendchar(char *s, uint64_t s_size, uint64_t *s_used, char c) | ||
| 55 | { | ||
| 56 | if (s_size == *s_used) | ||
| 57 | return false; | ||
| 58 | |||
| 59 | s[*s_used] = c; | ||
| 60 | (*s_used)++; | ||
| 61 | |||
| 62 | return true; | ||
| 63 | } | ||
| 64 | |||
| 65 | STATIC int64_t | ||
| 66 | solve_coord_dfs(dfsarg_solve_coord_t *arg) | ||
| 67 | { | ||
| 68 | uint64_t coord; | ||
| 69 | uint8_t pval; | ||
| 70 | |||
| 71 | coord = arg->coord->coord(arg->cube, arg->coord_data); | ||
| 72 | |||
| 73 | if (coord == 0) { | ||
| 74 | if (arg->nmoves != arg->depth) | ||
| 75 | return 0; | ||
| 76 | return solve_coord_appendsolution(arg); | ||
| 77 | } | ||
| 78 | |||
| 79 | pval = get_coord_pval(arg->coord, arg->ptable, coord); | ||
| 80 | if (arg->nmoves + pval > arg->depth) | ||
| 81 | return 0; | ||
| 82 | |||
| 83 | /* TODO recursive call */ | ||
| 84 | /* Is allowednextmove available here? */ | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | |||
| 89 | STATIC int64_t | ||
| 90 | solve_coord_dispatch( | ||
| 91 | cube_t cube, | ||
| 92 | const char *coord_axis, | ||
| 93 | uint8_t nissflag, | ||
| 94 | uint8_t minmoves, | ||
| 95 | uint8_t maxmoves, | ||
| 96 | uint64_t maxsolutions, | ||
| 97 | int optimal, | ||
| 98 | int threads, | ||
| 99 | uint64_t data_size, | ||
| 100 | const void *data, | ||
| 101 | uint64_t sols_size, | ||
| 102 | char *sols | ||
| 103 | ) | ||
| 104 | { | ||
| 105 | int i, n; | ||
| 106 | coord_t *coord; | ||
| 107 | uint8_t axis; | ||
| 108 | |||
| 109 | n = strlen(coord_axis); | ||
| 110 | for (i = 0; coord_axis[i] != ' ' && coord_axis[i] != '\0'; i++) ; | ||
| 111 | |||
| 112 | coord = parse_coord(coord_axis, i); | ||
| 113 | axis = parse_axis(coord_axis + i + 1, n - i - 1); | ||
| 114 | |||
| 115 | if (coord == NULL) { | ||
| 116 | LOG("Could not parse coordinate '%s'\n", coord_axis); | ||
| 117 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 118 | } | ||
| 119 | |||
| 120 | if (axis == UINT8_ERROR) { | ||
| 121 | LOG("Could not parse axis from '%s'\n", coord_axis); | ||
| 122 | return NISSY_ERROR_INVALID_SOLVER; | ||
| 123 | } | ||
| 124 | |||
| 125 | return solve_coord(cube, coord, axis, nissflag, minmoves, maxmoves, | ||
| 126 | maxsolutions, optimal, threads, data_size, data, sols_size, sols); | ||
| 127 | } | ||
| 128 | |||
| 129 | STATIC int64_t | ||
| 130 | solve_coord( | ||
| 131 | cube_t cube, | ||
| 132 | coord_t *coord, | ||
| 133 | uint8_t axis, | ||
| 134 | uint8_t nissflag, | ||
| 135 | uint8_t minmoves, | ||
| 136 | uint8_t maxmoves, | ||
| 137 | uint64_t maxsolutions, | ||
| 138 | int optimal, | ||
| 139 | int threads, | ||
| 140 | uint64_t data_size, | ||
| 141 | const void data, | ||
| 142 | uint64_t sols_size, | ||
| 143 | char *sols | ||
| 144 | ) | ||
| 145 | { | ||
| 146 | int8_t d; | ||
| 147 | uint8_t t, shortest_sol; | ||
| 148 | int64_t nsols; | ||
| 149 | uint64_t sols_used; | ||
| 150 | cube_t c; | ||
| 151 | const void *coord_data; | ||
| 152 | const uint8_t *ptable; | ||
| 153 | dfsarg_solve_coord_t arg; | ||
| 154 | tableinfo_t info; | ||
| 155 | |||
| 156 | if (readtableinfo(data_size, data, &info) != NISSY_OK) | ||
| 157 | goto solve_coord_error_data; | ||
| 158 | |||
| 159 | if (info.type == TABLETYPE_PRUNING) { | ||
| 160 | /* Only the pruning table */ | ||
| 161 | coord_data = NULL; | ||
| 162 | ptable = (uint8_t *)data + INFOSIZE; | ||
| 163 | } else { | ||
| 164 | /* Coordinate has extra data */ | ||
| 165 | coord_data = data + INFOSIZE; | ||
| 166 | ptable = (uint8_t *)data + info.next + INFOSIZE; | ||
| 167 | } | ||
| 168 | |||
| 169 | nsols = 0; | ||
| 170 | sols_used = 0; | ||
| 171 | shortest_sol = MAXLEN_COORDSOL + 1; | ||
| 172 | c = transform(cube, t); | ||
| 173 | t = coord->axistrans[axis]; | ||
| 174 | |||
| 175 | arg = (dfsarg_solve_coord_t) { | ||
| 176 | .cube = c, | ||
| 177 | .coord = coord, | ||
| 178 | .coord_data = coord_data, | ||
| 179 | .ptable = ptable, | ||
| 180 | .trans = t, | ||
| 181 | .nsols = &nsols, | ||
| 182 | .maxsolutions = (int64_t)maxsolutions, | ||
| 183 | .optimal = optimal, | ||
| 184 | .shortest_sol = &shortest_sol, | ||
| 185 | .solutions_size = sols_size, | ||
| 186 | .solutions_used = &sols_used, | ||
| 187 | .solutions = &sols, | ||
| 188 | }; | ||
| 189 | |||
| 190 | if (coord->coord(c, coord_data) == 0) { | ||
| 191 | if (minmoves == 0) { | ||
| 192 | nsols = 1; | ||
| 193 | if (!solve_coord_appendchar( | ||
| 194 | sols, sols_size, &sols_used, '\n')) | ||
| 195 | goto solve_coord_error_buffer; | ||
| 196 | } | ||
| 197 | goto solve_coord_done; | ||
| 198 | } | ||
| 199 | |||
| 200 | for ( | ||
| 201 | d = MAX(minmoves, 1); | ||
| 202 | d <= maxmoves && nsols < (int64_t)maxsolutions | ||
| 203 | && !(nsols != 0 && d > shortest_sol + optimal); | ||
| 204 | d++ | ||
| 205 | ) { | ||
| 206 | if (d >= 10) | ||
| 207 | LOG("Found %" PRId64 " solutions, searching at depth %" | ||
| 208 | PRId8 "\n", nsols, d); | ||
| 209 | |||
| 210 | arg.depth = d; | ||
| 211 | arg.nmoves = 0; | ||
| 212 | nsols += solve_coord_dfs(&arg); | ||
| 213 | } | ||
| 214 | |||
| 215 | solve_coord_done: | ||
| 216 | if (!solve_coord_appendchar(sols, sols_size, &sols_used, '\0')) | ||
| 217 | goto solve_coord_error_buffer; | ||
| 218 | |||
| 219 | return nsols; | ||
| 220 | |||
| 221 | solve_coord_error_data: | ||
| 222 | LOG("solve_coord: error reading table\n"); | ||
| 223 | return NISSY_ERROR_DATA; | ||
| 224 | |||
| 225 | solve_coord_error_buffer: | ||
| 226 | LOG("Could not append solution to buffer: size too small\n"); | ||
| 227 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 228 | } | ||
