aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO_COORDINATES4
-rw-r--r--src/solvers/coord/common.h28
-rw-r--r--src/solvers/coord/coord_solve.h225
-rw-r--r--src/solvers/coord/coord_types_macros.h1
-rw-r--r--src/solvers/coord/eo.h5
-rw-r--r--src/solvers/coord/gendata_coord.h14
-rw-r--r--src/solvers/h48/solve.h2
-rw-r--r--src/utils/constants.h4
8 files changed, 274 insertions, 9 deletions
diff --git a/TODO_COORDINATES b/TODO_COORDINATES
index 7e5628b..0202f49 100644
--- a/TODO_COORDINATES
+++ b/TODO_COORDINATES
@@ -1,6 +1,6 @@
1- solver 1- solver (from TODOs in appending solution)
2 - include NISS
3- test solver for EO 2- test solver for EO
3- add NISS (and add tests for NISS EO)
4- make solve parallelized 4- make solve parallelized
5- other coordinates 5- other coordinates
6 - gendata must handle symmetry 6 - gendata must handle symmetry
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index b54e5e2..1d6e622 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -6,6 +6,8 @@ coord_t *all_coordinates[] = {
6}; 6};
7 7
8STATIC void append_coord_name(const coord_t *, char *); 8STATIC void append_coord_name(const coord_t *, char *);
9STATIC coord_t *parse_coord(const char *, int);
10STATIC uint8_t parse_axis(const char *, int);
9 11
10STATIC void 12STATIC void
11append_coord_name(const coord_t *coord, char *str) 13append_coord_name(const coord_t *coord, char *str)
@@ -18,3 +20,29 @@ append_coord_name(const coord_t *coord, char *str)
18 20
19 str[j] = '\0'; 21 str[j] = '\0';
20} 22}
23
24STATIC coord_t *
25parse_coord(const char *coord, int n)
26{
27 int i;
28
29 for (i = 0; all_coordinates[i] != NULL; i++)
30 if (!strncmp(all_coordinates[i]->name, coord, n))
31 return all_coordinates[i];
32
33 return NULL;
34}
35
36STATIC uint8_t
37parse_axis(const char *axis, int n)
38{
39 if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) {
40 return AXIS_UD;
41 } else if (!strncmp(axis, "RL", n) || !strncmp(axis, "LR", n)) {
42 return AXIS_RL;
43 } else if (!strncmp(axis, "FB", n) || !strncmp(axis, "BF", n)) {
44 return AXIS_FB;
45 }
46
47 return UINT8_ERROR;
48}
diff --git a/src/solvers/coord/coord_solve.h b/src/solvers/coord/coord_solve.h
index 1d7c036..317cb33 100644
--- a/src/solvers/coord/coord_solve.h
+++ b/src/solvers/coord/coord_solve.h
@@ -1,3 +1,228 @@
1#include "coord_types_macros.h" 1#include "coord_types_macros.h"
2#include "common.h" 2#include "common.h"
3#include "gendata_coord.h" 3#include "gendata_coord.h"
4
5#define MAXLEN_COORDSOL 20
6
7typedef struct {
8 cube_t cube;
9 uint8_t depth;
10 uint8_t nmoves;
11 uint8_t moves[MAXLEN_COORDSOL];
12 coord_t *coord;
13 const void *coord_data;
14 const uint8_t *ptable;
15 uint8_t trans;
16 int64_t *nsols;
17 int64_t maxsolutions;
18 int optimal;
19 uint8_t *shortest_sol;
20 uint64_t solutions_size;
21 uint64_t *solutions_used;
22 char **solutions;
23} dfsarg_solve_coord_t;
24
25STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t,
26 uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char);
27STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t,
28 uint8_t, uint64_t, int, int, uint64_t, const void, uint64_t, char);
29STATIC bool solve_coord_appendchar(char *, uint64_t, uint64_t *, char);
30STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *);
31STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *);
32
33STATIC int64_t
34solve_coord_appendsolution(dfsarg_solve_coord_t *arg)
35{
36 uint8_t i, t, tmoves[MAXLEN_COORDSOL];
37
38 if (*arg->nsols >= arg->maxsolutions ||
39 arg->nmoves > *arg->shortest_sol + arg->optimal)
40 return 0;
41
42 sortparallel(arg->moves, arg->nmoves);
43
44 t = inverse_trans(arg->trans);
45 for (i = 0; i < arg->nmoves; i++)
46 tmoves[i] = transform_move(arg->moves[i], t);
47
48 /* TODO append tmoves[] */
49
50 return 1;
51}
52
53STATIC bool
54solve_coord_appendchar(char *s, uint64_t s_size, uint64_t *s_used, char c)
55{
56 if (s_size == *s_used)
57 return false;
58
59 s[*s_used] = c;
60 (*s_used)++;
61
62 return true;
63}
64
65STATIC int64_t
66solve_coord_dfs(dfsarg_solve_coord_t *arg)
67{
68 uint64_t coord;
69 uint8_t pval;
70
71 coord = arg->coord->coord(arg->cube, arg->coord_data);
72
73 if (coord == 0) {
74 if (arg->nmoves != arg->depth)
75 return 0;
76 return solve_coord_appendsolution(arg);
77 }
78
79 pval = get_coord_pval(arg->coord, arg->ptable, coord);
80 if (arg->nmoves + pval > arg->depth)
81 return 0;
82
83 /* TODO recursive call */
84 /* Is allowednextmove available here? */
85
86 return 0;
87}
88
89STATIC int64_t
90solve_coord_dispatch(
91 cube_t cube,
92 const char *coord_axis,
93 uint8_t nissflag,
94 uint8_t minmoves,
95 uint8_t maxmoves,
96 uint64_t maxsolutions,
97 int optimal,
98 int threads,
99 uint64_t data_size,
100 const void *data,
101 uint64_t sols_size,
102 char *sols
103)
104{
105 int i, n;
106 coord_t *coord;
107 uint8_t axis;
108
109 n = strlen(coord_axis);
110 for (i = 0; coord_axis[i] != ' ' && coord_axis[i] != '\0'; i++) ;
111
112 coord = parse_coord(coord_axis, i);
113 axis = parse_axis(coord_axis + i + 1, n - i - 1);
114
115 if (coord == NULL) {
116 LOG("Could not parse coordinate '%s'\n", coord_axis);
117 return NISSY_ERROR_INVALID_SOLVER;
118 }
119
120 if (axis == UINT8_ERROR) {
121 LOG("Could not parse axis from '%s'\n", coord_axis);
122 return NISSY_ERROR_INVALID_SOLVER;
123 }
124
125 return solve_coord(cube, coord, axis, nissflag, minmoves, maxmoves,
126 maxsolutions, optimal, threads, data_size, data, sols_size, sols);
127}
128
129STATIC int64_t
130solve_coord(
131 cube_t cube,
132 coord_t *coord,
133 uint8_t axis,
134 uint8_t nissflag,
135 uint8_t minmoves,
136 uint8_t maxmoves,
137 uint64_t maxsolutions,
138 int optimal,
139 int threads,
140 uint64_t data_size,
141 const void data,
142 uint64_t sols_size,
143 char *sols
144)
145{
146 int8_t d;
147 uint8_t t, shortest_sol;
148 int64_t nsols;
149 uint64_t sols_used;
150 cube_t c;
151 const void *coord_data;
152 const uint8_t *ptable;
153 dfsarg_solve_coord_t arg;
154 tableinfo_t info;
155
156 if (readtableinfo(data_size, data, &info) != NISSY_OK)
157 goto solve_coord_error_data;
158
159 if (info.type == TABLETYPE_PRUNING) {
160 /* Only the pruning table */
161 coord_data = NULL;
162 ptable = (uint8_t *)data + INFOSIZE;
163 } else {
164 /* Coordinate has extra data */
165 coord_data = data + INFOSIZE;
166 ptable = (uint8_t *)data + info.next + INFOSIZE;
167 }
168
169 nsols = 0;
170 sols_used = 0;
171 shortest_sol = MAXLEN_COORDSOL + 1;
172 c = transform(cube, t);
173 t = coord->axistrans[axis];
174
175 arg = (dfsarg_solve_coord_t) {
176 .cube = c,
177 .coord = coord,
178 .coord_data = coord_data,
179 .ptable = ptable,
180 .trans = t,
181 .nsols = &nsols,
182 .maxsolutions = (int64_t)maxsolutions,
183 .optimal = optimal,
184 .shortest_sol = &shortest_sol,
185 .solutions_size = sols_size,
186 .solutions_used = &sols_used,
187 .solutions = &sols,
188 };
189
190 if (coord->coord(c, coord_data) == 0) {
191 if (minmoves == 0) {
192 nsols = 1;
193 if (!solve_coord_appendchar(
194 sols, sols_size, &sols_used, '\n'))
195 goto solve_coord_error_buffer;
196 }
197 goto solve_coord_done;
198 }
199
200 for (
201 d = MAX(minmoves, 1);
202 d <= maxmoves && nsols < (int64_t)maxsolutions
203 && !(nsols != 0 && d > shortest_sol + optimal);
204 d++
205 ) {
206 if (d >= 10)
207 LOG("Found %" PRId64 " solutions, searching at depth %"
208 PRId8 "\n", nsols, d);
209
210 arg.depth = d;
211 arg.nmoves = 0;
212 nsols += solve_coord_dfs(&arg);
213 }
214
215solve_coord_done:
216 if (!solve_coord_appendchar(sols, sols_size, &sols_used, '\0'))
217 goto solve_coord_error_buffer;
218
219 return nsols;
220
221solve_coord_error_data:
222 LOG("solve_coord: error reading table\n");
223 return NISSY_ERROR_DATA;
224
225solve_coord_error_buffer:
226 LOG("Could not append solution to buffer: size too small\n");
227 return NISSY_ERROR_BUFFER_SIZE;
228}
diff --git a/src/solvers/coord/coord_types_macros.h b/src/solvers/coord/coord_types_macros.h
index 4f2877c..594f594 100644
--- a/src/solvers/coord/coord_types_macros.h
+++ b/src/solvers/coord/coord_types_macros.h
@@ -10,4 +10,5 @@ typedef struct {
10 uint64_t max; 10 uint64_t max;
11 uint32_t moves_mask; 11 uint32_t moves_mask;
12 uint64_t trans_mask; 12 uint64_t trans_mask;
13 uint8_t axistrans[3];
13} coord_t; 14} coord_t;
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index d6604d9..449397f 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -10,6 +10,11 @@ STATIC coord_t coordinate_eo = {
10 .max = POW_2_11, 10 .max = POW_2_11,
11 .trans_mask = TM_ALLTRANS, 11 .trans_mask = TM_ALLTRANS,
12 .moves_mask = MM_ALLMOVES, 12 .moves_mask = MM_ALLMOVES,
13 .axistrans = {
14 [AXIS_UD] = TRANS_FDr,
15 [AXIS_RL] = TRANS_URr,
16 [AXIS_FB] = TRANS_UFr,
17 },
13}; 18};
14 19
15STATIC uint64_t 20STATIC uint64_t
diff --git a/src/solvers/coord/gendata_coord.h b/src/solvers/coord/gendata_coord.h
index b3932cd..3d385e9 100644
--- a/src/solvers/coord/gendata_coord.h
+++ b/src/solvers/coord/gendata_coord.h
@@ -7,14 +7,16 @@ STATIC void set_coord_pval(const coord_t *, uint8_t *, uint64_t, uint8_t);
7STATIC size_t 7STATIC size_t
8gendata_coordinate_name(const char *name, void *buf) 8gendata_coordinate_name(const char *name, void *buf)
9{ 9{
10 int i; 10 coord_t *coord;
11 11
12 for (i = 0; all_coordinates[i] != NULL; i++) 12 coord = parse_coord(name, strlen(name));
13 if (strcmp(all_coordinates[i]->name, name) == 0) 13 if (coord == NULL) {
14 return gendata_coordinate(all_coordinates[i], buf); 14 LOG("Cannot generate data for coordinate '%s': not found\n",
15 name);
16 return 0;
17 }
15 18
16 LOG("Cannot generate data for coordinate '%s': not found\n", name); 19 return gendata_coordinate(coord, buf);
17 return 0;
18} 20}
19 21
20STATIC size_t 22STATIC size_t
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 6277082..44f6a89 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -457,7 +457,7 @@ solve_h48(
457 pthread_t thread[THREADS]; 457 pthread_t thread[THREADS];
458 pthread_mutex_t solutions_mutex; 458 pthread_mutex_t solutions_mutex;
459 459
460 if(readtableinfo_n(data_size, data, 2, &info) != NISSY_OK) 460 if (readtableinfo_n(data_size, data, 2, &info) != NISSY_OK)
461 goto solve_h48_error_data; 461 goto solve_h48_error_data;
462 462
463 cocsepdata = (uint32_t *)((char *)data + INFOSIZE); 463 cocsepdata = (uint32_t *)((char *)data + INFOSIZE);
diff --git a/src/utils/constants.h b/src/utils/constants.h
index 3d8bf5e..1db1940 100644
--- a/src/utils/constants.h
+++ b/src/utils/constants.h
@@ -93,6 +93,10 @@ STATIC int64_t binomial[12][12] = {
93#define TRANS_BDm UINT8_C(46) 93#define TRANS_BDm UINT8_C(46)
94#define TRANS_BLm UINT8_C(47) 94#define TRANS_BLm UINT8_C(47)
95 95
96#define AXIS_UD UINT8_C(0)
97#define AXIS_RL UINT8_C(1)
98#define AXIS_FB UINT8_C(2)
99
96#define NMOVES (1+MOVE_B3) 100#define NMOVES (1+MOVE_B3)
97#define NTRANS (1+TRANS_BLm) 101#define NTRANS (1+TRANS_BLm)
98 102

Generated with cgit - Back to sebastiano.tronto.net