aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-06-30 12:44:47 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-06-30 12:44:47 +0200
commit3c9efb490ccbe1b0d7768d77fcdcac012c00e8c6 (patch)
tree15791a5a2862801e214ed389d72d35b48a0dc8bc
parent05bdcfef13ef2bdd05df6af13a74ec3cd7fcd22f (diff)
downloadnissy-core-3c9efb490ccbe1b0d7768d77fcdcac012c00e8c6.tar.gz
nissy-core-3c9efb490ccbe1b0d7768d77fcdcac012c00e8c6.zip
Added a solver, but found out h48 table is broken
-rw-r--r--.gitignore1
-rw-r--r--Makefile6
-rw-r--r--README.md17
-rw-r--r--TODO.txt12
-rw-r--r--shell.c97
-rw-r--r--src/cube_public.h11
-rw-r--r--src/solve_generic.h3
-rw-r--r--src/solve_h48.h174
-rw-r--r--test/103_gendata_h48/00_h_0.out2
-rw-r--r--test/103_gendata_h48/01_h_1.out2
10 files changed, 265 insertions, 60 deletions
diff --git a/.gitignore b/.gitignore
index ce4229b..16439b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ gen
5debuggen 5debuggen
6perf.data 6perf.data
7perf.data.old 7perf.data.old
8run
8tables/* 9tables/*
9test/*/runtest 10test/*/runtest
10test/run 11test/run
diff --git a/Makefile b/Makefile
index 5859eca..43bc3e4 100644
--- a/Makefile
+++ b/Makefile
@@ -24,4 +24,8 @@ shell: cube.o
24 mkdir -p tables 24 mkdir -p tables
25 ${CC} ${CFLAGS} -o run cube.o shell.c 25 ${CC} ${CFLAGS} -o run cube.o shell.c
26 26
27.PHONY: all clean test benchmark shell 27debugshell: debugcube.o
28 mkdir -p tables
29 ${CC} ${DBGFLAGS} -o run debugcube.o shell.c
30
31.PHONY: all clean test benchmark shell debugshell
diff --git a/README.md b/README.md
index 71015b0..098b960 100644
--- a/README.md
+++ b/README.md
@@ -27,3 +27,20 @@ $ TEST=coord make test
27``` 27```
28 28
29Due to ongoing changes, benchmarks are currently broken. 29Due to ongoing changes, benchmarks are currently broken.
30
31## Solving
32
33Notes for myself while this is work in progress
34
35```
36$ make shell
37$ ./run frommoves -moves (scramble)
38```
39
40copy the result, then
41
42```
43$ ./run solve -solver "H48" -options "2;20" -n 1 -M 10 -cube (paste here)
44```
45
46Options can be changed from `2;20` to `n;20` for larger tables.
diff --git a/TODO.txt b/TODO.txt
index befedff..6f212c3 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,8 +1,16 @@
1Solver 1Solver
2 - write a solver (how many tricks? some, but not all are needed) 2 - fix and cleanup current implementation
3 - fails for UFRUFU when using full table
4 SOMETHING IS WRONG FOR coord_h48 = 3! (pvalue 15??)
5 - do not copy dfsarg, change and undo
6 - implement and use premove (and test) instead of inverting
3 - benchmark for solve 7 - benchmark for solve
4 table generation, where to keep tables? in benchmark folder or in tables/? 8 table generation, where to keep tables? in benchmark folder or in tables/?
9 - more tricks for solver, optimize, try larger tables
5 - remove solve_simple and maybe the whole solve_generic 10 - remove solve_simple and maybe the whole solve_generic
11 - shell: silently accept other formats too?
12 - shell: allow generating multiple tables for different options
13 - gendata: move info at start of tables?
6 14
7Cleanup cube_public and interface 15Cleanup cube_public and interface
8 - remove options, use only solver name 16 - remove options, use only solver name
@@ -17,6 +25,8 @@ Goal: find out which k value is best
17 25
18Improvements 26Improvements
19 - check hash of generated data 27 - check hash of generated data
28 - use interleaved tables (e.g. big table with k=2 or k=1 and interleaved
29 small table with k=4 for better backup pruning)
20 30
21## H48 optimal solver (some has already been implemented) 31## H48 optimal solver (some has already been implemented)
22 32
diff --git a/shell.c b/shell.c
index 1b8b70e..5cd8fb2 100644
--- a/shell.c
+++ b/shell.c
@@ -1,5 +1,6 @@
1#include <inttypes.h> 1#include <inttypes.h>
2#include <errno.h> 2#include <errno.h>
3#include <stdarg.h>
3#include <stdbool.h> 4#include <stdbool.h>
4#include <stdio.h> 5#include <stdio.h>
5#include <stdlib.h> 6#include <stdlib.h>
@@ -28,7 +29,6 @@ typedef struct {
28 int8_t maxmoves; 29 int8_t maxmoves;
29 int8_t optimal; 30 int8_t optimal;
30 int64_t maxsolutions; 31 int64_t maxsolutions;
31 int64_t datasize; /* Option for gendata + solve, TODO change? */
32} args_t; 32} args_t;
33 33
34static void print_cube_result(int64_t, char [static 22]); 34static void print_cube_result(int64_t, char [static 22]);
@@ -39,9 +39,7 @@ static int64_t inverse_exec(args_t *);
39static int64_t applymoves_exec(args_t *); 39static int64_t applymoves_exec(args_t *);
40static int64_t applytrans_exec(args_t *); 40static int64_t applytrans_exec(args_t *);
41static int64_t frommoves_exec(args_t *); 41static int64_t frommoves_exec(args_t *);
42static int64_t readcube_exec(args_t *); 42static int64_t convert_exec(args_t *);
43static int64_t writecube_exec(args_t *);
44static int64_t convertcube_exec(args_t *);
45static int64_t datasize_exec(args_t *); 43static int64_t datasize_exec(args_t *);
46static int64_t gendata_exec(args_t *); 44static int64_t gendata_exec(args_t *);
47static int64_t solve_exec(args_t *); 45static int64_t solve_exec(args_t *);
@@ -76,9 +74,7 @@ struct {
76 COMMAND("applymoves", applymoves_exec), 74 COMMAND("applymoves", applymoves_exec),
77 COMMAND("applytrans", applytrans_exec), 75 COMMAND("applytrans", applytrans_exec),
78 COMMAND("frommoves", frommoves_exec), 76 COMMAND("frommoves", frommoves_exec),
79 COMMAND("readcube", readcube_exec), 77 COMMAND("convert", convert_exec),
80 COMMAND("writecube", writecube_exec),
81 COMMAND("convertcube", convertcube_exec),
82 COMMAND("datasize", datasize_exec), 78 COMMAND("datasize", datasize_exec),
83 COMMAND("gendata", gendata_exec), 79 COMMAND("gendata", gendata_exec),
84 COMMAND("solve", solve_exec), 80 COMMAND("solve", solve_exec),
@@ -199,43 +195,19 @@ frommoves_exec(args_t *args)
199 char result[22]; 195 char result[22];
200 int64_t ret; 196 int64_t ret;
201 197
202 ret = nissy_frommoves(args->str_trans, result); 198 ret = nissy_frommoves(args->str_moves, result);
203 print_cube_result(ret, result); 199 print_cube_result(ret, result);
204 200
205 return ret; 201 return ret;
206} 202}
207 203
208static int64_t 204static int64_t
209readcube_exec(args_t *args) 205convert_exec(args_t *args)
210{
211 char result[22];
212 int64_t ret;
213
214 ret = nissy_readcube(args->str_format, args->str_cube, result);
215 print_cube_result(ret, result);
216
217 return ret;
218}
219
220static int64_t
221writecube_exec(args_t *args)
222{
223 char result[PRINTCUBE_BUFFER_SIZE];
224 int64_t ret;
225
226 ret = nissy_writecube(args->str_format, args->str_cube, result);
227 print_str_result(ret, result);
228
229 return ret;
230}
231
232static int64_t
233convertcube_exec(args_t *args)
234{ 206{
235 char result[PRINTCUBE_BUFFER_SIZE]; 207 char result[PRINTCUBE_BUFFER_SIZE];
236 int64_t ret; 208 int64_t ret;
237 209
238 ret = nissy_convertcube( 210 ret = nissy_convert(
239 args->str_format_in, args->str_format_out, args->str_cube, result); 211 args->str_format_in, args->str_format_out, args->str_cube, result);
240 print_str_result(ret, result); 212 print_str_result(ret, result);
241 213
@@ -275,14 +247,17 @@ gendata_exec(args_t *args)
275 247
276 if (tablepaths[i] == NULL) { 248 if (tablepaths[i] == NULL) {
277 fprintf(stderr, "Cannot write data to file\n"); 249 fprintf(stderr, "Cannot write data to file\n");
250 fclose(file);
278 return -2; 251 return -2;
279 } 252 }
280 253
281 size = nissy_datasize(args->str_solver, args->str_options); 254 size = nissy_datasize(args->str_solver, args->str_options);
255
282 if (size < 0) { 256 if (size < 0) {
283 fprintf(stderr, 257 fprintf(stderr,
284 "Unknown error in retrieving data size" 258 "Unknown error in retrieving data size"
285 "(make sure solver is valid)\n"); 259 "(make sure solver is valid)\n");
260 fclose(file);
286 return -3; 261 return -3;
287 } 262 }
288 263
@@ -291,19 +266,23 @@ gendata_exec(args_t *args)
291 ret = nissy_gendata(args->str_solver, args->str_options, buf); 266 ret = nissy_gendata(args->str_solver, args->str_options, buf);
292 if (ret < 0) { 267 if (ret < 0) {
293 fprintf(stderr, "Unknown error in generating data\n"); 268 fprintf(stderr, "Unknown error in generating data\n");
269 fclose(file);
294 free(buf); 270 free(buf);
295 return -4; 271 return -4;
296 } 272 }
297 if (ret != size) { 273 if (ret != size) {
298 fprintf(stderr, "Unknown error: unexpected data size\n"); 274 fprintf(stderr, "Unknown error: unexpected data size "
275 "(got %zu, expected %zu)\n", ret, size);
276 fclose(file);
299 free(buf); 277 free(buf);
300 return -5; 278 return -5;
301 } 279 }
302 280
303 written = fwrite(buf, size, 1, file); 281 written = fwrite(buf, size, 1, file);
282 fclose(file);
304 free(buf); 283 free(buf);
305 284
306 if (written != (int64_t)size) { 285 if (written != 1) {
307 fprintf(stderr, 286 fprintf(stderr,
308 "Error: data was generated correctly, but could not be " 287 "Error: data was generated correctly, but could not be "
309 "written to file (generated %" PRId64 " bytes, written " 288 "written to file (generated %" PRId64 " bytes, written "
@@ -311,7 +290,6 @@ gendata_exec(args_t *args)
311 return -6; 290 return -6;
312 } 291 }
313 292
314 args->datasize = size;
315 fprintf(stderr, "Data written to %s\n", path); 293 fprintf(stderr, "Data written to %s\n", path);
316 294
317 return 0; 295 return 0;
@@ -323,7 +301,7 @@ solve_exec(args_t *args)
323 int i; 301 int i;
324 FILE *file; 302 FILE *file;
325 char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH]; 303 char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH];
326 int64_t ret, gendata_ret; 304 int64_t ret, gendata_ret, size;
327 size_t read; 305 size_t read;
328 306
329 for (i = 0; tablepaths[i] != NULL; i++) { 307 for (i = 0; tablepaths[i] != NULL; i++) {
@@ -344,23 +322,30 @@ solve_exec(args_t *args)
344 } 322 }
345 323
346 /* Ugh, this is not elegant TODO */ 324 /* Ugh, this is not elegant TODO */
347 for (i = 0; tablepaths[i] != NULL; i++) { 325 if (file == NULL) {
348 strcpy(path, tablepaths[i]); 326 for (i = 0; tablepaths[i] != NULL; i++) {
349 strcat(path, args->str_solver); 327 strcpy(path, tablepaths[i]);
350 file = fopen(path, "rb"); 328 strcat(path, args->str_solver);
351 if (file != NULL) 329 file = fopen(path, "rb");
352 break; 330 if (file != NULL)
331 break;
332 }
353 } 333 }
354 334
355 if (tablepaths[i] == NULL) { 335 if (tablepaths[i] == NULL) {
356 fprintf(stderr, "Error: data file not found\n"); 336 fprintf(stderr, "Error: data file not found\n");
337 fclose(file);
357 return -1; 338 return -1;
358 } 339 }
359 340
360 buf = malloc(args->datasize); 341 size = nissy_datasize(args->str_solver, args->str_options);
361 read = fread(buf, args->datasize, 1, file); 342 buf = malloc(size);
362 if (read != args->datasize) { 343 read = fread(buf, size, 1, file);
363 fprintf(stderr, "Error reading data from file\n"); 344 fclose(file);
345 if (read != 1) {
346 fprintf(stderr, "Error reading data from file: "
347 "fread() returned %zu instead of 1 when attempting to"
348 "read %" PRId64 " bytes from file %s\n", read, size, path);
364 return -2; 349 return -2;
365 } 350 }
366 351
@@ -413,7 +398,7 @@ parse_args(int argc, char **argv, args_t *args)
413 options[j].name); 398 options[j].name);
414 return 1; 399 return 1;
415 } 400 }
416 if (!options[j].set(n, argv+i, args)) { 401 if (!options[j].set(n, argv+i+1, args)) {
417 fprintf(stderr, 402 fprintf(stderr,
418 "Error parsing arguments for option %s\n", 403 "Error parsing arguments for option %s\n",
419 options[j].name); 404 options[j].name);
@@ -448,7 +433,8 @@ parse_int64(char *argv, int64_t *result)
448{ 433{
449 *result = strtoll(argv, NULL, 10); 434 *result = strtoll(argv, NULL, 10);
450 435
451 return errno != 0; 436 /* TODO: figure out how errno works and use it */
437 return true;
452} 438}
453 439
454static bool 440static bool
@@ -565,11 +551,22 @@ set_maxsolutions(int argc, char **argv, args_t *args)
565 return parse_int64(argv[0], &args->maxsolutions); 551 return parse_int64(argv[0], &args->maxsolutions);
566} 552}
567 553
554void log_stderr(const char *str, ...)
555{
556 va_list args;
557
558 va_start(args, str);
559 vfprintf(stderr, str, args);
560 va_end(args);
561}
562
568int main(int argc, char **argv) 563int main(int argc, char **argv)
569{ 564{
570 int parse_error; 565 int parse_error;
571 args_t args; 566 args_t args;
572 567
568 nissy_setlogger(log_stderr);
569
573 parse_error = parse_args(argc-1, argv+1, &args); 570 parse_error = parse_args(argc-1, argv+1, &args);
574 if (parse_error) 571 if (parse_error)
575 return parse_error; 572 return parse_error;
diff --git a/src/cube_public.h b/src/cube_public.h
index ea1d28d..a1c4b90 100644
--- a/src/cube_public.h
+++ b/src/cube_public.h
@@ -89,7 +89,7 @@ nissy_frommoves(
89} 89}
90 90
91int64_t 91int64_t
92nissy_convertcube( 92nissy_convert(
93 const char *format_in, 93 const char *format_in,
94 const char *format_out, 94 const char *format_out,
95 const char *cube_string, 95 const char *cube_string,
@@ -155,6 +155,7 @@ nissy_solve(
155{ 155{
156 cube_t c; 156 cube_t c;
157 int64_t ret; 157 int64_t ret;
158 int h;
158 159
159 c = readcube_B32(cube); 160 c = readcube_B32(cube);
160 161
@@ -188,8 +189,12 @@ nissy_solve(
188 return -1; 189 return -1;
189 } 190 }
190 191
191 if (!strcmp(solver, "h48")) { 192 /* TODO define and use solve_options_t */
192 LOG("h48 solver not implemented yet\n"); 193 if (!strcmp(solver, "H48")) {
194 h = atoi(options); /* TODO: better parsing */
195 ret = solve_h48(
196 c, minmoves, maxmoves, maxsolutions,
197 (uint8_t)h, data, solutions);
193 ret = -1; 198 ret = -1;
194 } else if (!strcmp(solver, "simple")) { 199 } else if (!strcmp(solver, "simple")) {
195 ret = solve_simple( 200 ret = solve_simple(
diff --git a/src/solve_generic.h b/src/solve_generic.h
index d1d1469..41d995a 100644
--- a/src/solve_generic.h
+++ b/src/solve_generic.h
@@ -21,7 +21,7 @@ solve_generic_appendsolution(dfsarg_generic_t *arg)
21{ 21{
22 int strl; 22 int strl;
23 23
24 strl = writemoves(arg->moves, arg->depth, *arg->nextsol); 24 strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
25 LOG("Solution found: %s\n", *arg->nextsol); 25 LOG("Solution found: %s\n", *arg->nextsol);
26 *arg->nextsol += strl; 26 *arg->nextsol += strl;
27 **arg->nextsol = '\n'; 27 **arg->nextsol = '\n';
@@ -53,7 +53,6 @@ solve_generic_dfs(dfsarg_generic_t *arg)
53 return 1; 53 return 1;
54 } 54 }
55 55
56 /* memcpy(&nextarg, arg, sizeof(dfsarg_generic_t)); */
57 nextarg = *arg; 56 nextarg = *arg;
58 nextarg.nmoves = arg->nmoves + 1; 57 nextarg.nmoves = arg->nmoves + 1;
59 for (m = 0, ret = 0; m < 18; m++) { 58 for (m = 0, ret = 0; m < 18; m++) {
diff --git a/src/solve_h48.h b/src/solve_h48.h
index 1646f49..201c7c6 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -11,6 +11,8 @@
11#define COCLASS(x) (((x) & COCLASS_MASK) >> UINT32_C(16)) 11#define COCLASS(x) (((x) & COCLASS_MASK) >> UINT32_C(16))
12#define TTREP_MASK (UINT32_C(0xFF) << UINT32_C(8)) 12#define TTREP_MASK (UINT32_C(0xFF) << UINT32_C(8))
13#define TTREP(x) (((x) & TTREP_MASK) >> UINT32_C(8)) 13#define TTREP(x) (((x) & TTREP_MASK) >> UINT32_C(8))
14#define CBOUND_MASK UINT32_C(0xFF)
15#define CBOUND(x) ((x) & CBOUND_MASK)
14#define H48_ESIZE(h) ((_12c4 * _8c4) << (int64_t)(h)) 16#define H48_ESIZE(h) ((_12c4 * _8c4) << (int64_t)(h))
15 17
16#define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8)) 18#define ESEP_IND(i) ((uint32_t)(i) / UINT32_C(8))
@@ -19,6 +21,8 @@
19#define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8)) 21#define VISITED_IND(i) ((uint32_t)(i) / UINT32_C(8))
20#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8))) 22#define VISITED_MASK(i) (UINT32_C(1) << ((uint32_t)(i) % UINT32_C(8)))
21 23
24#define MAX_SOLUTION_LENGTH 20
25
22typedef struct { 26typedef struct {
23 cube_t cube; 27 cube_t cube;
24 uint8_t depth; 28 uint8_t depth;
@@ -39,6 +43,20 @@ typedef struct {
39 cube_t *crep; 43 cube_t *crep;
40} bfsarg_esep_t; 44} bfsarg_esep_t;
41 45
46typedef struct {
47 cube_t cube;
48 cube_t inverse;
49 int8_t nmoves;
50 int8_t depth;
51 uint8_t moves[MAX_SOLUTION_LENGTH];
52 int64_t *nsols;
53 int64_t maxsolutions;
54 uint8_t h;
55 uint32_t *cocsepdata;
56 uint32_t *h48data;
57 char **nextsol;
58} dfsarg_solveh48_t;
59
42_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t); 60_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
43_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t); 61_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t);
44_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); 62_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
@@ -53,6 +71,13 @@ _static_inline void set_visited(uint8_t *, int64_t);
53_static_inline uint8_t get_esep_pval(const uint32_t *, int64_t); 71_static_inline uint8_t get_esep_pval(const uint32_t *, int64_t);
54_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t); 72_static_inline void set_esep_pval(uint32_t *, int64_t, uint8_t);
55 73
74_static void solve_h48_appendsolution(dfsarg_solveh48_t *);
75_static_inline int8_t get_h48_cdata(cube_t, uint32_t *, uint32_t *);
76_static_inline int8_t get_h48_bound(cube_t, uint32_t, uint8_t, uint32_t *);
77_static_inline bool solve_h48_stop(dfsarg_solveh48_t *);
78_static int64_t solve_h48_dfs(dfsarg_solveh48_t *);
79_static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *);
80
56_static_inline int64_t 81_static_inline int64_t
57coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) 82coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
58{ 83{
@@ -238,8 +263,11 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
238 cube_t crep[COCSEP_CLASSES]; 263 cube_t crep[COCSEP_CLASSES];
239 size_t cocsepsize, infosize; 264 size_t cocsepsize, infosize;
240 265
266 /* TODO: move info at start of tables (all tables!) */
241 infosize = 4 * maxdepth; 267 infosize = 4 * maxdepth;
242 cocsepsize = gendata_cocsep(buf, selfsim, crep); 268 cocsepsize = gendata_cocsep(buf, selfsim, crep);
269 infosize = 88;
270
243 if (buf == NULL) 271 if (buf == NULL)
244 goto gendata_h48_return_size; 272 goto gendata_h48_return_size;
245 273
@@ -272,7 +300,6 @@ gendata_h48(void *buf, uint8_t h, uint8_t maxdepth)
272 } 300 }
273 301
274 info[0] = arg.depth-1; 302 info[0] = arg.depth-1;
275 infosize = 4 * (size_t)(info[0] + 2);
276 303
277 LOG("h48 pruning table computed\n"); 304 LOG("h48 pruning table computed\n");
278 LOG("Maximum pruning value: %" PRIu32 "\n", info[0]); 305 LOG("Maximum pruning value: %" PRIu32 "\n", info[0]);
@@ -353,3 +380,148 @@ set_esep_pval(uint32_t *buf32, int64_t i, uint8_t val)
353 buf32[ESEP_IND(i)] = 380 buf32[ESEP_IND(i)] =
354 (buf32[ESEP_IND(i)] & (~ESEP_MASK(i))) | (val << ESEP_SHIFT(i)); 381 (buf32[ESEP_IND(i)] & (~ESEP_MASK(i))) | (val << ESEP_SHIFT(i));
355} 382}
383
384_static void
385solve_h48_appendsolution(dfsarg_solveh48_t *arg)
386{
387 int strl;
388
389 strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol);
390 LOG("Solution found: %s\n", *arg->nextsol);
391 *arg->nextsol += strl;
392 **arg->nextsol = '\n';
393 (*arg->nextsol)++;
394 (*arg->nsols)++;
395}
396
397_static_inline int8_t
398get_h48_cdata(cube_t cube, uint32_t *cocsepdata, uint32_t *cdata)
399{
400 int64_t coord;
401
402 coord = coord_cocsep(cube);
403 *cdata = cocsepdata[coord];
404
405 return CBOUND(*cdata);
406}
407
408_static_inline int8_t
409get_h48_bound(cube_t cube, uint32_t cdata, uint8_t h, uint32_t *h48data)
410{
411 int64_t coord;
412
413 coord = coord_h48_edges(cube, COCLASS(cdata), TTREP(cdata), h);
414 return get_esep_pval(h48data, coord);
415}
416
417_static_inline bool
418solve_h48_stop(dfsarg_solveh48_t *arg)
419{
420 uint32_t data, data_inv;
421 int8_t bound;
422
423 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &data);
424 if (bound + arg->nmoves > arg->depth)
425 return true;
426
427 bound = get_h48_cdata(arg->inverse, arg->cocsepdata, &data_inv);
428 if (bound + arg->nmoves > arg->depth)
429 return true;
430
431/*
432 bound = get_h48_bound(arg->cube, data, arg->h, arg->h48data);
433LOG("Using pval %" PRId8 "\n", bound);
434 if (bound + arg->nmoves > arg->depth)
435 return true;
436
437 bound = get_h48_bound(arg->inverse, data_inv, arg->h, arg->h48data);
438 if (bound + arg->nmoves > arg->depth)
439 return true;
440*/
441
442 return false;
443}
444
445_static int64_t
446solve_h48_dfs(dfsarg_solveh48_t *arg)
447{
448 dfsarg_solveh48_t nextarg;
449 int64_t ret;
450 uint8_t m;
451
452 if (*arg->nsols == arg->maxsolutions)
453 return 0;
454
455 if (solve_h48_stop(arg))
456 return 0;
457
458 if (issolved(arg->cube)) {
459 if (arg->nmoves != arg->depth)
460 return 0;
461 solve_h48_appendsolution(arg);
462 return 1;
463 }
464
465 /* TODO: avoid copy, change arg and undo changes after recursion */
466 nextarg = *arg;
467 nextarg.nmoves = arg->nmoves + 1;
468 ret = 0;
469 for (m = 0; m < 18; m++) {
470 nextarg.moves[arg->nmoves] = m;
471 if (!allowednextmove(nextarg.moves, nextarg.nmoves)) {
472 /* If a move is not allowed, neither are its 180
473 * and 270 degree variations */
474 m += 2;
475 continue;
476 }
477 nextarg.cube = move(arg->cube, m);
478 nextarg.inverse = inverse(nextarg.cube); /* TODO: use premove */
479 ret += solve_h48_dfs(&nextarg);
480 }
481
482 return ret;
483}
484
485_static int64_t
486solve_h48(
487 cube_t cube,
488 int8_t minmoves,
489 int8_t maxmoves,
490 int8_t maxsolutions,
491 uint8_t h,
492 const void *data,
493 char *solutions
494)
495{
496 int64_t nsols;
497 dfsarg_solveh48_t arg;
498
499 arg = (dfsarg_solveh48_t) {
500 .cube = cube,
501 .inverse = inverse(cube),
502 .nsols = &nsols,
503 .maxsolutions = maxsolutions,
504 .h = h,
505 .cocsepdata = (uint32_t *)data,
506 .h48data = ((uint32_t *)data) + COCSEP_FULLSIZE / 4,
507 .nextsol = &solutions
508 };
509
510 nsols = 0;
511 for (arg.depth = minmoves;
512 arg.depth <= maxmoves && nsols < maxsolutions;
513 arg.depth++)
514 {
515 LOG("Found %" PRId64 " solutions, searching at depth %"
516 PRId8 "\n", nsols, arg.depth);
517 arg.nmoves = 0;
518 solve_h48_dfs(&arg);
519 }
520
521/*
522for (int64_t i = 0; i < 4; i++)
523LOG("Data for coord = %" PRId64 ": %" PRIu8 "\n",
524i, get_esep_pval(arg.h48data, i));
525*/
526 return nsols;
527}
diff --git a/test/103_gendata_h48/00_h_0.out b/test/103_gendata_h48/00_h_0.out
index db6e121..cc5cf9b 100644
--- a/test/103_gendata_h48/00_h_0.out
+++ b/test/103_gendata_h48/00_h_0.out
@@ -1,4 +1,4 @@
159903545 159903605
2 2
3cocsepdata: 3cocsepdata:
4Classes: 3393 4Classes: 3393
diff --git a/test/103_gendata_h48/01_h_1.out b/test/103_gendata_h48/01_h_1.out
index 456305d..bd0931c 100644
--- a/test/103_gendata_h48/01_h_1.out
+++ b/test/103_gendata_h48/01_h_1.out
@@ -1,4 +1,4 @@
1118687270 1118687330
2 2
3cocsepdata: 3cocsepdata:
4Classes: 3393 4Classes: 3393

Generated with cgit - Back to sebastiano.tronto.net