aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/coord/solve.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/solvers/coord/solve.h')
-rw-r--r--src/solvers/coord/solve.h224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
new file mode 100644
index 0000000..e954aac
--- /dev/null
+++ b/src/solvers/coord/solve.h
@@ -0,0 +1,224 @@
1#define MAXLEN_COORDSOL 20
2
3typedef struct {
4 cube_t cube;
5 uint8_t depth;
6 uint8_t nmoves;
7 uint8_t moves[MAXLEN_COORDSOL];
8 coord_t *coord;
9 const void *coord_data;
10 const uint8_t *ptable;
11 uint8_t trans;
12 int64_t *nsols;
13 int64_t maxsolutions;
14 int optimal;
15 uint8_t *shortest_sol;
16 uint64_t solutions_size;
17 uint64_t *solutions_used;
18 char **solutions;
19} dfsarg_solve_coord_t;
20
21STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t,
22 uint8_t, uint64_t, int, int, uint64_t, const void *, uint64_t, char *);
23STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t,
24 uint8_t, uint64_t, int, int, uint64_t, const void *, uint64_t, char *);
25STATIC bool solve_coord_appendchar(char *, uint64_t, uint64_t *, char);
26STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *);
27STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *);
28
29STATIC int64_t
30solve_coord_appendsolution(dfsarg_solve_coord_t *arg)
31{
32 uint8_t i, t, tmoves[MAXLEN_COORDSOL];
33
34 if (*arg->nsols >= arg->maxsolutions ||
35 arg->nmoves > *arg->shortest_sol + arg->optimal)
36 return 0;
37
38 sortparallel(arg->moves, arg->nmoves);
39
40 t = inverse_trans(arg->trans);
41 for (i = 0; i < arg->nmoves; i++)
42 tmoves[i] = transform_move(arg->moves[i], t);
43
44 /* TODO append tmoves[] */
45
46 return 1;
47}
48
49STATIC bool
50solve_coord_appendchar(char *s, uint64_t s_size, uint64_t *s_used, char c)
51{
52 if (s_size == *s_used)
53 return false;
54
55 s[*s_used] = c;
56 (*s_used)++;
57
58 return true;
59}
60
61STATIC int64_t
62solve_coord_dfs(dfsarg_solve_coord_t *arg)
63{
64 uint64_t coord;
65 uint8_t pval;
66
67 coord = arg->coord->coord(arg->cube, arg->coord_data);
68
69 if (coord == 0) {
70 if (arg->nmoves != arg->depth)
71 return 0;
72 return solve_coord_appendsolution(arg);
73 }
74
75 pval = get_coord_pval(arg->coord, arg->ptable, coord);
76 if (arg->nmoves + pval > arg->depth)
77 return 0;
78
79 /* TODO recursive call */
80 /* Is allowednextmove available here? */
81
82 return 0;
83}
84
85STATIC int64_t
86solve_coord_dispatch(
87 cube_t cube,
88 const char *coord_axis,
89 uint8_t nissflag,
90 uint8_t minmoves,
91 uint8_t maxmoves,
92 uint64_t maxsolutions,
93 int optimal,
94 int threads,
95 uint64_t data_size,
96 const void *data,
97 uint64_t sols_size,
98 char *sols
99)
100{
101 int i, n;
102 coord_t *coord;
103 uint8_t axis;
104
105 n = strlen(coord_axis);
106 for (i = 0; coord_axis[i] != ' ' && coord_axis[i] != '\0'; i++) ;
107
108 coord = parse_coord(coord_axis, i);
109 axis = parse_axis(coord_axis + i + 1, n - i - 1);
110
111 if (coord == NULL) {
112 LOG("Could not parse coordinate '%s'\n", coord_axis);
113 return NISSY_ERROR_INVALID_SOLVER;
114 }
115
116 if (axis == UINT8_ERROR) {
117 LOG("Could not parse axis from '%s'\n", coord_axis);
118 return NISSY_ERROR_INVALID_SOLVER;
119 }
120
121 return solve_coord(cube, coord, axis, nissflag, minmoves, maxmoves,
122 maxsolutions, optimal, threads, data_size, data, sols_size, sols);
123}
124
125STATIC int64_t
126solve_coord(
127 cube_t cube,
128 coord_t *coord,
129 uint8_t axis,
130 uint8_t nissflag,
131 uint8_t minmoves,
132 uint8_t maxmoves,
133 uint64_t maxsolutions,
134 int optimal,
135 int threads,
136 uint64_t data_size,
137 const void *data,
138 uint64_t sols_size,
139 char *sols
140)
141{
142 int8_t d;
143 uint8_t t, shortest_sol;
144 int64_t nsols;
145 uint64_t sols_used;
146 cube_t c;
147 const void *coord_data;
148 const uint8_t *ptable;
149 dfsarg_solve_coord_t arg;
150 tableinfo_t info;
151
152 if (readtableinfo(data_size, data, &info) != NISSY_OK)
153 goto solve_coord_error_data;
154
155 if (info.type == TABLETYPE_PRUNING) {
156 /* Only the pruning table */
157 coord_data = NULL;
158 ptable = (uint8_t *)data + INFOSIZE;
159 } else {
160 /* Coordinate has extra data */
161 coord_data = (uint8_t *)data + INFOSIZE;
162 ptable = (uint8_t *)data + info.next + INFOSIZE;
163 }
164
165 nsols = 0;
166 sols_used = 0;
167 shortest_sol = MAXLEN_COORDSOL + 1;
168 c = transform(cube, t);
169 t = coord->axistrans[axis];
170
171 arg = (dfsarg_solve_coord_t) {
172 .cube = c,
173 .coord = coord,
174 .coord_data = coord_data,
175 .ptable = ptable,
176 .trans = t,
177 .nsols = &nsols,
178 .maxsolutions = (int64_t)maxsolutions,
179 .optimal = optimal,
180 .shortest_sol = &shortest_sol,
181 .solutions_size = sols_size,
182 .solutions_used = &sols_used,
183 .solutions = &sols,
184 };
185
186 if (coord->coord(c, coord_data) == 0) {
187 if (minmoves == 0) {
188 nsols = 1;
189 if (!solve_coord_appendchar(
190 sols, sols_size, &sols_used, '\n'))
191 goto solve_coord_error_buffer;
192 }
193 goto solve_coord_done;
194 }
195
196 for (
197 d = MAX(minmoves, 1);
198 d <= maxmoves && nsols < (int64_t)maxsolutions
199 && !(nsols != 0 && d > shortest_sol + optimal);
200 d++
201 ) {
202 if (d >= 10)
203 LOG("Found %" PRId64 " solutions, searching at depth %"
204 PRId8 "\n", nsols, d);
205
206 arg.depth = d;
207 arg.nmoves = 0;
208 nsols += solve_coord_dfs(&arg);
209 }
210
211solve_coord_done:
212 if (!solve_coord_appendchar(sols, sols_size, &sols_used, '\0'))
213 goto solve_coord_error_buffer;
214
215 return nsols;
216
217solve_coord_error_data:
218 LOG("solve_coord: error reading table\n");
219 return NISSY_ERROR_DATA;
220
221solve_coord_error_buffer:
222 LOG("Could not append solution to buffer: size too small\n");
223 return NISSY_ERROR_BUFFER_SIZE;
224}

Generated with cgit - Back to sebastiano.tronto.net