diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2022-02-25 17:20:30 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2022-02-25 17:20:30 +0100 |
| commit | 06c3b9610b7694db34ee91312d8f3aa2196d7d62 (patch) | |
| tree | 8fe16806bdf9729de8f125ce12100ad58b431a2a | |
| parent | 1485cc87c248e1f56367774ebd4819a97116abcc (diff) | |
| download | nissy-06c3b9610b7694db34ee91312d8f3aa2196d7d62.tar.gz nissy-06c3b9610b7694db34ee91312d8f3aa2196d7d62.zip | |
Added cleanup command
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | TODO.md | 16 | ||||
| -rwxr-xr-x | nissy | bin | 0 -> 326784 bytes | |||
| -rw-r--r-- | src/commands.c | 24 | ||||
| -rw-r--r-- | src/moves.c | 120 | ||||
| -rw-r--r-- | src/moves.h | 1 |
6 files changed, 158 insertions, 7 deletions
| @@ -1,6 +1,6 @@ | |||
| 1 | # See LICENSE file for copyright and license details. | 1 | # See LICENSE file for copyright and license details. |
| 2 | 2 | ||
| 3 | VERSION = 2.0.1 | 3 | VERSION = 2.1-current |
| 4 | 4 | ||
| 5 | PREFIX = /usr/local | 5 | PREFIX = /usr/local |
| 6 | MANPREFIX = ${PREFIX}/share/man | 6 | MANPREFIX = ${PREFIX}/share/man |
| @@ -16,7 +16,7 @@ CC = cc | |||
| 16 | 16 | ||
| 17 | all: nissy | 17 | all: nissy |
| 18 | 18 | ||
| 19 | nissy: | 19 | nissy: clean |
| 20 | ${CC} ${CFLAGS} -o nissy src/*.c | 20 | ${CC} ${CFLAGS} -o nissy src/*.c |
| 21 | 21 | ||
| 22 | nissy.exe: | 22 | nissy.exe: |
| @@ -62,14 +62,18 @@ including e.g. solutions that were not shown because -c) | |||
| 62 | ## Technical stuff | 62 | ## Technical stuff |
| 63 | 63 | ||
| 64 | ### Memory management | 64 | ### Memory management |
| 65 | * free pruning table after solve is done? if so, I need to add another way | 65 | * free pruning table after solve is done? if I do this I need to deafault to a |
| 66 | of doing batch solving (I don't want to re-load the tables every time); | 66 | small table for < 8 moves solutions or smth |
| 67 | for example I could add the possibility of reading scrambles from file, | 67 | * improve multi-threading when solving multiple scrambles |
| 68 | and execute the same solve command to every line; also improve multi-threading: | ||
| 69 | I can just solve one scramble per thread, it's better because there is no lock. | ||
| 70 | * alternative: just add a command "free" to free up memory; it is not | 68 | * alternative: just add a command "free" to free up memory; it is not |
| 71 | user friendly (who wants to manage memory manually?) but on the other hand | 69 | user friendly (who wants to manage memory manually?) but on the other hand |
| 72 | it will only be used by the few who have less than 4(?) Gb of ram. | 70 | it will only be used by the few who have less than 4(?) Gb of ram. |
| 71 | * nissy -M maxmem option for running with at most maxmem memory; if exceeded | ||
| 72 | when loading a pruning table, return failure (or make every solve command | ||
| 73 | use tiny tables instead?); if maxmem is very 600Mb or | ||
| 74 | less do not use invtables (the performance loss is minimal anyway). If the | ||
| 75 | limit is really tiny, do not use mtables or ttables (but this would be | ||
| 76 | very slow and probably nobody will ever use it) | ||
| 73 | * Check if memory is enough for loading pruning tables; if not, abort | 77 | * Check if memory is enough for loading pruning tables; if not, abort |
| 74 | * For optimal solver: choose largest that fits in memory between nxopt and light | 78 | * For optimal solver: choose largest that fits in memory between nxopt and light |
| 75 | 79 | ||
| @@ -93,3 +97,5 @@ including e.g. solutions that were not shown because -c) | |||
| 93 | than when called directly, to avoid nasty problems with threading | 97 | than when called directly, to avoid nasty problems with threading |
| 94 | * unniss and inverse_alg work differently (one in place, the other makes | 98 | * unniss and inverse_alg work differently (one in place, the other makes |
| 95 | a copy and returns) changing inverse_alg seems the best option. | 99 | a copy and returns) changing inverse_alg seems the best option. |
| 100 | * parse command args: one function per arg type, then each command has | ||
| 101 | a list of options that it accepts (as a string) | ||
| Binary files differ | |||
diff --git a/src/commands.c b/src/commands.c index d9d6b50..13405b7 100644 --- a/src/commands.c +++ b/src/commands.c | |||
| @@ -12,6 +12,7 @@ CommandArgs * scramble_parse_args(int c, char **v); | |||
| 12 | /* Exec functions ************************************************************/ | 12 | /* Exec functions ************************************************************/ |
| 13 | 13 | ||
| 14 | static void gen_exec(CommandArgs *args); | 14 | static void gen_exec(CommandArgs *args); |
| 15 | static void cleanup_exec(CommandArgs *args); | ||
| 15 | static void invert_exec(CommandArgs *args); | 16 | static void invert_exec(CommandArgs *args); |
| 16 | static void solve_exec(CommandArgs *args); | 17 | static void solve_exec(CommandArgs *args); |
| 17 | static void scramble_exec(CommandArgs *args); | 18 | static void scramble_exec(CommandArgs *args); |
| @@ -123,6 +124,15 @@ quit_cmd = { | |||
| 123 | }; | 124 | }; |
| 124 | 125 | ||
| 125 | Command | 126 | Command |
| 127 | cleanup_cmd = { | ||
| 128 | .name = "cleanup", | ||
| 129 | .usage = "cleanup SCRAMBLE", | ||
| 130 | .description = "Rewrite a scramble using only standard moves (HTM)", | ||
| 131 | .parse_args = parse_only_scramble, | ||
| 132 | .exec = cleanup_exec, | ||
| 133 | }; | ||
| 134 | |||
| 135 | Command | ||
| 126 | unniss_cmd = { | 136 | unniss_cmd = { |
| 127 | .name = "unniss", | 137 | .name = "unniss", |
| 128 | .usage = "unniss SCRAMBLE", | 138 | .usage = "unniss SCRAMBLE", |
| @@ -151,6 +161,7 @@ Command *commands[NCOMMANDS] = { | |||
| 151 | &scramble_cmd, | 161 | &scramble_cmd, |
| 152 | &steps_cmd, | 162 | &steps_cmd, |
| 153 | &twophase_cmd, | 163 | &twophase_cmd, |
| 164 | &cleanup_cmd, | ||
| 154 | &unniss_cmd, | 165 | &unniss_cmd, |
| 155 | &version_cmd, | 166 | &version_cmd, |
| 156 | }; | 167 | }; |
| @@ -499,6 +510,19 @@ quit_exec(CommandArgs *args) | |||
| 499 | } | 510 | } |
| 500 | 511 | ||
| 501 | static void | 512 | static void |
| 513 | cleanup_exec(CommandArgs *args) | ||
| 514 | { | ||
| 515 | Alg *alg; | ||
| 516 | |||
| 517 | init_moves(); | ||
| 518 | |||
| 519 | alg = cleanup(args->scramble); | ||
| 520 | print_alg(alg, false); | ||
| 521 | |||
| 522 | free_alg(alg); | ||
| 523 | } | ||
| 524 | |||
| 525 | static void | ||
| 502 | unniss_exec(CommandArgs *args) | 526 | unniss_exec(CommandArgs *args) |
| 503 | { | 527 | { |
| 504 | unniss(args->scramble); | 528 | unniss(args->scramble); |
diff --git a/src/moves.c b/src/moves.c index 9547de9..7c33db4 100644 --- a/src/moves.c +++ b/src/moves.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | /* Local functions ***********************************************************/ | 3 | /* Local functions ***********************************************************/ |
| 4 | 4 | ||
| 5 | static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f); | 5 | static Cube apply_move_cubearray(Move m, Cube cube, PieceFilter f); |
| 6 | static void cleanup_aux(Alg *alg, Alg *ret, bool inv); | ||
| 6 | static bool read_mtables_file(); | 7 | static bool read_mtables_file(); |
| 7 | static bool write_mtables_file(); | 8 | static bool write_mtables_file(); |
| 8 | 9 | ||
| @@ -221,6 +222,125 @@ apply_move(Move m, Cube cube) | |||
| 221 | }; | 222 | }; |
| 222 | } | 223 | } |
| 223 | 224 | ||
| 225 | Alg * | ||
| 226 | cleanup(Alg *alg) | ||
| 227 | { | ||
| 228 | int i, j, k, b[2], n, L; | ||
| 229 | Move bb, m; | ||
| 230 | Alg *ret; | ||
| 231 | |||
| 232 | ret = new_alg(""); | ||
| 233 | cleanup_aux(alg, ret, false); | ||
| 234 | cleanup_aux(alg, ret, true); | ||
| 235 | |||
| 236 | do { | ||
| 237 | for (i = 0, j = 0, n = 0; i < ret->len; i = j) { | ||
| 238 | if (ret->move[i] > B3) { | ||
| 239 | ret->move[n] = ret->move[i]; | ||
| 240 | ret->inv[n] = ret->inv[i]; | ||
| 241 | n++; | ||
| 242 | j++; | ||
| 243 | continue; | ||
| 244 | } | ||
| 245 | |||
| 246 | bb = 1 + ((base_move(ret->move[i]) - 1)/6)*6; | ||
| 247 | while (j < ret->len && | ||
| 248 | ret->move[j] <= B3 && | ||
| 249 | ret->inv[j] == ret->inv[i] && | ||
| 250 | 1 + ((base_move(ret->move[j]) - 1)/6)*6 == bb) | ||
| 251 | j++; | ||
| 252 | |||
| 253 | for (k = i, b[0] = 0, b[1] = 0; k < j; k++) { | ||
| 254 | m = ret->move[k]; | ||
| 255 | if (base_move(m) == bb) | ||
| 256 | b[0] = (b[0]+1+m-base_move(m)) % 4; | ||
| 257 | else | ||
| 258 | b[1] = (b[1]+1+m-base_move(m)) % 4; | ||
| 259 | } | ||
| 260 | |||
| 261 | for (k = 0; k < 2; k++) { | ||
| 262 | if (b[k] != 0) { | ||
| 263 | ret->move[n] = bb + b[k] - 1 + 3*k; | ||
| 264 | ret->inv[n] = ret->inv[i]; | ||
| 265 | n++; | ||
| 266 | } | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | L = ret->len; | ||
| 271 | ret->len = n; | ||
| 272 | } while (L != n); | ||
| 273 | |||
| 274 | return ret; | ||
| 275 | } | ||
| 276 | |||
| 277 | static void | ||
| 278 | cleanup_aux(Alg *alg, Alg *ret, bool inv) | ||
| 279 | { | ||
| 280 | int i, j; | ||
| 281 | Cube c, d; | ||
| 282 | Move m, mm; | ||
| 283 | Alg *equiv_alg; | ||
| 284 | |||
| 285 | c = (Cube){0}; | ||
| 286 | for (i = 0; i < alg->len; i++) { | ||
| 287 | if (alg->inv[i] != inv) | ||
| 288 | continue; | ||
| 289 | |||
| 290 | equiv_alg = new_alg(equiv_alg_string[alg->move[i]]); | ||
| 291 | |||
| 292 | for (j = 0; j < equiv_alg->len; j++) { | ||
| 293 | m = equiv_alg->move[j]; | ||
| 294 | if (m == U) { | ||
| 295 | mm = 3*what_center_at(c, U_center) + 1; | ||
| 296 | append_move(ret, mm, inv); | ||
| 297 | } else { | ||
| 298 | c = apply_move(m, c); | ||
| 299 | } | ||
| 300 | } | ||
| 301 | |||
| 302 | free_alg(equiv_alg); | ||
| 303 | } | ||
| 304 | |||
| 305 | m = NULLMOVE; | ||
| 306 | switch (what_center_at(c, F_center)) { | ||
| 307 | case U_center: | ||
| 308 | m = x3; | ||
| 309 | break; | ||
| 310 | case D_center: | ||
| 311 | m = x; | ||
| 312 | break; | ||
| 313 | case R_center: | ||
| 314 | m = y; | ||
| 315 | break; | ||
| 316 | case L_center: | ||
| 317 | m = y3; | ||
| 318 | break; | ||
| 319 | case B_center: | ||
| 320 | if (what_center_at(c, U_center) == U_center) | ||
| 321 | m = y2; | ||
| 322 | else | ||
| 323 | m = x2; | ||
| 324 | break; | ||
| 325 | default: | ||
| 326 | break; | ||
| 327 | } | ||
| 328 | d = apply_move(m, (Cube){0}); | ||
| 329 | if (m != NULLMOVE) | ||
| 330 | append_move(ret, m, inv); | ||
| 331 | |||
| 332 | m = NULLMOVE; | ||
| 333 | if (what_center_at(c, U_center) == what_center_at(d, D_center)) { | ||
| 334 | m = z2; | ||
| 335 | } else if (what_center_at(c, U_center) == what_center_at(d, R_center)) { | ||
| 336 | m = z3; | ||
| 337 | } else if (what_center_at(c, U_center) == what_center_at(d, L_center)) { | ||
| 338 | m = z; | ||
| 339 | } | ||
| 340 | if (m != NULLMOVE) | ||
| 341 | append_move(ret, m, inv); | ||
| 342 | } | ||
| 343 | |||
| 224 | static bool | 344 | static bool |
| 225 | read_mtables_file() | 345 | read_mtables_file() |
| 226 | { | 346 | { |
diff --git a/src/moves.h b/src/moves.h index 4820f65..e7881a4 100644 --- a/src/moves.h +++ b/src/moves.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | Cube apply_alg(Alg *alg, Cube cube); | 8 | Cube apply_alg(Alg *alg, Cube cube); |
| 9 | Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a); | 9 | Cube apply_alg_generic(Alg *alg, Cube c, PieceFilter f, bool a); |
| 10 | Cube apply_move(Move m, Cube cube); | 10 | Cube apply_move(Move m, Cube cube); |
| 11 | Alg * cleanup(Alg *alg); | ||
| 11 | 12 | ||
| 12 | void init_moves(); | 13 | void init_moves(); |
| 13 | 14 | ||
