aboutsummaryrefslogtreecommitdiff
path: root/src/solvers
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers')
-rw-r--r--src/solvers/coord/common.h2
-rw-r--r--src/solvers/coord/coord.h1
-rw-r--r--src/solvers/coord/dr.h22
-rw-r--r--src/solvers/coord/dreo.h102
-rw-r--r--src/solvers/coord/eo.h15
-rw-r--r--src/solvers/coord/gendata.h11
-rw-r--r--src/solvers/coord/list.h1
-rw-r--r--src/solvers/coord/solve.h27
-rw-r--r--src/solvers/coord/types_macros.h1
9 files changed, 168 insertions, 14 deletions
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index 95c0e6c..2eb5ad0 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -125,7 +125,7 @@ coord_gendata_generic(
125 125
126 writetableinfo(&info, coord_datasize, data); 126 writetableinfo(&info, coord_datasize, data);
127 127
128 DBG_ASSERT(n == coord->sym.classes, 0, 128 DBG_ASSERT(n == coord->sym.classes, SIZE_MAX,
129 "%s coordinate data: computed %" PRIu64 " classes, " 129 "%s coordinate data: computed %" PRIu64 " classes, "
130 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes); 130 "expected %" PRIu64 "\n", coord->name, n, coord->sym.classes);
131 131
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
index 11d41bc..2f24035 100644
--- a/src/solvers/coord/coord.h
+++ b/src/solvers/coord/coord.h
@@ -2,6 +2,7 @@
2#include "common.h" 2#include "common.h"
3#include "eo.h" 3#include "eo.h"
4#include "dr.h" 4#include "dr.h"
5#include "dreo.h"
5#include "list.h" 6#include "list.h"
6#include "utils.h" 7#include "utils.h"
7#include "gendata.h" 8#include "gendata.h"
diff --git a/src/solvers/coord/dr.h b/src/solvers/coord/dr.h
index 314d4f1..3bc4c6d 100644
--- a/src/solvers/coord/dr.h
+++ b/src/solvers/coord/dr.h
@@ -1,5 +1,5 @@
1#define DREOESEP_CLASSES UINT64_C(64430) 1#define DREOESEP_CLASSES UINT64_C(64430)
2#define DREOESEP_MAX (POW_2_11 * COMB_12_4) 2#define DREOESEP_MAX (POW_2_11 * COMB_12_4)
3 3
4STATIC uint64_t coord_dreoesep_nosym(cube_t); 4STATIC uint64_t coord_dreoesep_nosym(cube_t);
5STATIC cube_t invcoord_dreoesep_nosym(uint64_t); 5STATIC cube_t invcoord_dreoesep_nosym(uint64_t);
@@ -10,6 +10,8 @@ STATIC cube_t coordinate_dr_cube(uint64_t, const void *);
10STATIC bool coordinate_dr_isnasty(uint64_t, const void *); 10STATIC bool coordinate_dr_isnasty(uint64_t, const void *);
11STATIC size_t coordinate_dr_gendata(void *); 11STATIC size_t coordinate_dr_gendata(void *);
12 12
13STATIC bool is_eoco_solvable(cube_t);
14
13/* TODO: remove the following two when all coordinates are converted to unsigned */ 15/* TODO: remove the following two when all coordinates are converted to unsigned */
14STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); } 16STATIC uint64_t coord_co_u(cube_t c) { return (uint64_t)coord_co(c); }
15STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); } 17STATIC cube_t invcoord_co_u(uint64_t i) { return invcoord_co((int64_t)i); }
@@ -29,6 +31,7 @@ STATIC coord_t coordinate_dr = {
29 [AXIS_FB] = TRANS_FDr, 31 [AXIS_FB] = TRANS_FDr,
30 }, 32 },
31 .is_admissible = &solution_lastqt_cw, 33 .is_admissible = &solution_lastqt_cw,
34 .is_solvable = &is_eoco_solvable,
32 .sym = { 35 .sym = {
33 .classes = DREOESEP_CLASSES, 36 .classes = DREOESEP_CLASSES,
34 .max = DREOESEP_MAX, 37 .max = DREOESEP_MAX,
@@ -100,3 +103,18 @@ coordinate_dr_gendata(void *data)
100{ 103{
101 return coord_gendata_generic(&coordinate_dr, data); 104 return coord_gendata_generic(&coordinate_dr, data);
102} 105}
106
107STATIC bool
108is_eoco_solvable(cube_t cube) {
109 uint8_t c[8], e[12], i, cocount, eocount;
110
111 pieces(&cube, c, e);
112
113 for (i = 0, cocount = 0; i < 8; i++)
114 cocount += (c[i] & COBITS_2) >> COSHIFT;
115
116 for (i = 0, eocount = 0; i < 12; i++)
117 eocount += (e[i] & EOBIT) >> EOSHIFT;
118
119 return cocount % 3 == 0 && eocount % 2 == 0;
120}
diff --git a/src/solvers/coord/dreo.h b/src/solvers/coord/dreo.h
new file mode 100644
index 0000000..37de0d3
--- /dev/null
+++ b/src/solvers/coord/dreo.h
@@ -0,0 +1,102 @@
1#define DRESEP_CLASSES 81
2
3STATIC uint64_t coord_dresep_nosym(cube_t);
4STATIC cube_t invcoord_dresep_nosym(uint64_t);
5STATIC cube_t coordinate_dreo_merge(cube_t, cube_t);
6
7STATIC uint64_t coordinate_dreo_coord(cube_t, const void *);
8STATIC cube_t coordinate_dreo_cube(uint64_t, const void *);
9STATIC bool coordinate_dreo_isnasty(uint64_t, const void *);
10STATIC size_t coordinate_dreo_gendata(void *);
11
12STATIC bool is_dreo_solvable(cube_t);
13
14STATIC coord_t coordinate_dreo = {
15 .name = "DREO",
16 .coord = &coordinate_dreo_coord,
17 .cube = &coordinate_dreo_cube,
18 .isnasty = &coordinate_dreo_isnasty,
19 .gendata = coordinate_dreo_gendata,
20 .max = DRESEP_CLASSES * POW_3_7,
21 .trans_mask = TM_UDRLFIX,
22 .moves_mask = MM_EO,
23 .axistrans = {
24 [AXIS_UD] = TRANS_UFr,
25 [AXIS_RL] = TRANS_RFr,
26 [AXIS_FB] = TRANS_FDr,
27 },
28 .is_admissible = &solution_lastqt_cw,
29 .is_solvable = &is_dreo_solvable,
30 .sym = {
31 .classes = DRESEP_CLASSES,
32 .max = COMB_12_4,
33 .coord = &coord_dresep_nosym,
34 .cube = &invcoord_dresep_nosym,
35 .max2 = POW_3_7,
36 .coord2 = &coord_co_u,
37 .cube2 = &invcoord_co_u,
38 .merge = &coordinate_dreo_merge,
39 },
40};
41
42STATIC uint64_t
43coord_dresep_nosym(cube_t cube)
44{
45 return (uint64_t)coord_esep(cube) / COMB_8_4;
46}
47
48STATIC cube_t
49invcoord_dresep_nosym(uint64_t coord)
50{
51 return invcoord_esep(coord * COMB_8_4);
52}
53
54STATIC cube_t
55coordinate_dreo_merge(cube_t c1, cube_t c2)
56{
57 cube_t merged;
58
59 merged = c1;
60 copy_corners(&merged, c2);
61
62 return merged;
63}
64
65STATIC uint64_t
66coordinate_dreo_coord(cube_t cube, const void *data)
67{
68 return coord_coord_generic(&coordinate_dreo, cube, data);
69}
70
71STATIC cube_t
72coordinate_dreo_cube(uint64_t i, const void *data)
73{
74 return coord_cube_generic(&coordinate_dreo, i, data);
75}
76
77STATIC bool
78coordinate_dreo_isnasty(uint64_t i, const void *data)
79{
80 return coord_isnasty_generic(&coordinate_dreo, i, data);
81}
82
83STATIC size_t
84coordinate_dreo_gendata(void *data)
85{
86 return coord_gendata_generic(&coordinate_dreo, data);
87}
88
89STATIC bool
90is_dreo_solvable(cube_t cube) {
91 uint8_t c[8], e[12], i, cocount;
92
93 if (coord_eo(cube) != 0)
94 return false;
95
96 pieces(&cube, c, e);
97
98 for (i = 0, cocount = 0; i < 8; i++)
99 cocount += (c[i] & COBITS_2) >> COSHIFT;
100
101 return cocount % 3 == 0;
102}
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index b83be01..a0685c4 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -2,6 +2,7 @@ STATIC uint64_t coordinate_eo_coord(cube_t, const void *);
2STATIC cube_t coordinate_eo_cube(uint64_t, const void *); 2STATIC cube_t coordinate_eo_cube(uint64_t, const void *);
3STATIC bool coordinate_eo_isnasty(uint64_t, const void *); 3STATIC bool coordinate_eo_isnasty(uint64_t, const void *);
4STATIC size_t coordinate_eo_gendata(void *); 4STATIC size_t coordinate_eo_gendata(void *);
5STATIC bool is_eo_even(cube_t);
5 6
6STATIC coord_t coordinate_eo = { 7STATIC coord_t coordinate_eo = {
7 .name = "EO", 8 .name = "EO",
@@ -18,6 +19,7 @@ STATIC coord_t coordinate_eo = {
18 [AXIS_FB] = TRANS_UFr, 19 [AXIS_FB] = TRANS_UFr,
19 }, 20 },
20 .is_admissible = &solution_lastqt_cw, 21 .is_admissible = &solution_lastqt_cw,
22 .is_solvable = &is_eo_even,
21 .sym = {0}, 23 .sym = {0},
22}; 24};
23 25
@@ -46,3 +48,16 @@ coordinate_eo_gendata(void *data)
46{ 48{
47 return 0; 49 return 0;
48} 50}
51
52STATIC bool
53is_eo_even(cube_t cube)
54{
55 uint8_t c[8], e[12], i, count;
56
57 pieces(&cube, c, e);
58
59 for (i = 0, count = 0; i < 12; i++)
60 count += (e[i] & EOBIT) >> EOSHIFT;
61
62 return count % 2 == 0;
63}
diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h
index 423dad1..63e1631 100644
--- a/src/solvers/coord/gendata.h
+++ b/src/solvers/coord/gendata.h
@@ -39,6 +39,9 @@ gendata_coord(const coord_t coord[static 1], void *buf)
39 39
40 coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE; 40 coord_data = buf == NULL ? NULL : ((uint8_t *)buf) + INFOSIZE;
41 coord_dsize = coord->gendata(coord_data); 41 coord_dsize = coord->gendata(coord_data);
42 if (coord_dsize == SIZE_MAX)
43 goto gendata_coord_error;
44
42 ninfo = coord_dsize == 0 ? 1 : 2; 45 ninfo = coord_dsize == 0 ? 1 : 2;
43 tablesize = DIV_ROUND_UP(coord->max, 2); 46 tablesize = DIV_ROUND_UP(coord->max, 2);
44 47
@@ -77,6 +80,10 @@ gendata_coord(const coord_t coord[static 1], void *buf)
77 80
78gendata_coord_return_size: 81gendata_coord_return_size:
79 return ninfo * INFOSIZE + coord_dsize + tablesize; 82 return ninfo * INFOSIZE + coord_dsize + tablesize;
83
84gendata_coord_error:
85 LOG("An unexpected error occurred when generating the data.\n");
86 return 0;
80} 87}
81 88
82STATIC tableinfo_t 89STATIC tableinfo_t
@@ -167,6 +174,8 @@ genptable_coord_fillneighbors(
167 c = coord->cube(i, data); 174 c = coord->cube(i, data);
168 tot = 0; 175 tot = 0;
169 for (m = 0; m < NMOVES; m++) { 176 for (m = 0; m < NMOVES; m++) {
177 if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask))
178 continue;
170 moved = move(c, m); 179 moved = move(c, m);
171 ii = coord->coord(moved, data); 180 ii = coord->coord(moved, data);
172 isnasty = coord->isnasty(ii, data); 181 isnasty = coord->isnasty(ii, data);
@@ -216,6 +225,8 @@ genptable_coord_fillfromnew(
216 for (j = 0, found = false; j < nsim && !found; j++) { 225 for (j = 0, found = false; j < nsim && !found; j++) {
217 c = coord->cube(sim[j], data); 226 c = coord->cube(sim[j], data);
218 for (m = 0; m < NMOVES; m++) { 227 for (m = 0; m < NMOVES; m++) {
228 if (!((UINT32_C(1) << (uint32_t)m) & coord->moves_mask))
229 continue;
219 ii = coord->coord(move(c, m), data); 230 ii = coord->coord(move(c, m), data);
220 if (get_coord_pval(coord, table, ii) < d) { 231 if (get_coord_pval(coord, table, ii) < d) {
221 found = true; 232 found = true;
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h
index 7d43d45..9409bb6 100644
--- a/src/solvers/coord/list.h
+++ b/src/solvers/coord/list.h
@@ -1,5 +1,6 @@
1coord_t *all_coordinates[] = { 1coord_t *all_coordinates[] = {
2 &coordinate_eo, 2 &coordinate_eo,
3 &coordinate_dr, 3 &coordinate_dr,
4 &coordinate_dreo,
4 NULL 5 NULL
5}; 6};
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index fa4134a..8806d17 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -135,11 +135,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
135 ret = 0; 135 ret = 0;
136 if (coord_continue_onnormal(arg)) { 136 if (coord_continue_onnormal(arg)) {
137 l = arg->solution_moves->nmoves; 137 l = arg->solution_moves->nmoves;
138 if (l == 0) { 138 mm = arg->coord->moves_mask;
139 mm = MM_ALLMOVES; 139 if (l != 0) {
140 } else {
141 m = arg->solution_moves->moves[l-1]; 140 m = arg->solution_moves->moves[l-1];
142 mm = allowedmask[movebase(m)]; 141 mm &= allowedmask[movebase(m)];
143 } 142 }
144 arg->solution_moves->nmoves++; 143 arg->solution_moves->nmoves++;
145 arg->lastisnormal = true; 144 arg->lastisnormal = true;
@@ -165,11 +164,10 @@ solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
165 164
166 if (coord_continue_oninverse(arg)) { 165 if (coord_continue_oninverse(arg)) {
167 l = arg->solution_moves->npremoves; 166 l = arg->solution_moves->npremoves;
168 if (l == 0) { 167 mm = arg->coord->moves_mask;
169 mm = MM_ALLMOVES; 168 if (l != 0) {
170 } else {
171 m = arg->solution_moves->premoves[l-1]; 169 m = arg->solution_moves->premoves[l-1];
172 mm = allowedmask[movebase(m)]; 170 mm &= allowedmask[movebase(m)];
173 } 171 }
174 arg->solution_moves->npremoves++; 172 arg->solution_moves->npremoves++;
175 arg->lastisnormal = false; 173 arg->lastisnormal = false;
@@ -264,6 +262,12 @@ solve_coord(
264 solution_settings_t solution_settings; 262 solution_settings_t solution_settings;
265 solution_list_t solution_list; 263 solution_list_t solution_list;
266 264
265 t = coord->axistrans[axis];
266 c = transform(cube, t);
267
268 if (!coord->is_solvable(c))
269 goto solve_coord_error_unsolvable;
270
267 if (!solution_list_init(&solution_list, solutions_size, sols)) 271 if (!solution_list_init(&solution_list, solutions_size, sols))
268 goto solve_coord_error_buffer; 272 goto solve_coord_error_buffer;
269 273
@@ -280,9 +284,6 @@ solve_coord(
280 ptable = (uint8_t *)data + info.next + INFOSIZE; 284 ptable = (uint8_t *)data + info.next + INFOSIZE;
281 } 285 }
282 286
283 t = coord->axistrans[axis];
284 c = transform(cube, t);
285
286 solution_moves_reset(&solution_moves); 287 solution_moves_reset(&solution_moves);
287 288
288 solution_settings = (solution_settings_t) { 289 solution_settings = (solution_settings_t) {
@@ -351,4 +352,8 @@ solve_coord_error_data:
351solve_coord_error_buffer: 352solve_coord_error_buffer:
352 LOG("Could not append solution to buffer: size too small\n"); 353 LOG("Could not append solution to buffer: size too small\n");
353 return NISSY_ERROR_BUFFER_SIZE; 354 return NISSY_ERROR_BUFFER_SIZE;
355
356solve_coord_error_unsolvable:
357 LOG("Cube not ready for solving %s\n", coord->name);
358 return NISSY_ERROR_UNSOLVABLE_CUBE;
354} 359}
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index a2eaefe..84ed8eb 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -25,6 +25,7 @@ typedef struct {
25 uint64_t trans_mask; 25 uint64_t trans_mask;
26 uint8_t axistrans[3]; 26 uint8_t axistrans[3];
27 bool (*is_admissible)(const solution_moves_t[static 1]); 27 bool (*is_admissible)(const solution_moves_t[static 1]);
28 bool (*is_solvable)(cube_t);
28 struct { 29 struct {
29 size_t classes; 30 size_t classes;
30 uint64_t max; 31 uint64_t max;

Generated with cgit - Back to sebastiano.tronto.net