diff options
| author | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-12-26 19:38:28 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-12-26 19:38:28 +0100 |
| commit | 975e3eafbae15b93a1a4f160dd781d359a6c717b (patch) | |
| tree | dc6b05fcb57a64014c260ce43baa222386e5140f | |
| parent | b82df53eb461506984eb2b6a9b53e445b75e46af (diff) | |
| download | nissy-975e3eafbae15b93a1a4f160dd781d359a6c717b.tar.gz nissy-975e3eafbae15b93a1a4f160dd781d359a6c717b.zip | |
Added two-phase solver
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | doc/nissy.1 | 5 | ||||
| -rwxr-xr-x | nissy | bin | 317952 -> 318160 bytes | |||
| -rwxr-xr-x | nissy.exe | bin | 782089 -> 786001 bytes | |||
| -rw-r--r-- | src/alg.c | 67 | ||||
| -rw-r--r-- | src/alg.h | 1 | ||||
| -rw-r--r-- | src/commands.c | 29 | ||||
| -rw-r--r-- | src/solve.c | 51 | ||||
| -rw-r--r-- | src/solve.h | 1 | ||||
| -rw-r--r-- | src/steps.c | 2 | ||||
| -rw-r--r-- | src/steps.h | 46 |
11 files changed, 171 insertions, 33 deletions
| @@ -10,7 +10,6 @@ It's more of a personal reminder than anything else. | |||
| 10 | ### Commands that are available in nissy 1.0, but not in this version (yet): | 10 | ### Commands that are available in nissy 1.0, but not in this version (yet): |
| 11 | * drcorners (solve corners after dr) | 11 | * drcorners (solve corners after dr) |
| 12 | * search and improve non-optimal subsequences | 12 | * search and improve non-optimal subsequences |
| 13 | * **fast non-optimal solver (also needed for scramble)** | ||
| 14 | * **scramble [dr, corners only, edges only, htr, fmc(RUF)...]** | 13 | * **scramble [dr, corners only, edges only, htr, fmc(RUF)...]** |
| 15 | * save and edit algs as "variables" | 14 | * save and edit algs as "variables" |
| 16 | (or just use a "logging system" to keep info about previously run commands, | 15 | (or just use a "logging system" to keep info about previously run commands, |
| @@ -32,6 +31,7 @@ including e.g. solutions that were not shown because -c) | |||
| 32 | * transform alg, rufify etc... | 31 | * transform alg, rufify etc... |
| 33 | * more scramble stuff (scramble FMC with rufify...) | 32 | * more scramble stuff (scramble FMC with rufify...) |
| 34 | * command notation to list available moves | 33 | * command notation to list available moves |
| 34 | * make multi-step solve much more general and create command | ||
| 35 | 35 | ||
| 36 | ## Distribution | 36 | ## Distribution |
| 37 | 37 | ||
diff --git a/doc/nissy.1 b/doc/nissy.1 index 549cc4f..643674a 100644 --- a/doc/nissy.1 +++ b/doc/nissy.1 | |||
| @@ -160,6 +160,11 @@ for the | |||
| 160 | .Ar solve | 160 | .Ar solve |
| 161 | command. | 161 | command. |
| 162 | . | 162 | . |
| 163 | .It Nm twophase Ar scramble | ||
| 164 | Find a solution using a two-phase method. This does not guarantee | ||
| 165 | to return an optimal solution (and in fact most often it does not), | ||
| 166 | but it is very fast. | ||
| 167 | . | ||
| 163 | .It Nm unniss Ar scramble | 168 | .It Nm unniss Ar scramble |
| 164 | Rewrite the scramble without using NISS. | 169 | Rewrite the scramble without using NISS. |
| 165 | . | 170 | . |
| Binary files differ | |||
| Binary files differ | |||
| @@ -107,36 +107,6 @@ allowed_next_HTM(Move l2, Move l1, Move m) | |||
| 107 | return !(p || (commute(l1, l2) && q)); | 107 | return !(p || (commute(l1, l2) && q)); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static int | ||
| 111 | axis(Move m) | ||
| 112 | { | ||
| 113 | if (m == NULLMOVE) | ||
| 114 | return 0; | ||
| 115 | |||
| 116 | if (m >= U && m <= B3) | ||
| 117 | return (m-1)/6 + 1; | ||
| 118 | |||
| 119 | if (m >= Uw && m <= Bw3) | ||
| 120 | return (m-1)/6 - 2; | ||
| 121 | |||
| 122 | if (base_move(m) == E || base_move(m) == y) | ||
| 123 | return 1; | ||
| 124 | |||
| 125 | if (base_move(m) == M || base_move(m) == x) | ||
| 126 | return 2; | ||
| 127 | |||
| 128 | if (base_move(m) == S || base_move(m) == z) | ||
| 129 | return 3; | ||
| 130 | |||
| 131 | return -1; | ||
| 132 | } | ||
| 133 | |||
| 134 | bool | ||
| 135 | commute(Move m1, Move m2) | ||
| 136 | { | ||
| 137 | return axis(m1) == axis(m2); | ||
| 138 | } | ||
| 139 | |||
| 140 | void | 110 | void |
| 141 | append_alg(AlgList *l, Alg *alg) | 111 | append_alg(AlgList *l, Alg *alg) |
| 142 | { | 112 | { |
| @@ -166,6 +136,30 @@ append_move(Alg *alg, Move m, bool inverse) | |||
| 166 | alg->len++; | 136 | alg->len++; |
| 167 | } | 137 | } |
| 168 | 138 | ||
| 139 | static int | ||
| 140 | axis(Move m) | ||
| 141 | { | ||
| 142 | if (m == NULLMOVE) | ||
| 143 | return 0; | ||
| 144 | |||
| 145 | if (m >= U && m <= B3) | ||
| 146 | return (m-1)/6 + 1; | ||
| 147 | |||
| 148 | if (m >= Uw && m <= Bw3) | ||
| 149 | return (m-1)/6 - 2; | ||
| 150 | |||
| 151 | if (base_move(m) == E || base_move(m) == y) | ||
| 152 | return 1; | ||
| 153 | |||
| 154 | if (base_move(m) == M || base_move(m) == x) | ||
| 155 | return 2; | ||
| 156 | |||
| 157 | if (base_move(m) == S || base_move(m) == z) | ||
| 158 | return 3; | ||
| 159 | |||
| 160 | return -1; | ||
| 161 | } | ||
| 162 | |||
| 169 | Move | 163 | Move |
| 170 | base_move(Move m) | 164 | base_move(Move m) |
| 171 | { | 165 | { |
| @@ -175,6 +169,12 @@ base_move(Move m) | |||
| 175 | return m - (m-1)%3; | 169 | return m - (m-1)%3; |
| 176 | } | 170 | } |
| 177 | 171 | ||
| 172 | bool | ||
| 173 | commute(Move m1, Move m2) | ||
| 174 | { | ||
| 175 | return axis(m1) == axis(m2); | ||
| 176 | } | ||
| 177 | |||
| 178 | void | 178 | void |
| 179 | compose_alg(Alg *alg1, Alg *alg2) | 179 | compose_alg(Alg *alg1, Alg *alg2) |
| 180 | { | 180 | { |
| @@ -185,6 +185,13 @@ compose_alg(Alg *alg1, Alg *alg2) | |||
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | void | 187 | void |
| 188 | copy_alg(Alg *src, Alg *dst) | ||
| 189 | { | ||
| 190 | dst->len = 0; /* Overwrites */ | ||
| 191 | compose_alg(dst, src); | ||
| 192 | } | ||
| 193 | |||
| 194 | void | ||
| 188 | free_alg(Alg *alg) | 195 | free_alg(Alg *alg) |
| 189 | { | 196 | { |
| 190 | free(alg->move); | 197 | free(alg->move); |
| @@ -19,6 +19,7 @@ void append_move(Alg *alg, Move m, bool inverse); | |||
| 19 | Move base_move(Move m); | 19 | Move base_move(Move m); |
| 20 | void compose_alg(Alg *alg1, Alg *alg2); | 20 | void compose_alg(Alg *alg1, Alg *alg2); |
| 21 | bool commute(Move m1, Move m2); | 21 | bool commute(Move m1, Move m2); |
| 22 | void copy_alg(Alg *src, Alg *dst); | ||
| 22 | void free_alg(Alg *alg); | 23 | void free_alg(Alg *alg); |
| 23 | void free_alglist(AlgList *l); | 24 | void free_alglist(AlgList *l); |
| 24 | Alg * inverse_alg(Alg *alg); | 25 | Alg * inverse_alg(Alg *alg); |
diff --git a/src/commands.c b/src/commands.c index 56ff944..02af19f 100644 --- a/src/commands.c +++ b/src/commands.c | |||
| @@ -2,12 +2,12 @@ | |||
| 2 | 2 | ||
| 3 | /* Arg parsing functions *****************************************************/ | 3 | /* Arg parsing functions *****************************************************/ |
| 4 | 4 | ||
| 5 | CommandArgs * solve_parse_args(int c, char **v); | ||
| 6 | CommandArgs * gen_parse_args(int c, char **v); | 5 | CommandArgs * gen_parse_args(int c, char **v); |
| 7 | CommandArgs * help_parse_args(int c, char **v); | 6 | CommandArgs * help_parse_args(int c, char **v); |
| 8 | CommandArgs * print_parse_args(int c, char **v); | 7 | CommandArgs * print_parse_args(int c, char **v); |
| 9 | CommandArgs * parse_only_scramble(int c, char **v); | 8 | CommandArgs * parse_only_scramble(int c, char **v); |
| 10 | CommandArgs * parse_no_arg(int c, char **v); | 9 | CommandArgs * parse_no_arg(int c, char **v); |
| 10 | CommandArgs * solve_parse_args(int c, char **v); | ||
| 11 | 11 | ||
| 12 | /* Exec functions ************************************************************/ | 12 | /* Exec functions ************************************************************/ |
| 13 | 13 | ||
| @@ -17,6 +17,7 @@ static void solve_exec(CommandArgs *args); | |||
| 17 | static void steps_exec(CommandArgs *args); | 17 | static void steps_exec(CommandArgs *args); |
| 18 | static void commands_exec(CommandArgs *args); | 18 | static void commands_exec(CommandArgs *args); |
| 19 | static void print_exec(CommandArgs *args); | 19 | static void print_exec(CommandArgs *args); |
| 20 | static void twophase_exec(CommandArgs *args); | ||
| 20 | static void help_exec(CommandArgs *args); | 21 | static void help_exec(CommandArgs *args); |
| 21 | static void quit_exec(CommandArgs *args); | 22 | static void quit_exec(CommandArgs *args); |
| 22 | static void unniss_exec(CommandArgs *args); | 23 | static void unniss_exec(CommandArgs *args); |
| @@ -93,6 +94,15 @@ help_cmd = { | |||
| 93 | }; | 94 | }; |
| 94 | 95 | ||
| 95 | Command | 96 | Command |
| 97 | twophase_cmd = { | ||
| 98 | .name = "twophase", | ||
| 99 | .usage = "twophase", | ||
| 100 | .description = "Find a solution quickly using a 2-phase method", | ||
| 101 | .parse_args = parse_only_scramble, | ||
| 102 | .exec = twophase_exec, | ||
| 103 | }; | ||
| 104 | |||
| 105 | Command | ||
| 96 | quit_cmd = { | 106 | quit_cmd = { |
| 97 | .name = "quit", | 107 | .name = "quit", |
| 98 | .usage = "quit", | 108 | .usage = "quit", |
| @@ -128,6 +138,7 @@ Command *commands[NCOMMANDS] = { | |||
| 128 | &quit_cmd, | 138 | &quit_cmd, |
| 129 | &solve_cmd, | 139 | &solve_cmd, |
| 130 | &steps_cmd, | 140 | &steps_cmd, |
| 141 | &twophase_cmd, | ||
| 131 | &unniss_cmd, | 142 | &unniss_cmd, |
| 132 | &version_cmd, | 143 | &version_cmd, |
| 133 | }; | 144 | }; |
| @@ -384,6 +395,22 @@ print_exec(CommandArgs *args) | |||
| 384 | } | 395 | } |
| 385 | 396 | ||
| 386 | static void | 397 | static void |
| 398 | twophase_exec(CommandArgs *args) | ||
| 399 | { | ||
| 400 | Cube c; | ||
| 401 | Alg *sol; | ||
| 402 | |||
| 403 | init_movesets(); | ||
| 404 | init_symcoord(); | ||
| 405 | |||
| 406 | c = apply_alg(args->scramble, (Cube){0}); | ||
| 407 | sol = solve_2phase(c, 1); | ||
| 408 | |||
| 409 | print_alg(sol, false); | ||
| 410 | free_alg(sol); | ||
| 411 | } | ||
| 412 | |||
| 413 | static void | ||
| 387 | help_exec(CommandArgs *args) | 414 | help_exec(CommandArgs *args) |
| 388 | { | 415 | { |
| 389 | if (args->command == NULL) { | 416 | if (args->command == NULL) { |
diff --git a/src/solve.c b/src/solve.c index 5a72bba..cfb2bd3 100644 --- a/src/solve.c +++ b/src/solve.c | |||
| @@ -438,3 +438,54 @@ solve(Cube cube, Step *step, SolveOptions *opts) | |||
| 438 | 438 | ||
| 439 | return sols; | 439 | return sols; |
| 440 | } | 440 | } |
| 441 | |||
| 442 | /* TODO: make more general! */ | ||
| 443 | Alg * | ||
| 444 | solve_2phase(Cube cube, int nthreads) | ||
| 445 | { | ||
| 446 | int bestlen, newb; | ||
| 447 | Alg *bestalg; | ||
| 448 | AlgList *sols1, *sols2; | ||
| 449 | AlgListNode *i; | ||
| 450 | Cube c; | ||
| 451 | SolveOptions opts1, opts2; | ||
| 452 | |||
| 453 | opts1.min_moves = 0; | ||
| 454 | opts1.max_moves = 13; | ||
| 455 | opts1.max_solutions = 100; | ||
| 456 | opts1.nthreads = nthreads; | ||
| 457 | opts1.optimal = 3; | ||
| 458 | opts1.can_niss = false; | ||
| 459 | opts1.verbose = false; | ||
| 460 | opts1.all = true; | ||
| 461 | |||
| 462 | opts2.min_moves = 0; | ||
| 463 | opts2.max_moves = 19; | ||
| 464 | opts2.max_solutions = 1; | ||
| 465 | opts2.nthreads = nthreads; | ||
| 466 | opts2.can_niss = false; | ||
| 467 | opts2.verbose = false; | ||
| 468 | |||
| 469 | sols1 = solve(cube, &drany_HTM, &opts1); | ||
| 470 | bestalg = new_alg(""); | ||
| 471 | bestlen = 999; | ||
| 472 | for (i = sols1->first; i != NULL; i = i->next) { | ||
| 473 | c = apply_alg(i->alg, cube); | ||
| 474 | sols2 = solve(c, &dranyfin_DR, &opts2); | ||
| 475 | |||
| 476 | if (sols2->len > 0) { | ||
| 477 | newb = i->alg->len + sols2->first->alg->len; | ||
| 478 | if (newb < bestlen) { | ||
| 479 | bestlen = newb; | ||
| 480 | copy_alg(i->alg, bestalg); | ||
| 481 | compose_alg(bestalg, sols2->first->alg); | ||
| 482 | } | ||
| 483 | } | ||
| 484 | |||
| 485 | free_alglist(sols2); | ||
| 486 | } | ||
| 487 | |||
| 488 | free_alglist(sols1); | ||
| 489 | |||
| 490 | return bestalg; | ||
| 491 | } | ||
diff --git a/src/solve.h b/src/solve.h index 668cd9a..6ce6609 100644 --- a/src/solve.h +++ b/src/solve.h | |||
| @@ -6,5 +6,6 @@ | |||
| 6 | #include "trans.h" | 6 | #include "trans.h" |
| 7 | 7 | ||
| 8 | AlgList * solve(Cube cube, Step *step, SolveOptions *opts); | 8 | AlgList * solve(Cube cube, Step *step, SolveOptions *opts); |
| 9 | Alg * solve_2phase(Cube cube, int nthreads); | ||
| 9 | 10 | ||
| 10 | #endif | 11 | #endif |
diff --git a/src/steps.c b/src/steps.c index 98e26b5..5de3206 100644 --- a/src/steps.c +++ b/src/steps.c | |||
| @@ -1437,7 +1437,7 @@ static int | |||
| 1437 | detect_pretrans_drud(Cube cube, Trans *ret) | 1437 | detect_pretrans_drud(Cube cube, Trans *ret) |
| 1438 | { | 1438 | { |
| 1439 | int i, n; | 1439 | int i, n; |
| 1440 | static Trans tt[3] = {uf, ur, fd}; | 1440 | static Trans tt[3] = {uf, fr, rd}; |
| 1441 | 1441 | ||
| 1442 | for (i = 0, n = 0; i < 3; i++) | 1442 | for (i = 0, n = 0; i < 3; i++) |
| 1443 | if (check_drud(apply_trans(tt[i], cube))) | 1443 | if (check_drud(apply_trans(tt[i], cube))) |
diff --git a/src/steps.h b/src/steps.h index 5744e48..53f8e1b 100644 --- a/src/steps.h +++ b/src/steps.h | |||
| @@ -7,6 +7,52 @@ | |||
| 7 | 7 | ||
| 8 | extern Step * steps[NSTEPS]; | 8 | extern Step * steps[NSTEPS]; |
| 9 | 9 | ||
| 10 | extern Step optimal_HTM; | ||
| 11 | extern Step optimal_light_HTM; | ||
| 12 | extern Step eofin_eo; | ||
| 13 | extern Step eofbfin_eofb; | ||
| 14 | extern Step eorlfin_eorl; | ||
| 15 | extern Step eoudfin_eoud; | ||
| 16 | extern Step eoany_HTM; | ||
| 17 | extern Step eofb_HTM; | ||
| 18 | extern Step eorl_HTM; | ||
| 19 | extern Step eoud_HTM; | ||
| 20 | extern Step coany_HTM; | ||
| 21 | extern Step coud_HTM; | ||
| 22 | extern Step corl_HTM; | ||
| 23 | extern Step cofb_HTM; | ||
| 24 | extern Step coany_URF; | ||
| 25 | extern Step coud_URF; | ||
| 26 | extern Step corl_URF; | ||
| 27 | extern Step cofb_URF; | ||
| 28 | extern Step drany_HTM; | ||
| 29 | extern Step drud_HTM; | ||
| 30 | extern Step drrl_HTM; | ||
| 31 | extern Step drfb_HTM; | ||
| 32 | extern Step dr_eo; | ||
| 33 | extern Step dr_eofb; | ||
| 34 | extern Step dr_eorl; | ||
| 35 | extern Step dr_eoud; | ||
| 36 | extern Step drud_eofb; | ||
| 37 | extern Step drrl_eofb; | ||
| 38 | extern Step drud_eorl; | ||
| 39 | extern Step drfb_eorl; | ||
| 40 | extern Step drfb_eoud; | ||
| 41 | extern Step drrl_eoud; | ||
| 42 | extern Step dranyfin_DR; | ||
| 43 | extern Step drudfin_drud; | ||
| 44 | extern Step drrlfin_drrl; | ||
| 45 | extern Step drfbfin_drfb; | ||
| 46 | extern Step htr_any; | ||
| 47 | extern Step htr_drud; | ||
| 48 | extern Step htr_drrl; | ||
| 49 | extern Step htr_drfb; | ||
| 50 | extern Step htrfin_htr; | ||
| 51 | extern Step cornershtr_HTM; | ||
| 52 | extern Step cornershtr_URF; | ||
| 53 | extern Step corners_HTM; | ||
| 54 | extern Step corners_URF; | ||
| 55 | |||
| 10 | void copy_estimatedata(EstimateData *s, EstimateData *d); | 56 | void copy_estimatedata(EstimateData *s, EstimateData *d); |
| 11 | void invert_estimatedata(EstimateData *ed); | 57 | void invert_estimatedata(EstimateData *ed); |
| 12 | void reset_estimatedata(EstimateData *ed); | 58 | void reset_estimatedata(EstimateData *ed); |
