diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2024-12-15 10:50:00 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2024-12-15 10:50:00 +0100 |
| commit | cb800102a14fb6923546b9d036dbf4e6a5b7542a (patch) | |
| tree | f0764cd8a1f0681cdb9492cf445d60d56c8304d3 /src | |
| parent | d2eb169c675101a64fb873a289fad1d4fe70c5e5 (diff) | |
| download | nissy-core-cb800102a14fb6923546b9d036dbf4e6a5b7542a.tar.gz nissy-core-cb800102a14fb6923546b9d036dbf4e6a5b7542a.zip | |
Solve bug related to duplicate solutions
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/io_trans.h | 2 | ||||
| -rw-r--r-- | src/core/moves.h | 2 | ||||
| -rw-r--r-- | src/core/transform.h | 2 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_cocsep.h | 2 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_eoesep.h | 6 | ||||
| -rw-r--r-- | src/solvers/h48/gendata_types_macros.h | 2 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 94 |
7 files changed, 62 insertions, 48 deletions
diff --git a/src/core/io_trans.h b/src/core/io_trans.h index f0db095..71b2287 100644 --- a/src/core/io_trans.h +++ b/src/core/io_trans.h | |||
| @@ -6,7 +6,7 @@ readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION]) | |||
| 6 | { | 6 | { |
| 7 | uint8_t t; | 7 | uint8_t t; |
| 8 | 8 | ||
| 9 | for (t = 0; t < 48; t++) | 9 | for (t = 0; t < NTRANS; t++) |
| 10 | if (!strncmp(buf, transstr[t], 11)) | 10 | if (!strncmp(buf, transstr[t], 11)) |
| 11 | return t; | 11 | return t; |
| 12 | 12 | ||
diff --git a/src/core/moves.h b/src/core/moves.h index 7d4972e..037944b 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -61,7 +61,7 @@ allowednextmove_mask(uint8_t *moves, uint8_t n) | |||
| 61 | result = disable_moves(result, (base1 - 1) * 3); | 61 | result = disable_moves(result, (base1 - 1) * 3); |
| 62 | 62 | ||
| 63 | if (n == 1) | 63 | if (n == 1) |
| 64 | return result; | 64 | return result; |
| 65 | 65 | ||
| 66 | base2 = movebase(moves[n-2]); | 66 | base2 = movebase(moves[n-2]); |
| 67 | axis2 = moveaxis(moves[n-2]); | 67 | axis2 = moveaxis(moves[n-2]); |
diff --git a/src/core/transform.h b/src/core/transform.h index f956718..a6bb937 100644 --- a/src/core/transform.h +++ b/src/core/transform.h | |||
| @@ -387,7 +387,7 @@ symmetry_mask(cube_t cube) | |||
| 387 | uint64_t t, ret; | 387 | uint64_t t, ret; |
| 388 | cube_t transformed; | 388 | cube_t transformed; |
| 389 | 389 | ||
| 390 | for (t = 0, ret = 0; t < 48; t++) { | 390 | for (t = 0, ret = 0; t < NTRANS; t++) { |
| 391 | transformed = transform(cube, t); | 391 | transformed = transform(cube, t); |
| 392 | ret |= ((uint64_t)equal(cube, transformed)) << t; | 392 | ret |= ((uint64_t)equal(cube, transformed)) << t; |
| 393 | } | 393 | } |
diff --git a/src/solvers/h48/gendata_cocsep.h b/src/solvers/h48/gendata_cocsep.h index 291ae48..3812a4a 100644 --- a/src/solvers/h48/gendata_cocsep.h +++ b/src/solvers/h48/gendata_cocsep.h | |||
| @@ -101,7 +101,7 @@ gendata_cocsep_dfs(cocsep_dfs_arg_t *arg) | |||
| 101 | 101 | ||
| 102 | if (arg->rep != NULL) | 102 | if (arg->rep != NULL) |
| 103 | arg->rep[*arg->n] = arg->cube; | 103 | arg->rep[*arg->n] = arg->cube; |
| 104 | for (t = 0, cc = 0; t < 48; t++) { | 104 | for (t = 0, cc = 0; t < NTRANS; t++) { |
| 105 | d = transform_corners(arg->cube, t); | 105 | d = transform_corners(arg->cube, t); |
| 106 | j = coord_cocsep(d); | 106 | j = coord_cocsep(d); |
| 107 | if (i == j && arg->selfsim != NULL) | 107 | if (i == j && arg->selfsim != NULL) |
diff --git a/src/solvers/h48/gendata_eoesep.h b/src/solvers/h48/gendata_eoesep.h index d3b73ea..23fbb3c 100644 --- a/src/solvers/h48/gendata_eoesep.h +++ b/src/solvers/h48/gendata_eoesep.h | |||
| @@ -50,7 +50,7 @@ gendata_esep_classes( | |||
| 50 | if (visited[i]) | 50 | if (visited[i]) |
| 51 | continue; | 51 | continue; |
| 52 | c = invcoord_esep(i); | 52 | c = invcoord_esep(i); |
| 53 | for (t = 0; t < 48; t++) { | 53 | for (t = 0; t < NTRANS; t++) { |
| 54 | j = coord_esep(transform(c, t)); | 54 | j = coord_esep(transform(c, t)); |
| 55 | cl = class << UINT32_C(16); | 55 | cl = class << UINT32_C(16); |
| 56 | ti = inverse_trans(t) << UINT32_C(8); | 56 | ti = inverse_trans(t) << UINT32_C(8); |
| @@ -206,7 +206,7 @@ gendata_eoesep_marksim( | |||
| 206 | c = invcoord_eoesep(i); | 206 | c = invcoord_eoesep(i); |
| 207 | for (m = 0; m < 18; m++) { | 207 | for (m = 0; m < 18; m++) { |
| 208 | moved = move(c, m); | 208 | moved = move(c, m); |
| 209 | for (t = 0; t < 48; t++) { | 209 | for (t = 0; t < NTRANS; t++) { |
| 210 | transformed = transform(moved, t); | 210 | transformed = transform(moved, t); |
| 211 | coord = coord_eoesep_sym(transformed, esep_classes); | 211 | coord = coord_eoesep_sym(transformed, esep_classes); |
| 212 | pval = get_eoesep_pval(buf8, coord); | 212 | pval = get_eoesep_pval(buf8, coord); |
| @@ -232,7 +232,7 @@ gendata_eoesep_next( | |||
| 232 | int64_t coord; | 232 | int64_t coord; |
| 233 | cube_t moved, transformed; | 233 | cube_t moved, transformed; |
| 234 | 234 | ||
| 235 | for (t = 0; t < 48; t++) { | 235 | for (t = 0; t < NTRANS; t++) { |
| 236 | transformed = transform(c, t); | 236 | transformed = transform(c, t); |
| 237 | for (m = 0; m < 18; m++) { | 237 | for (m = 0; m < 18; m++) { |
| 238 | moved = move(transformed, m); | 238 | moved = move(transformed, m); |
diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h index d7c88af..a2026b2 100644 --- a/src/solvers/h48/gendata_types_macros.h +++ b/src/solvers/h48/gendata_types_macros.h | |||
| @@ -43,7 +43,7 @@ _t by _ttrep). | |||
| 43 | int64_t VAR_COCLASS = COCLASS(ARG_COCSEPDATA[VAR_COCSEP]); \ | 43 | int64_t VAR_COCLASS = COCLASS(ARG_COCSEPDATA[VAR_COCSEP]); \ |
| 44 | cube_t VAR_REP = transform(ARG_CUBE, VAR_TTREP); \ | 44 | cube_t VAR_REP = transform(ARG_CUBE, VAR_TTREP); \ |
| 45 | uint64_t VAR_S = ARG_SELFSIM[VAR_COCLASS]; \ | 45 | uint64_t VAR_S = ARG_SELFSIM[VAR_COCLASS]; \ |
| 46 | for (uint8_t VAR_T = 0; VAR_T < 48 && VAR_S; VAR_T++, VAR_S >>= 1) { \ | 46 | for (uint8_t VAR_T = 0; VAR_T < NTRANS && VAR_S; VAR_T++, VAR_S >>= 1) { \ |
| 47 | if (!(VAR_S & 1)) continue; \ | 47 | if (!(VAR_S & 1)) continue; \ |
| 48 | ARG_CUBE = transform(VAR_REP, VAR_T); \ | 48 | ARG_CUBE = transform(VAR_REP, VAR_T); \ |
| 49 | ARG_CUBE = transform(ARG_CUBE, VAR_INVERSE_TTREP); \ | 49 | ARG_CUBE = transform(ARG_CUBE, VAR_INVERSE_TTREP); \ |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 1ca294a..d168985 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -57,8 +57,7 @@ typedef struct { | |||
| 57 | } dfsarg_solve_h48_maketasks_t; | 57 | } dfsarg_solve_h48_maketasks_t; |
| 58 | 58 | ||
| 59 | STATIC int64_t solve_h48_appendsolution(dfsarg_solve_h48_t *); | 59 | STATIC int64_t solve_h48_appendsolution(dfsarg_solve_h48_t *); |
| 60 | STATIC bool solve_h48_appendmoves(dfsarg_solve_h48_t *, int8_t, | 60 | STATIC int64_t solve_h48_appendallsym(dfsarg_solve_h48_t *); |
| 61 | uint8_t *, uint8_t); | ||
| 62 | STATIC bool solve_h48_appendchar(dfsarg_solve_h48_t *, char); | 61 | STATIC bool solve_h48_appendchar(dfsarg_solve_h48_t *, char); |
| 63 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t *); | 62 | STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t *); |
| 64 | STATIC int64_t solve_h48_maketasks( | 63 | STATIC int64_t solve_h48_maketasks( |
| @@ -73,15 +72,10 @@ STATIC int64_t solve_h48(cube_t, int8_t, int8_t, uint64_t, int8_t, int8_t, | |||
| 73 | STATIC int64_t | 72 | STATIC int64_t |
| 74 | solve_h48_appendsolution(dfsarg_solve_h48_t *arg) | 73 | solve_h48_appendsolution(dfsarg_solve_h48_t *arg) |
| 75 | { | 74 | { |
| 76 | uint8_t t; | ||
| 77 | int64_t ret; | ||
| 78 | uint64_t solstart; | ||
| 79 | |||
| 80 | if (*arg->nsols >= arg->maxsolutions || | 75 | if (*arg->nsols >= arg->maxsolutions || |
| 81 | arg->nmoves + arg->npremoves > *arg->shortest_sol + arg->optimal) | 76 | arg->nmoves + arg->npremoves > *arg->shortest_sol + arg->optimal) |
| 82 | return 0; | 77 | return 0; |
| 83 | 78 | ||
| 84 | solstart = *arg->solutions_used; | ||
| 85 | invertmoves(arg->premoves, arg->npremoves, arg->moves + arg->nmoves); | 79 | invertmoves(arg->premoves, arg->npremoves, arg->moves + arg->nmoves); |
| 86 | 80 | ||
| 87 | /* Do not append the solution in case premoves cancel with normal */ | 81 | /* Do not append the solution in case premoves cancel with normal */ |
| @@ -90,18 +84,63 @@ solve_h48_appendsolution(dfsarg_solve_h48_t *arg) | |||
| 90 | if (arg->npremoves > 1 && !allowednextmove(arg->moves, arg->nmoves+2)) | 84 | if (arg->npremoves > 1 && !allowednextmove(arg->moves, arg->nmoves+2)) |
| 91 | return 0; | 85 | return 0; |
| 92 | 86 | ||
| 93 | for (t = 0, ret = 0; t < 48 && *arg->nsols < arg->maxsolutions; t++) { | 87 | return solve_h48_appendallsym(arg); |
| 88 | } | ||
| 89 | |||
| 90 | STATIC int64_t | ||
| 91 | solve_h48_appendallsym(dfsarg_solve_h48_t *arg) | ||
| 92 | { | ||
| 93 | bool eq; | ||
| 94 | uint8_t t, i, j, k, n; | ||
| 95 | int64_t ret, strl, l; | ||
| 96 | char *m; | ||
| 97 | uint8_t all[NTRANS][MAXLEN]; | ||
| 98 | |||
| 99 | n = arg->nmoves + arg->npremoves; | ||
| 100 | |||
| 101 | for (t = 0, j = 0; t < NTRANS; t++) { | ||
| 94 | if (!(arg->symmask0 & (UINT64_C(1) << (uint64_t)t))) | 102 | if (!(arg->symmask0 & (UINT64_C(1) << (uint64_t)t))) |
| 95 | continue; | 103 | continue; |
| 96 | 104 | ||
| 97 | if (!solve_h48_appendmoves(arg, arg->nmoves + arg->npremoves, | 105 | for (i = 0; i < n; i++) |
| 98 | arg->moves, t)) | 106 | all[j][i] = transform_move(arg->moves[i], t); |
| 99 | goto solve_h48_appendsolution_error; | 107 | |
| 108 | /* Sort parallel moves for consistency */ | ||
| 109 | for (i = 0; i < n - 1; i++) | ||
| 110 | if (moveaxis(all[j][i]) == moveaxis(all[j][i+1]) && | ||
| 111 | movebase(all[j][i]) == movebase(all[j][i+1]) + 1) | ||
| 112 | SWAP(all[j][i], all[j][i+1]); | ||
| 113 | |||
| 114 | /* Check for duplicate solutions */ | ||
| 115 | for (k = 0; k < j; k++) { | ||
| 116 | eq = true; | ||
| 117 | for (i = 0; i < n; i++) | ||
| 118 | if (all[k][i] != all[j][i]) | ||
| 119 | eq = false; | ||
| 120 | /* If a solution was already found, we skip it */ | ||
| 121 | if (eq) | ||
| 122 | continue; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* If all is good, the solution is accepted */ | ||
| 126 | j++; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* The solutions are appended */ | ||
| 130 | for (k = 0; k < j && *arg->nsols < arg->maxsolutions; k++) { | ||
| 131 | l = arg->solutions_size - *arg->solutions_used; | ||
| 132 | m = *arg->solutions + *arg->solutions_used; | ||
| 133 | strl = writemoves(all[k], n, l, m); | ||
| 134 | if (strl < 0) | ||
| 135 | goto solve_h48_appendallsym_error; | ||
| 100 | 136 | ||
| 101 | LOG("Solution found: %s\n", *arg->solutions + solstart); | 137 | LOG("Solution found: %s\n", m); |
| 138 | |||
| 139 | *arg->solutions_used += MAX(0, strl-1); | ||
| 102 | 140 | ||
| 103 | if (!solve_h48_appendchar(arg, '\n')) | 141 | if (!solve_h48_appendchar(arg, '\n')) |
| 104 | goto solve_h48_appendsolution_error; | 142 | goto solve_h48_appendallsym_error; |
| 143 | |||
| 105 | (*arg->nsols)++; | 144 | (*arg->nsols)++; |
| 106 | *arg->shortest_sol = | 145 | *arg->shortest_sol = |
| 107 | MIN(*arg->shortest_sol, arg->nmoves + arg->npremoves); | 146 | MIN(*arg->shortest_sol, arg->nmoves + arg->npremoves); |
| @@ -110,37 +149,12 @@ solve_h48_appendsolution(dfsarg_solve_h48_t *arg) | |||
| 110 | 149 | ||
| 111 | return ret; | 150 | return ret; |
| 112 | 151 | ||
| 113 | solve_h48_appendsolution_error: | 152 | solve_h48_appendallsym_error: |
| 114 | LOG("Could not append solution to buffer: size too small\n"); | 153 | LOG("Could not append solution to buffer: size too small\n"); |
| 115 | return NISSY_ERROR_BUFFER_SIZE; | 154 | return NISSY_ERROR_BUFFER_SIZE; |
| 116 | } | 155 | } |
| 117 | 156 | ||
| 118 | STATIC bool | 157 | STATIC bool |
| 119 | solve_h48_appendmoves( | ||
| 120 | dfsarg_solve_h48_t *arg, | ||
| 121 | int8_t n, | ||
| 122 | uint8_t *moves, | ||
| 123 | uint8_t t | ||
| 124 | ) | ||
| 125 | { | ||
| 126 | int i; | ||
| 127 | int64_t strl; | ||
| 128 | uint8_t mm[MAXLEN]; | ||
| 129 | |||
| 130 | for (i = 0; i < n; i++) | ||
| 131 | mm[i] = transform_move(moves[i], t); | ||
| 132 | |||
| 133 | strl = writemoves(mm, n, arg->solutions_size - *arg->solutions_used, | ||
| 134 | *arg->solutions + *arg->solutions_used); | ||
| 135 | |||
| 136 | if (strl < 0) | ||
| 137 | return false; | ||
| 138 | |||
| 139 | *arg->solutions_used += MAX(0, strl-1); | ||
| 140 | return true; | ||
| 141 | } | ||
| 142 | |||
| 143 | STATIC bool | ||
| 144 | solve_h48_appendchar(dfsarg_solve_h48_t *arg, char c) | 158 | solve_h48_appendchar(dfsarg_solve_h48_t *arg, char c) |
| 145 | { | 159 | { |
| 146 | if (arg->solutions_size <= *arg->solutions_used) | 160 | if (arg->solutions_size <= *arg->solutions_used) |
| @@ -397,7 +411,7 @@ solve_h48_maketasks( | |||
| 397 | 411 | ||
| 398 | /* Avoid symmetry-equivalent moves from the starting cube */ | 412 | /* Avoid symmetry-equivalent moves from the starting cube */ |
| 399 | if (maketasks_arg->nmoves == 1) | 413 | if (maketasks_arg->nmoves == 1) |
| 400 | for (t = 0; t < 48; t++) | 414 | for (t = 0; t < NTRANS; t++) |
| 401 | if (solve_arg->symmask0 & | 415 | if (solve_arg->symmask0 & |
| 402 | (UINT64_C(1) << (uint64_t)t)) | 416 | (UINT64_C(1) << (uint64_t)t)) |
| 403 | mm &= ~(UINT32_C(1) << | 417 | mm &= ~(UINT32_C(1) << |
