diff options
25 files changed, 302 insertions, 70 deletions
| @@ -8,6 +8,7 @@ tables/* | |||
| 8 | test/*/runtest | 8 | test/*/runtest |
| 9 | test/run | 9 | test/run |
| 10 | test/run.DSYM | 10 | test/run.DSYM |
| 11 | run.DSYM | ||
| 11 | test/last.* | 12 | test/last.* |
| 12 | tools/results | 13 | tools/results |
| 13 | .vscode | 14 | .vscode |
diff --git a/src/core/cube.h b/src/core/cube.h index fe36f90..4b28103 100644 --- a/src/core/cube.h +++ b/src/core/cube.h | |||
| @@ -13,11 +13,13 @@ _static cube_t frommoves(const char *); | |||
| 13 | _static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); | 13 | _static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); |
| 14 | _static cube_t getcube(int64_t, int64_t, int64_t, int64_t); | 14 | _static cube_t getcube(int64_t, int64_t, int64_t, int64_t); |
| 15 | 15 | ||
| 16 | _static cube_t move(cube_t, uint8_t); | ||
| 17 | _static cube_t transform_edges(cube_t, uint8_t); | 16 | _static cube_t transform_edges(cube_t, uint8_t); |
| 18 | _static cube_t transform_corners(cube_t, uint8_t); | 17 | _static cube_t transform_corners(cube_t, uint8_t); |
| 19 | _static cube_t transform(cube_t, uint8_t); | 18 | _static cube_t transform(cube_t, uint8_t); |
| 20 | 19 | ||
| 20 | /* declared in moves.h */ | ||
| 21 | _static cube_t move(cube_t, uint8_t); | ||
| 22 | |||
| 21 | _static cube_t | 23 | _static cube_t |
| 22 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) | 24 | cubefromarray(uint8_t c[static 8], uint8_t e[static 12]) |
| 23 | { | 25 | { |
| @@ -239,52 +241,6 @@ applytrans(cube_t cube, const char *buf) | |||
| 239 | return transform(cube, t); | 241 | return transform(cube, t); |
| 240 | } | 242 | } |
| 241 | 243 | ||
| 242 | _static cube_t | ||
| 243 | move(cube_t c, uint8_t m) | ||
| 244 | { | ||
| 245 | switch (m) { | ||
| 246 | case _move_U: | ||
| 247 | return _move(U, c); | ||
| 248 | case _move_U2: | ||
| 249 | return _move(U2, c); | ||
| 250 | case _move_U3: | ||
| 251 | return _move(U3, c); | ||
| 252 | case _move_D: | ||
| 253 | return _move(D, c); | ||
| 254 | case _move_D2: | ||
| 255 | return _move(D2, c); | ||
| 256 | case _move_D3: | ||
| 257 | return _move(D3, c); | ||
| 258 | case _move_R: | ||
| 259 | return _move(R, c); | ||
| 260 | case _move_R2: | ||
| 261 | return _move(R2, c); | ||
| 262 | case _move_R3: | ||
| 263 | return _move(R3, c); | ||
| 264 | case _move_L: | ||
| 265 | return _move(L, c); | ||
| 266 | case _move_L2: | ||
| 267 | return _move(L2, c); | ||
| 268 | case _move_L3: | ||
| 269 | return _move(L3, c); | ||
| 270 | case _move_F: | ||
| 271 | return _move(F, c); | ||
| 272 | case _move_F2: | ||
| 273 | return _move(F2, c); | ||
| 274 | case _move_F3: | ||
| 275 | return _move(F3, c); | ||
| 276 | case _move_B: | ||
| 277 | return _move(B, c); | ||
| 278 | case _move_B2: | ||
| 279 | return _move(B2, c); | ||
| 280 | case _move_B3: | ||
| 281 | return _move(B3, c); | ||
| 282 | default: | ||
| 283 | LOG("move error, unknown move\n"); | ||
| 284 | return zero; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | 244 | /* |
| 289 | TODO transform is now relegated to a separated file because it is too long. | 245 | TODO transform is now relegated to a separated file because it is too long. |
| 290 | It would be nice to make it shorter without loosing performance. | 246 | It would be nice to make it shorter without loosing performance. |
diff --git a/src/core/moves.h b/src/core/moves.h index 7da6405..8f9c8f5 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -1,7 +1,23 @@ | |||
| 1 | /* probably these can be placed in constants file */ | ||
| 2 | #define NORMAL 0x00 | ||
| 3 | #define INVERSE 0x01 | ||
| 4 | #define INVERSEBRANCH 0x03 | ||
| 5 | #define NORMALBRANCH 0x02 | ||
| 6 | #define ALLMOVES 0x3FFFF | ||
| 7 | #define NOHALFTURNS 0x2DB6D | ||
| 8 | |||
| 1 | _static_inline bool allowednextmove(uint8_t *, uint8_t); | 9 | _static_inline bool allowednextmove(uint8_t *, uint8_t); |
| 10 | _static uint32_t allowednextmoveH48(uint8_t *, uint8_t, uint32_t); | ||
| 11 | |||
| 2 | _static_inline uint8_t inverse_trans(uint8_t); | 12 | _static_inline uint8_t inverse_trans(uint8_t); |
| 3 | _static_inline uint8_t movebase(uint8_t); | 13 | _static_inline uint8_t movebase(uint8_t); |
| 4 | _static_inline uint8_t moveaxis(uint8_t); | 14 | _static_inline uint8_t moveaxis(uint8_t); |
| 15 | _static_inline uint32_t disable_moves(uint32_t, uint8_t); | ||
| 16 | |||
| 17 | _static cube_t move(cube_t, uint8_t); | ||
| 18 | _static cube_t premove(cube_t, uint8_t); | ||
| 19 | _static uint8_t inverse_move(uint8_t); | ||
| 20 | _static uint8_t* invertpremoves(uint8_t *, uint8_t); | ||
| 5 | 21 | ||
| 6 | _static bool | 22 | _static bool |
| 7 | allowednextmove(uint8_t *moves, uint8_t n) | 23 | allowednextmove(uint8_t *moves, uint8_t n) |
| @@ -28,6 +44,40 @@ allowednextmove(uint8_t *moves, uint8_t n) | |||
| 28 | return axis[1] != axis[2] || base[0] != base[2]; | 44 | return axis[1] != axis[2] || base[0] != base[2]; |
| 29 | } | 45 | } |
| 30 | 46 | ||
| 47 | _static_inline uint32_t | ||
| 48 | disable_moves(uint32_t current_result, uint8_t base_index) | ||
| 49 | { | ||
| 50 | return current_result & ~(7 << base_index); | ||
| 51 | } | ||
| 52 | |||
| 53 | _static uint32_t | ||
| 54 | allowednextmoveH48(uint8_t *moves, uint8_t n, uint32_t h48branch) | ||
| 55 | { | ||
| 56 | uint32_t result = ALLMOVES; | ||
| 57 | if (h48branch & NORMALBRANCH) | ||
| 58 | result &= NOHALFTURNS; | ||
| 59 | if (n < 1) | ||
| 60 | return result; | ||
| 61 | |||
| 62 | uint8_t base1 = movebase(moves[n-1]); | ||
| 63 | uint8_t axis1 = moveaxis(moves[n-1]); | ||
| 64 | |||
| 65 | result = disable_moves(result, base1 * 3); | ||
| 66 | if (base1 % 2) | ||
| 67 | result = disable_moves(result, (base1 - 1) * 3); | ||
| 68 | |||
| 69 | if (n == 1) | ||
| 70 | return result; | ||
| 71 | |||
| 72 | uint8_t base2 = movebase(moves[n-2]); | ||
| 73 | uint8_t axis2 = moveaxis(moves[n-2]); | ||
| 74 | |||
| 75 | if(axis1 == axis2) | ||
| 76 | result = disable_moves(result, base2 * 3); | ||
| 77 | |||
| 78 | return result; | ||
| 79 | } | ||
| 80 | |||
| 31 | _static_inline uint8_t | 81 | _static_inline uint8_t |
| 32 | inverse_trans(uint8_t t) | 82 | inverse_trans(uint8_t t) |
| 33 | { | 83 | { |
| @@ -45,3 +95,116 @@ moveaxis(uint8_t move) | |||
| 45 | { | 95 | { |
| 46 | return move / 6; | 96 | return move / 6; |
| 47 | } | 97 | } |
| 98 | |||
| 99 | _static cube_t | ||
| 100 | move(cube_t c, uint8_t m) | ||
| 101 | { | ||
| 102 | switch (m) { | ||
| 103 | case _move_U: | ||
| 104 | return _move(U, c); | ||
| 105 | case _move_U2: | ||
| 106 | return _move(U2, c); | ||
| 107 | case _move_U3: | ||
| 108 | return _move(U3, c); | ||
| 109 | case _move_D: | ||
| 110 | return _move(D, c); | ||
| 111 | case _move_D2: | ||
| 112 | return _move(D2, c); | ||
| 113 | case _move_D3: | ||
| 114 | return _move(D3, c); | ||
| 115 | case _move_R: | ||
| 116 | return _move(R, c); | ||
| 117 | case _move_R2: | ||
| 118 | return _move(R2, c); | ||
| 119 | case _move_R3: | ||
| 120 | return _move(R3, c); | ||
| 121 | case _move_L: | ||
| 122 | return _move(L, c); | ||
| 123 | case _move_L2: | ||
| 124 | return _move(L2, c); | ||
| 125 | case _move_L3: | ||
| 126 | return _move(L3, c); | ||
| 127 | case _move_F: | ||
| 128 | return _move(F, c); | ||
| 129 | case _move_F2: | ||
| 130 | return _move(F2, c); | ||
| 131 | case _move_F3: | ||
| 132 | return _move(F3, c); | ||
| 133 | case _move_B: | ||
| 134 | return _move(B, c); | ||
| 135 | case _move_B2: | ||
| 136 | return _move(B2, c); | ||
| 137 | case _move_B3: | ||
| 138 | return _move(B3, c); | ||
| 139 | default: | ||
| 140 | LOG("move error, unknown move\n"); | ||
| 141 | return zero; | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | _static cube_t | ||
| 146 | premove(cube_t c, uint8_t m) | ||
| 147 | { | ||
| 148 | switch (m) { | ||
| 149 | case _move_U: | ||
| 150 | return _premove(U3, c); | ||
| 151 | case _move_U2: | ||
| 152 | return _premove(U2, c); | ||
| 153 | case _move_U3: | ||
| 154 | return _premove(U, c); | ||
| 155 | case _move_D: | ||
| 156 | return _premove(D3, c); | ||
| 157 | case _move_D2: | ||
| 158 | return _premove(D2, c); | ||
| 159 | case _move_D3: | ||
| 160 | return _premove(D, c); | ||
| 161 | case _move_R: | ||
| 162 | return _premove(R3, c); | ||
| 163 | case _move_R2: | ||
| 164 | return _premove(R2, c); | ||
| 165 | case _move_R3: | ||
| 166 | return _premove(R, c); | ||
| 167 | case _move_L: | ||
| 168 | return _premove(L3, c); | ||
| 169 | case _move_L2: | ||
| 170 | return _premove(L2, c); | ||
| 171 | case _move_L3: | ||
| 172 | return _premove(L, c); | ||
| 173 | case _move_F: | ||
| 174 | return _premove(F3, c); | ||
| 175 | case _move_F2: | ||
| 176 | return _premove(F2, c); | ||
| 177 | case _move_F3: | ||
| 178 | return _premove(F, c); | ||
| 179 | case _move_B: | ||
| 180 | return _premove(B3, c); | ||
| 181 | case _move_B2: | ||
| 182 | return _premove(B2, c); | ||
| 183 | case _move_B3: | ||
| 184 | return _premove(B, c); | ||
| 185 | default: | ||
| 186 | LOG("move error, unknown move\n"); | ||
| 187 | return zero; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | _static uint8_t | ||
| 192 | inverse_move(uint8_t m) | ||
| 193 | { | ||
| 194 | return m - 2 * (m % 3) + 2; | ||
| 195 | } | ||
| 196 | |||
| 197 | _static uint8_t* | ||
| 198 | invertpremoves(uint8_t *moves, uint8_t nmoves) | ||
| 199 | { | ||
| 200 | uint8_t i; | ||
| 201 | uint8_t *ret = malloc(nmoves * sizeof(uint8_t)); | ||
| 202 | |||
| 203 | for (i = 0; i < nmoves; i++) | ||
| 204 | ret[i] = inverse_move(moves[i]); | ||
| 205 | |||
| 206 | // invert elements in the array | ||
| 207 | for (i = 0; i < nmoves / 2; i++) | ||
| 208 | _swap(ret[i], ret[nmoves - i - 1]); | ||
| 209 | return ret; | ||
| 210 | } | ||
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 0843792..bbe59e5 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -11,6 +11,9 @@ typedef struct { | |||
| 11 | uint32_t *cocsepdata; | 11 | uint32_t *cocsepdata; |
| 12 | uint32_t *h48data; | 12 | uint32_t *h48data; |
| 13 | char **nextsol; | 13 | char **nextsol; |
| 14 | uint8_t nissbranch; | ||
| 15 | int8_t npremoves; | ||
| 16 | uint8_t premoves[MAXLEN]; | ||
| 14 | } dfsarg_solveh48_t; | 17 | } dfsarg_solveh48_t; |
| 15 | 18 | ||
| 16 | typedef struct { | 19 | typedef struct { |
| @@ -26,8 +29,7 @@ typedef struct { | |||
| 26 | _static void solve_h48_appendsolution(dfsarg_solveh48_t *); | 29 | _static void solve_h48_appendsolution(dfsarg_solveh48_t *); |
| 27 | _static_inline bool solve_h48_stop(dfsarg_solveh48_t *); | 30 | _static_inline bool solve_h48_stop(dfsarg_solveh48_t *); |
| 28 | _static int64_t solve_h48_dfs(dfsarg_solveh48_t *); | 31 | _static int64_t solve_h48_dfs(dfsarg_solveh48_t *); |
| 29 | _static int64_t solve_h48( | 32 | _static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, uint8_t, const void *, char *); |
| 30 | cube_t, int8_t, int8_t, int8_t, uint8_t, uint8_t, const void *, char *); | ||
| 31 | 33 | ||
| 32 | _static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); | 34 | _static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *); |
| 33 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); | 35 | _static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]); |
| @@ -36,10 +38,22 @@ _static void | |||
| 36 | solve_h48_appendsolution(dfsarg_solveh48_t *arg) | 38 | solve_h48_appendsolution(dfsarg_solveh48_t *arg) |
| 37 | { | 39 | { |
| 38 | int strl; | 40 | int strl; |
| 41 | char *solution = *arg->nextsol; | ||
| 39 | 42 | ||
| 40 | strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol); | 43 | strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol); |
| 41 | LOG("Solution found: %s\n", *arg->nextsol); | 44 | *arg->nextsol += strl; |
| 42 | *arg->nextsol += strl; | 45 | |
| 46 | if (arg->npremoves) { | ||
| 47 | **arg->nextsol = ' '; | ||
| 48 | (*arg->nextsol)++; | ||
| 49 | |||
| 50 | uint8_t* invertedpremoves = invertpremoves(arg->premoves, arg->npremoves); | ||
| 51 | strl = writemoves(invertedpremoves, arg->npremoves, *arg->nextsol); | ||
| 52 | free(invertedpremoves); | ||
| 53 | *arg->nextsol += strl; | ||
| 54 | } | ||
| 55 | LOG("Solution found: %s\n", solution); | ||
| 56 | |||
| 43 | **arg->nextsol = '\n'; | 57 | **arg->nextsol = '\n'; |
| 44 | (*arg->nextsol)++; | 58 | (*arg->nextsol)++; |
| 45 | (*arg->nsols)++; | 59 | (*arg->nsols)++; |
| @@ -51,24 +65,27 @@ solve_h48_stop(dfsarg_solveh48_t *arg) | |||
| 51 | uint32_t data, data_inv; | 65 | uint32_t data, data_inv; |
| 52 | int8_t bound; | 66 | int8_t bound; |
| 53 | 67 | ||
| 68 | arg->nissbranch = NORMAL; | ||
| 54 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data); | 69 | bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data); |
| 55 | if (bound + arg->nmoves > arg->depth) | 70 | if (bound + arg->nmoves + arg->npremoves > arg->depth) |
| 56 | return true; | 71 | return true; |
| 57 | 72 | ||
| 58 | bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv); | 73 | bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv); |
| 59 | if (bound + arg->nmoves > arg->depth) | 74 | if (bound + arg->nmoves + arg->npremoves > arg->depth) |
| 60 | return true; | 75 | return true; |
| 61 | 76 | ||
| 62 | /* | ||
| 63 | bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data); | 77 | bound = get_h48_bound(arg->cube, data, arg->h, arg->k, arg->h48data); |
| 64 | LOG("Using pval %" PRId8 "\n", bound); | 78 | // LOG("Using pval %" PRId8 "\n", bound); |
| 65 | if (bound + arg->nmoves > arg->depth) | 79 | if (bound + arg->nmoves + arg->npremoves > arg->depth) |
| 66 | return true; | 80 | return true; |
| 81 | if (bound + arg->nmoves + arg->npremoves == arg->depth) | ||
| 82 | arg->nissbranch = INVERSEBRANCH; | ||
| 67 | 83 | ||
| 68 | bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->k, arg->h48data); | 84 | bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->k, arg->h48data); |
| 69 | if (bound + arg->nmoves > arg->depth) | 85 | if (bound + arg->nmoves + arg->npremoves > arg->depth) |
| 70 | return true; | 86 | return true; |
| 71 | */ | 87 | if (bound + arg->nmoves + arg->npremoves == arg->depth) |
| 88 | arg->nissbranch = NORMALBRANCH; | ||
| 72 | 89 | ||
| 73 | return false; | 90 | return false; |
| 74 | } | 91 | } |
| @@ -87,7 +104,7 @@ solve_h48_dfs(dfsarg_solveh48_t *arg) | |||
| 87 | return 0; | 104 | return 0; |
| 88 | 105 | ||
| 89 | if (issolved(arg->cube)) { | 106 | if (issolved(arg->cube)) { |
| 90 | if (arg->nmoves != arg->depth) | 107 | if (arg->nmoves + arg->npremoves != arg->depth) |
| 91 | return 0; | 108 | return 0; |
| 92 | solve_h48_appendsolution(arg); | 109 | solve_h48_appendsolution(arg); |
| 93 | return 1; | 110 | return 1; |
| @@ -95,19 +112,30 @@ solve_h48_dfs(dfsarg_solveh48_t *arg) | |||
| 95 | 112 | ||
| 96 | /* TODO: avoid copy, change arg and undo changes after recursion */ | 113 | /* TODO: avoid copy, change arg and undo changes after recursion */ |
| 97 | nextarg = *arg; | 114 | nextarg = *arg; |
| 98 | nextarg.nmoves = arg->nmoves + 1; | ||
| 99 | ret = 0; | 115 | ret = 0; |
| 100 | for (m = 0; m < 18; m++) { | 116 | uint32_t allowed; |
| 101 | nextarg.moves[arg->nmoves] = m; | 117 | if(arg->nissbranch & INVERSE) { |
| 102 | if (!allowednextmove(nextarg.moves, nextarg.nmoves)) { | 118 | allowed = allowednextmoveH48(arg->premoves, arg->npremoves, arg->nissbranch); |
| 103 | /* If a move is not allowed, neither are its 180 | 119 | for (m = 0; m < 18; m++) { |
| 104 | * and 270 degree variations */ | 120 | if(allowed & (1 << m)) { |
| 105 | m += 2; | 121 | nextarg.npremoves = arg->npremoves + 1; |
| 106 | continue; | 122 | nextarg.premoves[arg->npremoves] = m; |
| 123 | nextarg.inverse = move(arg->inverse, m); | ||
| 124 | nextarg.cube = premove(arg->cube, m); | ||
| 125 | ret += solve_h48_dfs(&nextarg); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } else { | ||
| 129 | allowed = allowednextmoveH48(arg->moves, arg->nmoves, arg->nissbranch); | ||
| 130 | for (m = 0; m < 18; m++) { | ||
| 131 | if (allowed & (1 << m)) { | ||
| 132 | nextarg.nmoves = arg->nmoves + 1; | ||
| 133 | nextarg.moves[arg->nmoves] = m; | ||
| 134 | nextarg.cube = move(arg->cube, m); | ||
| 135 | nextarg.inverse = premove(arg->inverse, m); | ||
| 136 | ret += solve_h48_dfs(&nextarg); | ||
| 137 | } | ||
| 107 | } | 138 | } |
| 108 | nextarg.cube = move(arg->cube, m); | ||
| 109 | nextarg.inverse = inverse(nextarg.cube); /* TODO: use premove */ | ||
| 110 | ret += solve_h48_dfs(&nextarg); | ||
| 111 | } | 139 | } |
| 112 | 140 | ||
| 113 | return ret; | 141 | return ret; |
| @@ -148,6 +176,7 @@ solve_h48( | |||
| 148 | LOG("Found %" PRId64 " solutions, searching at depth %" | 176 | LOG("Found %" PRId64 " solutions, searching at depth %" |
| 149 | PRId8 "\n", nsols, arg.depth); | 177 | PRId8 "\n", nsols, arg.depth); |
| 150 | arg.nmoves = 0; | 178 | arg.nmoves = 0; |
| 179 | arg.npremoves = 0; | ||
| 151 | solve_h48_dfs(&arg); | 180 | solve_h48_dfs(&arg); |
| 152 | } | 181 | } |
| 153 | 182 | ||
diff --git a/test/082_allowednext_h48/00_empty_U.in b/test/082_allowednext_h48/00_empty_U.in new file mode 100644 index 0000000..28271a6 --- /dev/null +++ b/test/082_allowednext_h48/00_empty_U.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 0 | ||
| 2 | 0 | ||
| 3 | |||
diff --git a/test/082_allowednext_h48/00_empty_U.out b/test/082_allowednext_h48/00_empty_U.out new file mode 100644 index 0000000..8607955 --- /dev/null +++ b/test/082_allowednext_h48/00_empty_U.out | |||
| @@ -0,0 +1 @@ | |||
| 0x3FFFF | |||
diff --git a/test/082_allowednext_h48/01_F.in b/test/082_allowednext_h48/01_F.in new file mode 100644 index 0000000..e7ae375 --- /dev/null +++ b/test/082_allowednext_h48/01_F.in | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 0 | ||
| 2 | 1 | ||
| 3 | F | ||
| 4 | |||
diff --git a/test/082_allowednext_h48/01_F.out b/test/082_allowednext_h48/01_F.out new file mode 100644 index 0000000..5d6f843 --- /dev/null +++ b/test/082_allowednext_h48/01_F.out | |||
| @@ -0,0 +1 @@ | |||
| 0x38FFF | |||
diff --git a/test/082_allowednext_h48/02_U2.in b/test/082_allowednext_h48/02_U2.in new file mode 100644 index 0000000..2c5ee5f --- /dev/null +++ b/test/082_allowednext_h48/02_U2.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 0 | ||
| 2 | 1 | ||
| 3 | U | ||
diff --git a/test/082_allowednext_h48/02_U2.out b/test/082_allowednext_h48/02_U2.out new file mode 100644 index 0000000..a9a5adb --- /dev/null +++ b/test/082_allowednext_h48/02_U2.out | |||
| @@ -0,0 +1 @@ | |||
| 0x3FFF8 | |||
diff --git a/test/082_allowednext_h48/03_R_L.in b/test/082_allowednext_h48/03_R_L.in new file mode 100644 index 0000000..b6c0625 --- /dev/null +++ b/test/082_allowednext_h48/03_R_L.in | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | 0 | ||
| 2 | 2 | ||
| 3 | R | ||
| 4 | L' | ||
| 5 | |||
diff --git a/test/082_allowednext_h48/03_R_L.out b/test/082_allowednext_h48/03_R_L.out new file mode 100644 index 0000000..a4aa4b2 --- /dev/null +++ b/test/082_allowednext_h48/03_R_L.out | |||
| @@ -0,0 +1 @@ | |||
| 0x3F03F | |||
diff --git a/test/082_allowednext_h48/04_D.in b/test/082_allowednext_h48/04_D.in new file mode 100644 index 0000000..83da556 --- /dev/null +++ b/test/082_allowednext_h48/04_D.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 0 | ||
| 2 | 1 | ||
| 3 | D | ||
diff --git a/test/082_allowednext_h48/04_D.out b/test/082_allowednext_h48/04_D.out new file mode 100644 index 0000000..fe91843 --- /dev/null +++ b/test/082_allowednext_h48/04_D.out | |||
| @@ -0,0 +1 @@ | |||
| 0x3FFC0 | |||
diff --git a/test/082_allowednext_h48/05_U_F_B2.in b/test/082_allowednext_h48/05_U_F_B2.in new file mode 100644 index 0000000..67e090f --- /dev/null +++ b/test/082_allowednext_h48/05_U_F_B2.in | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | 0 | ||
| 2 | 2 | ||
| 3 | U | ||
| 4 | F | ||
| 5 | |||
diff --git a/test/082_allowednext_h48/05_U_F_B2.out b/test/082_allowednext_h48/05_U_F_B2.out new file mode 100644 index 0000000..5d6f843 --- /dev/null +++ b/test/082_allowednext_h48/05_U_F_B2.out | |||
| @@ -0,0 +1 @@ | |||
| 0x38FFF | |||
diff --git a/test/082_allowednext_h48/06_empty_bound.in b/test/082_allowednext_h48/06_empty_bound.in new file mode 100644 index 0000000..389e262 --- /dev/null +++ b/test/082_allowednext_h48/06_empty_bound.in | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | 2 | ||
| 2 | 0 | ||
diff --git a/test/082_allowednext_h48/06_empty_bound.out b/test/082_allowednext_h48/06_empty_bound.out new file mode 100644 index 0000000..eb601fc --- /dev/null +++ b/test/082_allowednext_h48/06_empty_bound.out | |||
| @@ -0,0 +1 @@ | |||
| 0x2DB6D | |||
diff --git a/test/082_allowednext_h48/07_F_bound.in b/test/082_allowednext_h48/07_F_bound.in new file mode 100644 index 0000000..b3ae33d --- /dev/null +++ b/test/082_allowednext_h48/07_F_bound.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 2 | ||
| 2 | 1 | ||
| 3 | F | ||
diff --git a/test/082_allowednext_h48/07_F_bound.out b/test/082_allowednext_h48/07_F_bound.out new file mode 100644 index 0000000..0dc8997 --- /dev/null +++ b/test/082_allowednext_h48/07_F_bound.out | |||
| @@ -0,0 +1 @@ | |||
| 0x28B6D | |||
diff --git a/test/082_allowednext_h48/08_U_D_bound_inverse.in b/test/082_allowednext_h48/08_U_D_bound_inverse.in new file mode 100644 index 0000000..707f7e0 --- /dev/null +++ b/test/082_allowednext_h48/08_U_D_bound_inverse.in | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 3 | ||
| 2 | 2 | ||
| 3 | U | ||
| 4 | D2 \ No newline at end of file | ||
diff --git a/test/082_allowednext_h48/08_U_D_bound_inverse.out b/test/082_allowednext_h48/08_U_D_bound_inverse.out new file mode 100644 index 0000000..6f47cf0 --- /dev/null +++ b/test/082_allowednext_h48/08_U_D_bound_inverse.out | |||
| @@ -0,0 +1 @@ | |||
| 0x2DB40 | |||
diff --git a/test/082_allowednext_h48/09_R_false_bound.in b/test/082_allowednext_h48/09_R_false_bound.in new file mode 100644 index 0000000..0b1d441 --- /dev/null +++ b/test/082_allowednext_h48/09_R_false_bound.in | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | 1 | ||
| 2 | 1 | ||
| 3 | R \ No newline at end of file | ||
diff --git a/test/082_allowednext_h48/09_R_false_bound.out b/test/082_allowednext_h48/09_R_false_bound.out new file mode 100644 index 0000000..121bfeb --- /dev/null +++ b/test/082_allowednext_h48/09_R_false_bound.out | |||
| @@ -0,0 +1 @@ | |||
| 0x3FE3F | |||
diff --git a/test/082_allowednext_h48/allowednext_h48_tests.c b/test/082_allowednext_h48/allowednext_h48_tests.c new file mode 100644 index 0000000..4cee695 --- /dev/null +++ b/test/082_allowednext_h48/allowednext_h48_tests.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #include "../test.h" | ||
| 2 | |||
| 3 | uint32_t allowednextmoveH48(uint8_t *, uint8_t, uint32_t); | ||
| 4 | |||
| 5 | static char *moves[] = { | ||
| 6 | "U", "U2", "U'", | ||
| 7 | "D", "D2", "D'", | ||
| 8 | "R", "R2", "R'", | ||
| 9 | "L", "L2", "L'", | ||
| 10 | "F", "F2", "F'", | ||
| 11 | "B", "B2", "B'", | ||
| 12 | }; | ||
| 13 | |||
| 14 | void run(void) { | ||
| 15 | char movestr[STRLENMAX]; | ||
| 16 | uint8_t m[100]; | ||
| 17 | int n, i, j, bound; | ||
| 18 | |||
| 19 | fgets(movestr, STRLENMAX, stdin); | ||
| 20 | bound = atoi(movestr); | ||
| 21 | |||
| 22 | fgets(movestr, STRLENMAX, stdin); | ||
| 23 | n = atoi(movestr); | ||
| 24 | |||
| 25 | for (i = 0; i < n; i++) { | ||
| 26 | fgets(movestr, STRLENMAX, stdin); | ||
| 27 | movestr[strcspn(movestr, "\n")] = 0; | ||
| 28 | for (j = 0; j < 18; j++) | ||
| 29 | if (!strcmp(movestr, moves[j])) | ||
| 30 | m[i] = j; | ||
| 31 | } | ||
| 32 | |||
| 33 | fprintf(stderr, "Last two: %s, %s\n", | ||
| 34 | n > 1 ? moves[m[n-2]] : "-", | ||
| 35 | n > 0 ? moves[m[n-1]] : "-"); | ||
| 36 | uint32_t allowed = allowednextmoveH48(m, n, bound); | ||
| 37 | printf("0x%05X\n", allowed); | ||
| 38 | } | ||
