diff options
Diffstat (limited to 'old/2021-02-18-piecefilter/src/solve.c')
| -rw-r--r-- | old/2021-02-18-piecefilter/src/solve.c | 179 |
1 files changed, 0 insertions, 179 deletions
diff --git a/old/2021-02-18-piecefilter/src/solve.c b/old/2021-02-18-piecefilter/src/solve.c deleted file mode 100644 index ac19d6f..0000000 --- a/old/2021-02-18-piecefilter/src/solve.c +++ /dev/null | |||
| @@ -1,179 +0,0 @@ | |||
| 1 | #include "solve.h" | ||
| 2 | |||
| 3 | /* Data for creating a pruning table: | ||
| 4 | - compressed: if set to true, each entry occupies only 4 bits, but values | ||
| 5 | larger than 15 cannot be stored. | ||
| 6 | - available[] is the list of availabel moves, as above. | ||
| 7 | - *ptable is the actual table to fill. | ||
| 8 | - n is the number of states (size of ptable). | ||
| 9 | - index must "linearize" the cube, i.e. return its index in ptable. | ||
| 10 | - fname is the name of the file where to store the table */ | ||
| 11 | typedef struct { | ||
| 12 | bool compressed, *available; | ||
| 13 | int max_moves; | ||
| 14 | uint8_t *ptable; | ||
| 15 | uint64_t n; | ||
| 16 | uint64_t (*index)(Cube); | ||
| 17 | char *fname; | ||
| 18 | } PruneData; | ||
| 19 | |||
| 20 | /* TODO: comment this */ | ||
| 21 | typedef struct { | ||
| 22 | bool niss; | ||
| 23 | int m, d; | ||
| 24 | uint64_t *n; | ||
| 25 | Move last1, last2; | ||
| 26 | } DfsData; | ||
| 27 | |||
| 28 | void solve_dfs(Cube cube, SolveData *sd, DfsData dd); | ||
| 29 | void init_ptable(PruneData *pd, bool read, bool write); | ||
| 30 | |||
| 31 | /* Search solutions of lenght exactly d */ | ||
| 32 | void solve_dfs(Cube cube, SolveData *sd, DfsData dd) { | ||
| 33 | if (*dd.n >= sd->max_solutions || | ||
| 34 | ((!sd->can_niss || dd.niss) && dd.m + sd->f(cube) > dd.d)) | ||
| 35 | return; | ||
| 36 | |||
| 37 | (sd->solutions[*dd.n][dd.m]).inverse = dd.niss; | ||
| 38 | (sd->solutions[*dd.n][dd.m]).m = NULLMOVE; | ||
| 39 | |||
| 40 | if (!sd->f(cube)) { /* Solved */ | ||
| 41 | if (dd.m == dd.d) { | ||
| 42 | (*dd.n)++; | ||
| 43 | if (*dd.n < sd->max_solutions) | ||
| 44 | copy_alg(sd->solutions[*dd.n-1], sd->solutions[*dd.n]); | ||
| 45 | } | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | |||
| 49 | for (int i = 0; i < NMOVES && sd->sorted_moves[i] != NULLMOVE; i++) { | ||
| 50 | Move move = sd->sorted_moves[i]; | ||
| 51 | if (possible_next[dd.last2][dd.last1][move]) { | ||
| 52 | sd->solutions[*dd.n][dd.m].inverse = dd.niss; | ||
| 53 | sd->solutions[*dd.n][dd.m].m = move; | ||
| 54 | DfsData nn = { .niss = dd.niss, .m = dd.m+1, .d = dd.d, .n = dd.n, | ||
| 55 | .last1 = move, .last2 = dd.last1 }; | ||
| 56 | solve_dfs(move_cube(move, cube), sd, nn); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | if (sd->can_niss && !dd.niss && | ||
| 61 | (!dd.m || (dd.m && sd->f(move_cube(dd.last1, blank_cube()))))) { | ||
| 62 | DfsData nn = { .niss = true, .m = dd.m, .d = dd.d, .n = dd.n }; | ||
| 63 | solve_dfs(inverse_cube(cube), sd, nn); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | /* Iterative deepening depth-first search: for i running from the minimum | ||
| 68 | to the maximum number of moves allowed, looks for solutions of length i. */ | ||
| 69 | int solve(Cube cube, SolveData *sd) { | ||
| 70 | if (sd->precondition != NULL && !sd->precondition(cube)) | ||
| 71 | return -1; | ||
| 72 | |||
| 73 | /* If not given, generate sorted list of moves */ | ||
| 74 | if (sd->sorted_moves[0] == NULLMOVE) { | ||
| 75 | int a[NMOVES], b[NMOVES], ia = 0, ib = 0; | ||
| 76 | for (int i = 0; i < NMOVES; i++) { | ||
| 77 | if (sd->available[i]) { | ||
| 78 | if (sd->f(move_cube(i, blank_cube()))) | ||
| 79 | a[ia++] = i; | ||
| 80 | else | ||
| 81 | b[ib++] = i; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | intarrcopy(a, (int *)sd->sorted_moves, ia); | ||
| 85 | intarrcopy(b, (int *)sd->sorted_moves+ia, ib); | ||
| 86 | sd->sorted_moves[ia+ib] = NULLMOVE; | ||
| 87 | } | ||
| 88 | |||
| 89 | sd->max_solutions = min(sd->max_solutions, MAXS); | ||
| 90 | /*TODO | ||
| 91 | Cube rotated = apply_alg(sd->pre_rotation, blank_cube()); | ||
| 92 | cube = apply_alg(inverse_cube(rotated), compose(cube, rotated)); | ||
| 93 | */ | ||
| 94 | |||
| 95 | uint64_t ret = 0; | ||
| 96 | for (int i=sd->min_moves; i<=sd->max_moves&&!(ret&&sd->optimal_only); i++) { | ||
| 97 | DfsData dd = { .d = i, .n = &ret }; | ||
| 98 | solve_dfs(cube, sd, dd); | ||
| 99 | } | ||
| 100 | |||
| 101 | for (uint64_t i = 0; i < ret; i++) { | ||
| 102 | /* TODO: transform solutions with inverse of pre_rotation */ | ||
| 103 | if (sd->cleanup) | ||
| 104 | cleanup(sd->solutions[i], sd->max_moves*3); | ||
| 105 | } | ||
| 106 | |||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | void prune_dfs(Cube cube, PruneData *pd, DfsData dd) { | ||
| 111 | uint64_t ind = pd->index(cube); | ||
| 112 | if ((!ind || pd->ptable[ind]) && pd->ptable[ind] != dd.m) | ||
| 113 | return; | ||
| 114 | if (dd.m == dd.d) { | ||
| 115 | if (ind && !pd->ptable[ind]) { | ||
| 116 | pd->ptable[ind] = dd.m; | ||
| 117 | (*dd.n)++; | ||
| 118 | } | ||
| 119 | return; | ||
| 120 | } | ||
| 121 | |||
| 122 | for (int i = 0; i < NMOVES; i++) { | ||
| 123 | if (dd.m<20) | ||
| 124 | if (possible_next[dd.last2][dd.last1][i] && pd->available[i]) { | ||
| 125 | DfsData nn = { .m = dd.m+1, .d = dd.d, .n = dd.n, | ||
| 126 | .last1 = i, .last2 = dd.last1 }; | ||
| 127 | prune_dfs(move_cube(i, cube), pd, nn); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | void init_ptable(PruneData *pd, bool read, bool write) { | ||
| 133 | if (read) { | ||
| 134 | FILE *ptf; | ||
| 135 | if ((ptf = fopen(pd->fname, "rb")) != NULL) { | ||
| 136 | fread(pd->ptable, sizeof(uint8_t), pd->n, ptf); | ||
| 137 | fclose(ptf); | ||
| 138 | return; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | /* TODO: for now it behaves always as if copressed = false */ | ||
| 143 | for (uint64_t i = 0; i < pd->n; i++) | ||
| 144 | pd->ptable[i] = 0; | ||
| 145 | |||
| 146 | uint64_t s = 1; | ||
| 147 | for (int i = 1; i < pd->max_moves && s < pd->n; i++) { | ||
| 148 | DfsData dd = { .d = i, .n = &s }; | ||
| 149 | prune_dfs(blank_cube(), pd, dd); | ||
| 150 | } | ||
| 151 | |||
| 152 | if (write) { | ||
| 153 | FILE *ptf; | ||
| 154 | if ((ptf = fopen(pd->fname, "wb")) != NULL) { | ||
| 155 | fwrite(pd->ptable, sizeof(uint8_t), pd->n, ptf); | ||
| 156 | fclose(ptf); | ||
| 157 | return; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | /* Solving steps (and indexing functions) */ | ||
| 163 | |||
| 164 | uint64_t index_eofb(Cube cube) { return cube.eofb; } | ||
| 165 | uint16_t f_eofb(Cube cube) { | ||
| 166 | static bool initialized_ptable; | ||
| 167 | static uint8_t pt_eofb[pow2to11]; | ||
| 168 | if (!initialized_ptable) { | ||
| 169 | PruneData pd = { | ||
| 170 | .compressed = false, .available = standard_moveset, .max_moves = 13, | ||
| 171 | .ptable = pt_eofb, .n = pow2to11, .index = index_eofb, | ||
| 172 | .fname = "ptable_eofb" | ||
| 173 | }; | ||
| 174 | init_ptable(&pd, false, true); | ||
| 175 | initialized_ptable = true; | ||
| 176 | } | ||
| 177 | return cube.eofb ? pt_eofb[cube.eofb] : 0; | ||
| 178 | } | ||
| 179 | |||
