aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.txt28
-rw-r--r--shell.c32
-rw-r--r--src/cube.h6
-rw-r--r--src/cube_public.h16
-rw-r--r--src/solve_h48.h111
-rw-r--r--tools/stats_tables_h48/stats_tables_h48.c69
6 files changed, 255 insertions, 7 deletions
diff --git a/TODO.txt b/TODO.txt
index 6f212c3..86c48fd 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,7 +1,29 @@
1Check stats for all tables using H48stats solver
2 - implement gencube
3 - move cubefromarray from cube_io to where needed
4 - implement in cube_generic
5 - fix in cube_public
6 - add tests
7 - test shell
8 - optional: dr states (just to check options)
9 - implement tool for stats
10 - output to file, only write cocsep to stdout
11
12Bug in esep table generation
13 - Fails for UFRUFU, try command
14 ./run solve -solver H48 -options "2;20" -n 1 -M 10 -cube \
15 "$(./run frommoves -moves "UFRUFU")"
16 - Fundamental error in how tables are generated, each coordinate has too
17 many representative. I need to use the big table with the full coordinate
18 first (h=11, ~241 billion positions, 60Gb with k=2). From this the smaller
19 tables can be easily deduced.
20 - Investigate the possibility of computing smaller tables directly in some
21 other way, even if slow.
22 - use dfs for computing big table, save distance %3 until the last two steps,
23 then clean the table and double loop over moves to fill the value
24
1Solver 25Solver
2 - fix and cleanup current implementation 26 - cleanup h48 solver
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 27 - do not copy dfsarg, change and undo
6 - implement and use premove (and test) instead of inverting 28 - implement and use premove (and test) instead of inverting
7 - benchmark for solve 29 - benchmark for solve
diff --git a/shell.c b/shell.c
index 5cd8fb2..03618de 100644
--- a/shell.c
+++ b/shell.c
@@ -29,6 +29,7 @@ typedef struct {
29 int8_t maxmoves; 29 int8_t maxmoves;
30 int8_t optimal; 30 int8_t optimal;
31 int64_t maxsolutions; 31 int64_t maxsolutions;
32 uint8_t id[16];
32} args_t; 33} args_t;
33 34
34static void print_cube_result(int64_t, char [static 22]); 35static void print_cube_result(int64_t, char [static 22]);
@@ -40,6 +41,7 @@ static int64_t applymoves_exec(args_t *);
40static int64_t applytrans_exec(args_t *); 41static int64_t applytrans_exec(args_t *);
41static int64_t frommoves_exec(args_t *); 42static int64_t frommoves_exec(args_t *);
42static int64_t convert_exec(args_t *); 43static int64_t convert_exec(args_t *);
44static int64_t gencube_exec(args_t *);
43static int64_t datasize_exec(args_t *); 45static int64_t datasize_exec(args_t *);
44static int64_t gendata_exec(args_t *); 46static int64_t gendata_exec(args_t *);
45static int64_t solve_exec(args_t *); 47static int64_t solve_exec(args_t *);
@@ -63,6 +65,7 @@ static bool set_minmoves(int, char **, args_t *);
63static bool set_maxmoves(int, char **, args_t *); 65static bool set_maxmoves(int, char **, args_t *);
64static bool set_optimal(int, char **, args_t *); 66static bool set_optimal(int, char **, args_t *);
65static bool set_maxsolutions(int, char **, args_t *); 67static bool set_maxsolutions(int, char **, args_t *);
68static bool set_id(int, char **, args_t *);
66 69
67#define COMMAND(N, E) { .name = N, .exec = E } 70#define COMMAND(N, E) { .name = N, .exec = E }
68struct { 71struct {
@@ -75,6 +78,7 @@ struct {
75 COMMAND("applytrans", applytrans_exec), 78 COMMAND("applytrans", applytrans_exec),
76 COMMAND("frommoves", frommoves_exec), 79 COMMAND("frommoves", frommoves_exec),
77 COMMAND("convert", convert_exec), 80 COMMAND("convert", convert_exec),
81 COMMAND("gencube", gencube_exec),
78 COMMAND("datasize", datasize_exec), 82 COMMAND("datasize", datasize_exec),
79 COMMAND("gendata", gendata_exec), 83 COMMAND("gendata", gendata_exec),
80 COMMAND("solve", solve_exec), 84 COMMAND("solve", solve_exec),
@@ -102,6 +106,7 @@ struct {
102 OPTION("-M", 1, set_maxmoves), 106 OPTION("-M", 1, set_maxmoves),
103 OPTION("-O", 1, set_optimal), 107 OPTION("-O", 1, set_optimal),
104 OPTION("-n", 1, set_maxsolutions), 108 OPTION("-n", 1, set_maxsolutions),
109 OPTION("-id", 16, set_id),
105 OPTION(NULL, 0, NULL) 110 OPTION(NULL, 0, NULL)
106}; 111};
107 112
@@ -215,6 +220,18 @@ convert_exec(args_t *args)
215} 220}
216 221
217static int64_t 222static int64_t
223gencube_exec(args_t *args)
224{
225 char result[PRINTCUBE_BUFFER_SIZE];
226 int64_t ret;
227
228 ret = nissy_gencube(args->id, args->str_options, result);
229 print_str_result(ret, result);
230
231 return ret;
232}
233
234static int64_t
218datasize_exec(args_t *args) 235datasize_exec(args_t *args)
219{ 236{
220 int64_t ret; 237 int64_t ret;
@@ -551,6 +568,21 @@ set_maxsolutions(int argc, char **argv, args_t *args)
551 return parse_int64(argv[0], &args->maxsolutions); 568 return parse_int64(argv[0], &args->maxsolutions);
552} 569}
553 570
571static bool
572set_id(int argc, char **argv, args_t *args)
573{
574 int i;
575 int64_t n;
576
577 for (i = 0; i < 16; i++) {
578 if (!parse_int64(argv[i], &n))
579 return false;
580 args->id[i] = (uint8_t)n;
581 }
582
583 return true;
584}
585
554void log_stderr(const char *str, ...) 586void log_stderr(const char *str, ...)
555{ 587{
556 va_list args; 588 va_list args;
diff --git a/src/cube.h b/src/cube.h
index b5eb615..d3d096a 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -41,6 +41,12 @@ int64_t nissy_convert(
41 char *result 41 char *result
42); 42);
43 43
44int64_t nissy_gencube(
45 uint8_t id[16],
46 const char *options,
47 char result[static 22]
48);
49
44/* 50/*
45Returns the size of the data generated by nissy_gendata, when called with 51Returns the size of the data generated by nissy_gendata, when called with
46the same parameters, or -1 in case of error. The returned value can be 52the same parameters, or -1 in case of error. The returned value can be
diff --git a/src/cube_public.h b/src/cube_public.h
index a1c4b90..fe003c9 100644
--- a/src/cube_public.h
+++ b/src/cube_public.h
@@ -105,6 +105,18 @@ nissy_convert(
105} 105}
106 106
107int64_t 107int64_t
108nissy_gencube(
109 uint8_t id[16],
110 const char *options,
111 char result[static 22]
112)
113{
114 /* TODO: compute cube from id % (number of positions) */
115 /* options can be used for generating e.g. DR-state cube */
116 return -1;
117}
118
119int64_t
108nissy_datasize( 120nissy_datasize(
109 const char *solver, 121 const char *solver,
110 const char *options 122 const char *options
@@ -131,6 +143,8 @@ nissy_gendata(
131 h = atoi(options); 143 h = atoi(options);
132 maxdepth = atoi(&options[i+1]); 144 maxdepth = atoi(&options[i+1]);
133 ret = gendata_h48(data, h, maxdepth); 145 ret = gendata_h48(data, h, maxdepth);
146 } else if (!strcmp(solver, "H48stats")) {
147 ret = gendata_cocsep(data, NULL, NULL);
134 } else { 148 } else {
135 LOG("gendata: implemented only for H48 solver\n"); 149 LOG("gendata: implemented only for H48 solver\n");
136 ret = -1; 150 ret = -1;
@@ -196,6 +210,8 @@ nissy_solve(
196 c, minmoves, maxmoves, maxsolutions, 210 c, minmoves, maxmoves, maxsolutions,
197 (uint8_t)h, data, solutions); 211 (uint8_t)h, data, solutions);
198 ret = -1; 212 ret = -1;
213 } else if (!strcmp(solver, "H48stats")) {
214 ret = solve_h48stats(c, maxmoves, data, solutions);
199 } else if (!strcmp(solver, "simple")) { 215 } else if (!strcmp(solver, "simple")) {
200 ret = solve_simple( 216 ret = solve_simple(
201 c, minmoves, maxmoves, maxsolutions, optimal, solutions); 217 c, minmoves, maxmoves, maxsolutions, optimal, solutions);
diff --git a/src/solve_h48.h b/src/solve_h48.h
index 201c7c6..c2c541d 100644
--- a/src/solve_h48.h
+++ b/src/solve_h48.h
@@ -57,6 +57,15 @@ typedef struct {
57 char **nextsol; 57 char **nextsol;
58} dfsarg_solveh48_t; 58} dfsarg_solveh48_t;
59 59
60typedef struct {
61 cube_t cube;
62 int8_t nmoves;
63 int8_t depth;
64 uint8_t moves[MAX_SOLUTION_LENGTH];
65 uint32_t *cocsepdata;
66 char *s;
67} dfsarg_solveh48stats_t;
68
60_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t); 69_static_inline int64_t coord_h48(cube_t, const uint32_t *, uint8_t);
61_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t); 70_static_inline int64_t coord_h48_edges(cube_t, int64_t, uint8_t, uint8_t);
62_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t); 71_static_inline cube_t invcoord_h48(int64_t, const cube_t *, uint8_t);
@@ -78,6 +87,9 @@ _static_inline bool solve_h48_stop(dfsarg_solveh48_t *);
78_static int64_t solve_h48_dfs(dfsarg_solveh48_t *); 87_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 *); 88_static int64_t solve_h48(cube_t, int8_t, int8_t, int8_t, uint8_t, const void *, char *);
80 89
90_static int64_t solve_h48stats_dfs(dfsarg_solveh48stats_t *);
91_static int64_t solve_h48stats(cube_t, int8_t, const void *, char [static 13]);
92
81_static_inline int64_t 93_static_inline int64_t
82coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h) 94coord_h48(cube_t c, const uint32_t *cocsepdata, uint8_t h)
83{ 95{
@@ -104,9 +116,15 @@ coord_h48_edges(cube_t c, int64_t coclass, uint8_t t, uint8_t h)
104 d = transform_edges(c, t); 116 d = transform_edges(c, t);
105 esep = coord_esep(d); 117 esep = coord_esep(d);
106 eo = coord_eo(d); 118 eo = coord_eo(d);
107 edges = (esep << (int64_t)h) + (eo >> (11 - (int64_t)h)); 119 edges = (esep << 11) + eo;
120
121 return (coclass * H48_ESIZE(11) + edges) >> (11 - (int64_t)h);
108 122
123/*
124TODO: decide which alternative is better, if above or below
125 edges = (esep << (int64_t)h) + (eo >> (11 - (int64_t)h));
109 return coclass * H48_ESIZE(h) + edges; 126 return coclass * H48_ESIZE(h) + edges;
127*/
110} 128}
111 129
112/* 130/*
@@ -160,7 +178,8 @@ gendata_cocsep(void *buf, uint64_t *selfsim, cube_t *rep)
160 buf32 = (uint32_t *)buf; 178 buf32 = (uint32_t *)buf;
161 info = buf32 + COCSEP_TABLESIZE; 179 info = buf32 + COCSEP_TABLESIZE;
162 memset(buf32, 0xFF, sizeof(uint32_t) * COCSEP_TABLESIZE); 180 memset(buf32, 0xFF, sizeof(uint32_t) * COCSEP_TABLESIZE);
163 memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES); 181 if (selfsim != NULL)
182 memset(selfsim, 0, sizeof(uint64_t) * COCSEP_CLASSES);
164 183
165 arg = (dfsarg_cocsep_t) { 184 arg = (dfsarg_cocsep_t) {
166 .cube = solved, 185 .cube = solved,
@@ -221,7 +240,8 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
221 d = transform_corners(arg->cube, t); 240 d = transform_corners(arg->cube, t);
222 j = coord_cocsep(d); 241 j = coord_cocsep(d);
223 is = (i == j); 242 is = (i == j);
224 arg->selfsim[*arg->n] |= is << t; 243 if (arg->selfsim != NULL)
244 arg->selfsim[*arg->n] |= is << t;
225 set_visited(arg->visited, j); 245 set_visited(arg->visited, j);
226 tinv = inverse_trans(t); 246 tinv = inverse_trans(t);
227 olddepth = (uint8_t)(arg->buf32[j] & 0xFF); 247 olddepth = (uint8_t)(arg->buf32[j] & 0xFF);
@@ -232,7 +252,8 @@ gendata_cocsep_dfs(dfsarg_cocsep_t *arg)
232 depth = (uint32_t)arg->depth; 252 depth = (uint32_t)arg->depth;
233 arg->buf32[j] = class | ttrep | depth; 253 arg->buf32[j] = class | ttrep | depth;
234 } 254 }
235 arg->rep[*arg->n] = arg->cube; 255 if (arg->rep != NULL)
256 arg->rep[*arg->n] = arg->cube;
236 (*arg->n)++; 257 (*arg->n)++;
237 258
238 return cc; 259 return cc;
@@ -525,3 +546,85 @@ i, get_esep_pval(arg.h48data, i));
525*/ 546*/
526 return nsols; 547 return nsols;
527} 548}
549
550/*
551The h48stats solver computes how many moves it takes to solve to each of
552the 13 h48 coordinates: the corner-only coordinate, and 12 cocsep+esep
553coordinates with h from 0 to 11. The solutions array is filled with
554the length of the solutions: solutions[0] contains the value for the
555corner-only coordinate, and for i>0 solutions[i] contains the value for
556the cocsep+esep coordinate with h=i-1. The solution array is therefore
557not a printable string.
558*/
559_static int64_t
560solve_h48stats_dfs(dfsarg_solveh48stats_t *arg)
561{
562 int8_t bound, u;
563 uint8_t m;
564 uint32_t d;
565 int64_t coord, h;
566 dfsarg_solveh48stats_t nextarg;
567
568 bound = get_h48_cdata(arg->cube, arg->cocsepdata, &d);
569 if (bound + arg->nmoves > arg->depth)
570 return 0;
571
572 u = COCLASS(d) == 0 && arg->s[0] == 99;
573 arg->s[0] = u * arg->nmoves + (1-u) * arg->s[0];
574
575 coord = coord_h48_edges(arg->cube, COCLASS(d), TTREP(d), 11);
576 for (h = 0; h <= 11; h++) {
577 u = coord >> (11-h) == 0 && arg->s[h+1] == 99;
578 arg->s[h+1] = u * arg->nmoves + (1-u) * arg->s[h+1];
579 }
580
581 if (arg->s[12] != 99)
582 return 0;
583
584 nextarg = *arg;
585 nextarg.nmoves = arg->nmoves + 1;
586 for (m = 0; m < 18; m++) {
587 nextarg.moves[arg->nmoves] = m;
588 if (!allowednextmove(nextarg.moves, nextarg.nmoves)) {
589 /* If a move is not allowed, neither are its 180
590 * and 270 degree variations */
591 m += 2;
592 continue;
593 }
594 nextarg.cube = move(arg->cube, m);
595 solve_h48stats_dfs(&nextarg);
596 }
597
598 return 0;
599}
600
601_static int64_t
602solve_h48stats(
603 cube_t cube,
604 int8_t maxmoves,
605 const void *data,
606 char solutions[static 13]
607)
608{
609 int i;
610 dfsarg_solveh48stats_t arg;
611
612 arg = (dfsarg_solveh48stats_t) {
613 .cube = cube,
614 .cocsepdata = (uint32_t *)data,
615 .s = solutions
616 };
617
618 for (i = 0; i < 13; i++)
619 solutions[i] = (char)99;
620
621 for (arg.depth = 0;
622 arg.depth <= maxmoves && solutions[12] == 99;
623 arg.depth++)
624 {
625 arg.nmoves = 0;
626 solve_h48stats_dfs(&arg);
627 }
628
629 return 0;
630}
diff --git a/tools/stats_tables_h48/stats_tables_h48.c b/tools/stats_tables_h48/stats_tables_h48.c
new file mode 100644
index 0000000..9f9bacf
--- /dev/null
+++ b/tools/stats_tables_h48/stats_tables_h48.c
@@ -0,0 +1,69 @@
1#include <time.h>
2#include "../timerun.h"
3#include "../../src/cube.h"
4
5#define MAXMOVES 20
6#define NCUBES 1000
7
8typedef struct { uint8_t n[16]; } i128;
9
10char *buf;
11
12i128 rand128(void) {
13 uint8_t i, j;
14 i128 ret = {0};
15
16 for (i = 0; i < 16; i++)
17 for (j = 0; j < 8; j++)
18 ret.n[i] |= (uint8_t)(rand() % 2) << j;
19
20 return ret;
21}
22
23void output(int64_t v[13][100]) {
24/* TODO: write to file and output only cocsepdata table stats */
25}
26
27void run(void) {
28 uint32_t *h48info;
29 int i, j;
30 char sols[13], cube[22];
31 int64_t s, v[13][100] = {0};
32
33 s = nissy_gendata("H48stats", "", buf);
34
35 if (s == -1) {
36 printf("Error generating table\n");
37 return;
38 }
39
40 for (i = 0; i < NCUBES; i++) {
41 nissy_gencube(rand128(), "", cube);
42 nissy_solve(cube, "H48stats",
43 "", "", "", 0, MAXMOVES, 1, -1, buf, sols);
44 for (j = 0; j < 13; j++)
45 v[j][(int)sols[j]]++;
46 }
47
48 output(v);
49}
50
51int main() {
52 int64_t size;
53
54 srand(time(NULL));
55
56 size = nissy_datasize("H48", OPTIONS);
57 if (size == -1) {
58 printf("h48 stats: error in datasize\n");
59 return 1;
60 }
61
62 buf = malloc(size);
63
64 timerun(run, "h48 table stats");
65
66 free(buf);
67
68 return 0;
69}

Generated with cgit - Back to sebastiano.tronto.net