aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48/solve.h
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-08-18 14:26:45 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-08-18 14:26:45 +0200
commit18c9a8b8905304cf5f8fc15825769046a3144866 (patch)
treea7807bb32b0a5d9ded7d3cedccc598f64a9b00fe /src/solvers/h48/solve.h
parentf25a10e19eca294c4e6a99e4f80ce5cfd11a0e5f (diff)
downloadnissy-core-18c9a8b8905304cf5f8fc15825769046a3144866.tar.gz
nissy-core-18c9a8b8905304cf5f8fc15825769046a3144866.zip
Reorganized folder structure
Diffstat (limited to 'src/solvers/h48/solve.h')
-rw-r--r--src/solvers/h48/solve.h242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
new file mode 100644
index 0000000..8531a40
--- /dev/null
+++ b/src/solvers/h48/solve.h
@@ -0,0 +1,242 @@
1typedef struct {
2 cube_t cube;
3 cube_t inverse;
4 int8_t nmoves;
5 int8_t depth;
6 uint8_t moves[MAXLEN];
7 int64_t *nsols;
8 int64_t maxsolutions;
9 uint8_t h;
10 uint32_t *cocsepdata;
11 uint32_t *h48data;
12 char **nextsol;
13} dfsarg_solveh48_t;
14
15typedef struct {
16 cube_t cube;
17 int8_t nmoves;
18 int8_t depth;
19 uint8_t moves[MAXLEN];
20 uint32_t *cocsepdata;
21 uint32_t *h48data;
22 char *s;
23} dfsarg_solveh48stats_t;
24
25_static void solve_h48_appendsolution(dfsarg_solveh48_t *);
26_static_inline bool solve_h48_stop(dfsarg_solveh48_t *);
27_static int64_t solve_h48_dfs(dfsarg_solveh48_t *);
28_static int64_t solve_h48(
29 cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *);
30
31_static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *);
32_static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 12]);
33
34_static void
35solve_h48_appendsolution(dfsarg_solveh48_t *arg)
36{
37 int strl;
38
39 strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
40 LOG("Solution found: %s\n", *arg->nextsol);
41 *arg->nextsol += strl;
42 **arg->nextsol = '\n';
43 (*arg->nextsol)++;
44 (*arg->nsols)++;
45}
46
47_static_inline bool
48solve_h48_stop(dfsarg_solveh48_t *arg)
49{
50 uint32_t data, data_inv;
51 int8_t bound;
52
53 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data);
54 if (bound + arg->nmoves > arg->depth)
55 return true;
56
57 bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv);
58 if (bound + arg->nmoves > arg->depth)
59 return true;
60
61/*
62 bound = get_h48_bound(arg->cube, data, arg->h, arg->h48data);
63LOG("Using pval %" PRId8 "\n", bound);
64 if (bound + arg->nmoves > arg->depth)
65 return true;
66
67 bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->h48data);
68 if (bound + arg->nmoves > arg->depth)
69 return true;
70*/
71
72 return false;
73}
74
75_static int64_t
76solve_h48_dfs(dfsarg_solveh48_t *arg)
77{
78 dfsarg_solveh48_t nextarg;
79 int64_t ret;
80 uint8_t m;
81
82 if (*arg->nsols == arg->maxsolutions)
83 return 0;
84
85 if (solve_h48_stop(arg))
86 return 0;
87
88 if (issolved(arg->cube)) {
89 if (arg->nmoves != arg->depth)
90 return 0;
91 solve_h48_appendsolution(arg);
92 return 1;
93 }
94
95 /* TODO: avoid copy, change arg and undo changes after recursion */
96 nextarg = *arg;
97 nextarg.nmoves = arg->nmoves + 1;
98 ret = 0;
99 for (m = 0; m < 18; m++) {
100 nextarg.moves[arg->nmoves] = m;
101 if (!allowednextmove(nextarg.moves, nextarg.nmoves)) {
102 /* If a move is not allowed, neither are its 180
103 * and 270 degree variations */
104 m += 2;
105 continue;
106 }
107 nextarg.cube = move(arg->cube, m);
108 nextarg.inverse = inverse(nextarg.cube); /* TODO: use premove */
109 ret += solve_h48_dfs(&nextarg);
110 }
111
112 return ret;
113}
114
115_static int64_t
116solve_h48(
117 cube_t cube,
118 int8_t minmoves,
119 int8_t maxmoves,
120 int8_t maxsolutions,
121 uint8_t h,
122 const void *data,
123 char *solutions
124)
125{
126 int64_t nsols;
127 dfsarg_solveh48_t arg;
128
129 arg = (dfsarg_solveh48_t) {
130 .cube = cube,
131 .inverse = inverse(cube),
132 .nsols = &nsols,
133 .maxsolutions = maxsolutions,
134 .h = h,
135 .cocsepdata = (uint32_t *)data,
136 .h48data = ((uint32_t *)data) + COCSEP_FULLSIZE / 4,
137 .nextsol = &solutions
138 };
139
140 nsols = 0;
141 for (arg.depth = minmoves;
142 arg.depth <= maxmoves && nsols < maxsolutions;
143 arg.depth++)
144 {
145 LOG("Found %" PRId64 " solutions, searching at depth %"
146 PRId8 "\n", nsols, arg.depth);
147 arg.nmoves = 0;
148 solve_h48_dfs(&arg);
149 }
150
151 return nsols;
152}
153
154/*
155The h48stats solver computes how many moves it takes to solve to
156each of the 12 h48 coordinates, one for each value of h from 0 to 11.
157The solutions array is filled with the length of the solutions. The
158solution array is therefore not a printable string.
159*/
160_static int64_t
161solve_h48stats_dfs(dfsarg_solveh48stats_t *arg)
162{
163 const int64_t limit = 11;
164
165 int8_t bound, u;
166 uint8_t m;
167 uint32_t d;
168 int64_t coord, h;
169 dfsarg_solveh48stats_t nextarg;
170
171 /* Check cocsep lower bound (corners only) */
172 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d);
173 if (bound + arg->nmoves > arg->depth)
174 return 0;
175
176 /* Check h48 lower bound for h=0 (esep, but no eo) */
177 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 0);
178 bound = get_esep_pval(arg->h48data, coord);
179 if (bound + arg->nmoves > arg->depth)
180 return 0;
181
182 /* Update all other values, if solved */
183 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11);
184 for (h = 0; h <= limit; h++) {
185 u = coord >> (11-h) == 0 && arg->s[h] == 99;
186 arg->s[h] = u * arg->nmoves + (1-u) * arg->s[h];
187 }
188
189 if (arg->s[limit] != 99)
190 return 0;
191
192 nextarg = *arg;
193 nextarg.nmoves = arg->nmoves + 1;
194 for (m = 0; m < 18; m++) {
195 nextarg.moves[arg->nmoves] = m;
196 if (!allowednextmove(nextarg.moves, nextarg.nmoves)) {
197 /* If a move is not allowed, neither are its 180
198 * and 270 degree variations */
199 m += 2;
200 continue;
201 }
202 nextarg.cube = move(arg->cube, m);
203 solve_h48stats_dfs(&nextarg);
204 }
205
206 return 0;
207}
208
209_static int64_t
210solve_h48stats(
211 cube_t cube,
212 int8_t maxmoves,
213 const void *data,
214 char solutions[static 12]
215)
216{
217 int i;
218 size_t cocsepsize;
219 dfsarg_solveh48stats_t arg;
220
221 cocsepsize = gendata_cocsep(NULL, NULL, NULL);
222
223 arg = (dfsarg_solveh48stats_t) {
224 .cube = cube,
225 .cocsepdata = (uint32_t *)data,
226 .h48data = ((uint32_t *)data) + (cocsepsize/4),
227 .s = solutions
228 };
229
230 for (i = 0; i < 12; i++)
231 solutions[i] = (char)99;
232
233 for (arg.depth = 0;
234 arg.depth <= maxmoves && solutions[11] == 99;
235 arg.depth++)
236 {
237 arg.nmoves = 0;
238 solve_h48stats_dfs(&arg);
239 }
240
241 return 0;
242}

Generated with cgit - Back to sebastiano.tronto.net