aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-03-25 14:09:14 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2025-03-25 14:09:14 +0100
commit9154476ba6bf400c1eb379f0a3aa6caae2d06d4d (patch)
tree73bfb47ccb6cb31a7c91f9917b37a517f2146c24
parentcc2dacd43eb7f5ed3a2917612b9a2a9232a61e59 (diff)
downloadnissy-core-9154476ba6bf400c1eb379f0a3aa6caae2d06d4d.tar.gz
nissy-core-9154476ba6bf400c1eb379f0a3aa6caae2d06d4d.zip
Added NISS to coord solver
-rw-r--r--shell/shell.c40
-rw-r--r--src/core/moves.h4
-rw-r--r--src/solvers/coord/common.h88
-rw-r--r--src/solvers/coord/coord.h4
-rw-r--r--src/solvers/coord/eo.h2
-rw-r--r--src/solvers/coord/list.h4
-rw-r--r--src/solvers/coord/solve.h199
-rw-r--r--src/solvers/coord/types_macros.h2
-rw-r--r--src/solvers/coord/utils.h68
9 files changed, 308 insertions, 103 deletions
diff --git a/shell/shell.c b/shell/shell.c
index 0387856..1b66f19 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -73,7 +73,8 @@ static int64_t countmoves_exec(args_t *);
73static int64_t help_exec(args_t *); 73static int64_t help_exec(args_t *);
74 74
75static int parse_args(int, char **, args_t *); 75static int parse_args(int, char **, args_t *);
76static bool parse_uint(char *, unsigned *); 76static bool parse_uint(const char *, unsigned *);
77static uint8_t parse_nisstype(const char *);
77 78
78static bool set_cube(int, char **, args_t *); 79static bool set_cube(int, char **, args_t *);
79static bool set_cube_perm(int, char **, args_t *); 80static bool set_cube_perm(int, char **, args_t *);
@@ -111,7 +112,7 @@ struct {
111 OPTION(FLAG_MOVES, 1, set_str_moves), 112 OPTION(FLAG_MOVES, 1, set_str_moves),
112 OPTION(FLAG_TRANS, 1, set_str_trans), 113 OPTION(FLAG_TRANS, 1, set_str_trans),
113 OPTION(FLAG_SOLVER, 1, set_str_solver), 114 OPTION(FLAG_SOLVER, 1, set_str_solver),
114 OPTION(FLAG_NISSTYPE, 1, set_str_nisstype), /* TODO: more args ? */ 115 OPTION(FLAG_NISSTYPE, 1, set_str_nisstype),
115 OPTION(FLAG_MINMOVES, 1, set_minmoves), 116 OPTION(FLAG_MINMOVES, 1, set_minmoves),
116 OPTION(FLAG_MAXMOVES, 1, set_maxmoves), 117 OPTION(FLAG_MAXMOVES, 1, set_maxmoves),
117 OPTION(FLAG_OPTIMAL, 1, set_optimal), 118 OPTION(FLAG_OPTIMAL, 1, set_optimal),
@@ -431,12 +432,18 @@ solve_exec(args_t *args)
431 int64_t ret, gendata_ret, size; 432 int64_t ret, gendata_ret, size;
432 size_t read; 433 size_t read;
433 434
434 nissflag = NISSY_NISSFLAG_NORMAL; /* TODO: parse str_nisstype */ 435 nissflag = parse_nisstype(args->str_nisstype);
436 if (nissflag == UINT8_MAX) {
437 fprintf(stderr, "solve: unknown niss type '%s', use one "
438 "of the following:\nnormal\ninverse\nlinear\nmixed\nall",
439 args->str_nisstype);
440 return -1;
441 }
435 442
436 size = nissy_solverinfo(args->str_solver, dataid); 443 size = nissy_solverinfo(args->str_solver, dataid);
437 444
438 if (size < 0) { 445 if (size < 0) {
439 fprintf(stderr, "solve: unknown solver %s\n", 446 fprintf(stderr, "solve: unknown solver '%s'\n",
440 args->str_solver); 447 args->str_solver);
441 return size; 448 return size;
442 } 449 }
@@ -622,8 +629,8 @@ parse_args(int argc, char **argv, args_t *args)
622 return 0; 629 return 0;
623} 630}
624 631
625bool 632static bool
626parse_uint(char *argv, unsigned *result) 633parse_uint(const char *argv, unsigned *result)
627{ 634{
628 *result = strtol(argv, NULL, 10); 635 *result = strtol(argv, NULL, 10);
629 636
@@ -631,6 +638,27 @@ parse_uint(char *argv, unsigned *result)
631 return true; 638 return true;
632} 639}
633 640
641static uint8_t
642parse_nisstype(const char *arg)
643{
644 if (!strcmp("normal", arg))
645 return NISSY_NISSFLAG_NORMAL;
646
647 if (!strcmp("inverse", arg))
648 return NISSY_NISSFLAG_INVERSE;
649
650 if (!strcmp("linear", arg))
651 return NISSY_NISSFLAG_LINEAR;
652
653 if (!strcmp("mixed", arg))
654 return NISSY_NISSFLAG_MIXED;
655
656 if (!strcmp("all", arg))
657 return NISSY_NISSFLAG_ALL;
658
659 return UINT8_MAX;
660}
661
634static bool 662static bool
635set_cube(int argc, char **argv, args_t *args) 663set_cube(int argc, char **argv, args_t *args)
636{ 664{
diff --git a/src/core/moves.h b/src/core/moves.h
index e56d5c8..11ac34e 100644
--- a/src/core/moves.h
+++ b/src/core/moves.h
@@ -15,7 +15,7 @@ STATIC cube_t move(cube_t, uint8_t);
15STATIC cube_t premove(cube_t, uint8_t); 15STATIC cube_t premove(cube_t, uint8_t);
16STATIC uint8_t inverse_move(uint8_t); 16STATIC uint8_t inverse_move(uint8_t);
17STATIC void sortparallel_moves(size_t n, uint8_t [n]); 17STATIC void sortparallel_moves(size_t n, uint8_t [n]);
18STATIC bool are_lastmoves_singlecw(size_t n, uint8_t [n]); 18STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]);
19 19
20STATIC cube_t applymoves(cube_t, const char *); 20STATIC cube_t applymoves(cube_t, const char *);
21 21
@@ -236,7 +236,7 @@ sortparallel_moves(size_t n, uint8_t moves[n])
236} 236}
237 237
238STATIC bool 238STATIC bool
239are_lastmoves_singlecw(size_t n, uint8_t moves[n]) 239are_lastmoves_singlecw(size_t n, const uint8_t moves[n])
240{ 240{
241 bool two; 241 bool two;
242 242
diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h
index 8553658..4cfc36f 100644
--- a/src/solvers/coord/common.h
+++ b/src/solvers/coord/common.h
@@ -1,13 +1,7 @@
1coord_t *all_coordinates[] = {
2 &coordinate_eo,
3 NULL
4};
5
6STATIC void append_coord_name(const coord_t *, char *); 1STATIC void append_coord_name(const coord_t *, char *);
7STATIC coord_t *parse_coord(size_t n, const char [n]); 2STATIC bool solution_lastqt_cw(const solution_moves_t [static 1]);
8STATIC uint8_t parse_axis(size_t n, const char [n]); 3STATIC bool coord_can_switch(
9STATIC void parse_coord_and_axis(size_t n, const char [n], coord_t **, uint8_t *); 4 const coord_t [static 1], const void *, size_t n, const uint8_t [n]);
10STATIC int64_t dataid_coord(const char *, char [static NISSY_DATAID_SIZE]);
11 5
12STATIC void 6STATIC void
13append_coord_name(const coord_t *coord, char *str) 7append_coord_name(const coord_t *coord, char *str)
@@ -21,66 +15,40 @@ append_coord_name(const coord_t *coord, char *str)
21 str[j] = '\0'; 15 str[j] = '\0';
22} 16}
23 17
24STATIC coord_t * 18STATIC bool
25parse_coord(size_t n, const char coord[n]) 19solution_lastqt_cw(const solution_moves_t s[static 1])
26{ 20{
27 int i; 21 return are_lastmoves_singlecw(s->nmoves, s->moves) &&
28 22 are_lastmoves_singlecw(s->npremoves, s->premoves);
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(size_t n, const char axis[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} 23}
49 24
50STATIC void 25STATIC bool
51parse_coord_and_axis( 26coord_can_switch(
27 const coord_t coord[static 1],
28 const void *data,
52 size_t n, 29 size_t n,
53 const char str[n], 30 const uint8_t moves[n]
54 coord_t **coord,
55 uint8_t *axis
56) 31)
57{ 32{
58 size_t i; 33 /*
59 34 This function checks that the last move (or two moves, if parallel)
60 for (i = 0; i < n; i++) 35 have a non-trivial effect on the coordinate of the solved cube. This
61 if (str[i] == '_') 36 works in general for all coordinates that have been used so far, but
62 break; 37 in more general cases that have not been considered yet it may fail.
63 38 */
64 if (coord != NULL)
65 *coord = parse_coord(i, str);
66 39
67 if (axis != NULL) 40 uint64_t i;
68 *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, str+i+1);
69}
70
71STATIC int64_t
72dataid_coord(const char *ca, char dataid[static NISSY_DATAID_SIZE])
73{
74 coord_t *c;
75 41
76 parse_coord_and_axis(strlen(ca), ca, &c, NULL); 42 if (n == 0)
43 return true;
77 44
78 if (c == NULL) { 45 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data);
79 LOG("dataid_coord: cannot parse coordinate from '%s'\n", ca); 46 if (i == 0)
80 return NISSY_ERROR_INVALID_SOLVER; 47 return false;
81 }
82 48
83 strcpy(dataid, c->name); 49 if (n == 1 || !parallel(moves[n-1], moves[n-2]))
50 return true;
84 51
85 return NISSY_OK; 52 i = coord->coord(move(SOLVED_CUBE, moves[n-1]), data);
53 return i != 0;
86} 54}
diff --git a/src/solvers/coord/coord.h b/src/solvers/coord/coord.h
index 6ca68c5..f42739d 100644
--- a/src/solvers/coord/coord.h
+++ b/src/solvers/coord/coord.h
@@ -1,5 +1,7 @@
1#include "types_macros.h" 1#include "types_macros.h"
2#include "eo.h"
3#include "common.h" 2#include "common.h"
3#include "eo.h"
4#include "list.h"
5#include "utils.h"
4#include "gendata.h" 6#include "gendata.h"
5#include "solve.h" 7#include "solve.h"
diff --git a/src/solvers/coord/eo.h b/src/solvers/coord/eo.h
index 46a6f70..ef9b27a 100644
--- a/src/solvers/coord/eo.h
+++ b/src/solvers/coord/eo.h
@@ -15,7 +15,7 @@ STATIC coord_t coordinate_eo = {
15 [AXIS_RL] = TRANS_URr, 15 [AXIS_RL] = TRANS_URr,
16 [AXIS_FB] = TRANS_UFr, 16 [AXIS_FB] = TRANS_UFr,
17 }, 17 },
18 .is_admissible = &are_lastmoves_singlecw, 18 .is_admissible = &solution_lastqt_cw,
19}; 19};
20 20
21STATIC uint64_t 21STATIC uint64_t
diff --git a/src/solvers/coord/list.h b/src/solvers/coord/list.h
new file mode 100644
index 0000000..32c94a4
--- /dev/null
+++ b/src/solvers/coord/list.h
@@ -0,0 +1,4 @@
1coord_t *all_coordinates[] = {
2 &coordinate_eo,
3 NULL
4};
diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h
index c056adc..c3fbd02 100644
--- a/src/solvers/coord/solve.h
+++ b/src/solvers/coord/solve.h
@@ -1,66 +1,191 @@
1typedef struct { 1typedef struct {
2 cube_t cube; 2 cube_t cube;
3 cube_t inverse;
3 uint8_t target_depth; 4 uint8_t target_depth;
4 solution_moves_t *solution_moves; 5 solution_moves_t *solution_moves;
5 solution_settings_t *solution_settings; 6 solution_settings_t *solution_settings;
7 solution_list_t *solution_list;
8 uint8_t nissflag;
9 bool lastisnormal;
6 coord_t *coord; 10 coord_t *coord;
7 const void *coord_data; 11 const void *coord_data;
8 const uint8_t *ptable; 12 const uint8_t *ptable;
9 solution_list_t *solution_list;
10} dfsarg_solve_coord_t; 13} dfsarg_solve_coord_t;
11 14
12STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t, 15STATIC int64_t solve_coord(cube_t, coord_t [static 1], uint8_t, uint8_t,
13 uint8_t, uint64_t, int8_t, int, uint64_t, const void *, size_t, char *); 16 uint8_t, uint8_t, uint64_t, int8_t, int, uint64_t, const void *,
17 size_t n, char [n]);
14STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t, 18STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t,
15 uint8_t, uint64_t, int8_t, int, uint64_t, const void *, size_t, char *); 19 uint8_t, uint64_t, int8_t, int, uint64_t, const void *, size_t n, char [n]);
16STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *); 20STATIC bool coord_solution_admissible(const dfsarg_solve_coord_t [static 1]);
21STATIC bool solve_coord_dfs_stop(const dfsarg_solve_coord_t [static 1]);
22STATIC bool coord_continue_onnormal(const dfsarg_solve_coord_t [static 1]);
23STATIC bool coord_continue_oninverse(const dfsarg_solve_coord_t [static 1]);
24STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t [static 1]);
25
26STATIC bool
27coord_solution_admissible(const dfsarg_solve_coord_t arg[static 1])
28{
29 uint8_t n;
30
31 n = arg->solution_moves->nmoves + arg->solution_moves->npremoves;
32 if (arg->target_depth != n)
33 return false;
34
35 return arg->coord->is_admissible == NULL ||
36 arg->coord->is_admissible(arg->solution_moves);
37}
38
39STATIC bool
40solve_coord_dfs_stop(const dfsarg_solve_coord_t arg[static 1])
41{
42 bool hasnissed;
43 uint8_t n, pval;
44 uint64_t coord;
45 const cube_t *c;
46
47 n = arg->solution_moves->nmoves + arg->solution_moves->npremoves;
48 if (n >= arg->target_depth)
49 return true;
50
51 hasnissed = arg->solution_moves->nmoves > 0 &&
52 arg->solution_moves->npremoves > 0;
53 if (!hasnissed && (arg->nissflag & NISSY_NISSFLAG_MIXED))
54 return false;
55
56 c = arg->lastisnormal ? &arg->cube : &arg->inverse;
57
58 coord = arg->coord->coord(*c, arg->coord_data);
59 pval = get_coord_pval(arg->coord, arg->ptable, coord);
60
61 return n + pval > arg->target_depth;
62}
63
64STATIC bool
65coord_continue_onnormal(const dfsarg_solve_coord_t arg[static 1])
66{
67 uint8_t f, nn, ni, th;
68
69 f = arg->nissflag;
70 nn = arg->solution_moves->nmoves;
71 ni = arg->solution_moves->npremoves;
72 th = DIV_ROUND_UP(arg->target_depth, 2);
73
74 if (nn + ni == 0)
75 return f & (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_MIXED);
76
77 if (arg->lastisnormal)
78 return (f & NISSY_NISSFLAG_NORMAL) ||
79 ((f & NISSY_NISSFLAG_MIXED) && (ni > 0 || nn <= th));
80
81 return (f & NISSY_NISSFLAG_MIXED) && nn == 0 && ni < th &&
82 coord_can_switch(arg->coord, arg->coord_data,
83 ni, arg->solution_moves->premoves);
84}
85
86STATIC bool
87coord_continue_oninverse(const dfsarg_solve_coord_t arg[static 1])
88{
89 uint8_t f, nn, ni, th;
90
91 f = arg->nissflag;
92 nn = arg->solution_moves->nmoves;
93 ni = arg->solution_moves->npremoves;
94 th = DIV_ROUND_UP(arg->target_depth, 2);
95
96 if (nn + ni == 0)
97 return f & (NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED);
98
99 if (!arg->lastisnormal)
100 return (f & NISSY_NISSFLAG_INVERSE) ||
101 ((f & NISSY_NISSFLAG_MIXED) && (nn > 0 || ni < th));
102
103 return (f & NISSY_NISSFLAG_MIXED) && ni == 0 && nn <= th &&
104 coord_can_switch(arg->coord, arg->coord_data,
105 nn, arg->solution_moves->moves);
106}
17 107
18STATIC int64_t 108STATIC int64_t
19solve_coord_dfs(dfsarg_solve_coord_t *arg) 109solve_coord_dfs(dfsarg_solve_coord_t arg[static 1])
20{ 110{
21 uint8_t m, pval; 111 bool lastbackup;
112 uint8_t m, l, nnbackup, nibackup;
22 uint32_t mm; 113 uint32_t mm;
23 uint64_t coord; 114 uint64_t coord;
24 int64_t n, ret; 115 int64_t n, ret;
25 cube_t backup_cube; 116 cube_t backup_cube, backup_inverse;
26 117
27 coord = arg->coord->coord(arg->cube, arg->coord_data); 118 coord = arg->coord->coord(arg->cube, arg->coord_data);
28
29 if (coord == 0) { 119 if (coord == 0) {
30 if (arg->solution_moves->nmoves != arg->target_depth || 120 if (!coord_solution_admissible(arg))
31 (arg->coord->is_admissible != NULL &&
32 !arg->coord->is_admissible(arg->solution_moves->nmoves,
33 arg->solution_moves->moves)))
34 return 0; 121 return 0;
35 return appendsolution(arg->solution_moves, 122 return appendsolution(arg->solution_moves,
36 arg->solution_settings, arg->solution_list); 123 arg->solution_settings, arg->solution_list);
37 } 124 }
38 125
39 pval = get_coord_pval(arg->coord, arg->ptable, coord); 126 if (solve_coord_dfs_stop(arg))
40 if (arg->solution_moves->nmoves + pval > arg->target_depth)
41 return 0; 127 return 0;
42 128
43 backup_cube = arg->cube; 129 backup_cube = arg->cube;
130 backup_inverse = arg->inverse;
131 lastbackup = arg->lastisnormal;
132 nnbackup = arg->solution_moves->nmoves;
133 nibackup = arg->solution_moves->npremoves;
44 134
45 ret = 0; 135 ret = 0;
46 mm = allowednextmove_mask( 136 if (coord_continue_onnormal(arg)) {
47 arg->solution_moves->nmoves, arg->solution_moves->moves); 137 l = arg->solution_moves->nmoves;
48 arg->solution_moves->nmoves++; 138 mm = allowednextmove_mask(l, arg->solution_moves->moves);
49 for (m = 0; m < NMOVES; m++) { 139 arg->solution_moves->nmoves++;
50 if (!(mm & (1 << m))) 140 arg->lastisnormal = true;
51 continue;
52 141
53 arg->solution_moves->moves[arg->solution_moves->nmoves-1] = m; 142 for (m = 0; m < NMOVES; m++) {
54 arg->cube = move(backup_cube, m); 143 if (!(mm & (UINT32_C(1) << (uint32_t)m)))
55 n = solve_coord_dfs(arg); 144 continue;
56 if (n < 0) 145
57 return n; 146 arg->solution_moves->moves[l] = m;
58 ret += n; 147 arg->cube = move(backup_cube, m);
148 arg->inverse = premove(backup_inverse, m);
149 n = solve_coord_dfs(arg);
150 if (n < 0)
151 return n;
152 ret += n;
153 arg->solution_moves->npremoves = nibackup;
154 }
155
156 arg->solution_moves->nmoves--;
59 } 157 }
158
159 arg->lastisnormal = lastbackup;
160
161 if (coord_continue_oninverse(arg)) {
162 l = arg->solution_moves->npremoves;
163 mm = allowednextmove_mask(l, arg->solution_moves->premoves);
164 arg->solution_moves->npremoves++;
165 arg->lastisnormal = false;
166
167 for (m = 0; m < NMOVES; m++) {
168 if (!(mm & (UINT32_C(1) << (uint32_t)m)))
169 continue;
170
171 arg->solution_moves->premoves[l] = m;
172 arg->inverse = move(backup_inverse, m);
173 arg->cube = premove(backup_cube, m);
174 n = solve_coord_dfs(arg);
175 if (n < 0)
176 return n;
177 ret += n;
178 arg->solution_moves->nmoves = nnbackup;
179 }
180
181 arg->solution_moves->npremoves--;
182 }
183
60 arg->cube = backup_cube; 184 arg->cube = backup_cube;
61 arg->solution_moves->nmoves--; 185 arg->inverse = backup_inverse;
186 arg->lastisnormal = lastbackup;
62 187
63 return 0; 188 return ret;
64} 189}
65 190
66STATIC int64_t 191STATIC int64_t
@@ -76,7 +201,7 @@ solve_coord_dispatch(
76 uint64_t data_size, 201 uint64_t data_size,
77 const void *data, 202 const void *data,
78 size_t solutions_size, 203 size_t solutions_size,
79 char *sols 204 char sols[solutions_size]
80) 205)
81{ 206{
82 coord_t *coord; 207 coord_t *coord;
@@ -103,7 +228,7 @@ solve_coord_dispatch(
103STATIC int64_t 228STATIC int64_t
104solve_coord( 229solve_coord(
105 cube_t cube, 230 cube_t cube,
106 coord_t *coord, 231 coord_t coord [static 1],
107 uint8_t axis, 232 uint8_t axis,
108 uint8_t nissflag, 233 uint8_t nissflag,
109 uint8_t minmoves, 234 uint8_t minmoves,
@@ -114,7 +239,7 @@ solve_coord(
114 uint64_t data_size, 239 uint64_t data_size,
115 const void *data, 240 const void *data,
116 size_t solutions_size, 241 size_t solutions_size,
117 char *sols 242 char sols[solutions_size]
118) 243)
119{ 244{
120 int8_t d; 245 int8_t d;
@@ -160,12 +285,22 @@ solve_coord(
160 285
161 arg = (dfsarg_solve_coord_t) { 286 arg = (dfsarg_solve_coord_t) {
162 .cube = c, 287 .cube = c,
288 .inverse = inverse(c),
163 .coord = coord, 289 .coord = coord,
164 .coord_data = coord_data, 290 .coord_data = coord_data,
165 .ptable = ptable, 291 .ptable = ptable,
166 .solution_moves = &solution_moves, 292 .solution_moves = &solution_moves,
167 .solution_settings = &solution_settings, 293 .solution_settings = &solution_settings,
168 .solution_list = &solution_list, 294 .solution_list = &solution_list,
295 .nissflag = nissflag,
296
297 /*
298 Since no move has been done yet, this field should be
299 neither true nor false; using its value now is logically
300 undefined behavior.
301 TODO: find a more elegant solution
302 */
303 .lastisnormal = true,
169 }; 304 };
170 305
171 if (coord->coord(c, coord_data) == 0) { 306 if (coord->coord(c, coord_data) == 0) {
diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h
index f2d436c..9eaeca0 100644
--- a/src/solvers/coord/types_macros.h
+++ b/src/solvers/coord/types_macros.h
@@ -11,5 +11,5 @@ typedef struct {
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 uint8_t axistrans[3];
14 bool (*is_admissible)(size_t n, uint8_t [n]); 14 bool (*is_admissible)(const solution_moves_t[static 1]);
15} coord_t; 15} coord_t;
diff --git a/src/solvers/coord/utils.h b/src/solvers/coord/utils.h
new file mode 100644
index 0000000..ab4aded
--- /dev/null
+++ b/src/solvers/coord/utils.h
@@ -0,0 +1,68 @@
1STATIC coord_t *parse_coord(size_t n, const char [n]);
2STATIC uint8_t parse_axis(size_t n, const char [n]);
3STATIC void parse_coord_and_axis(size_t n, const char [n], coord_t **, uint8_t *);
4STATIC int64_t dataid_coord(const char *, char [static NISSY_DATAID_SIZE]);
5
6STATIC coord_t *
7parse_coord(size_t n, const char coord[n])
8{
9 int i;
10
11 for (i = 0; all_coordinates[i] != NULL; i++)
12 if (!strncmp(all_coordinates[i]->name, coord, n))
13 return all_coordinates[i];
14
15 return NULL;
16}
17
18STATIC uint8_t
19parse_axis(size_t n, const char axis[n])
20{
21 if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) {
22 return AXIS_UD;
23 } else if (!strncmp(axis, "RL", n) || !strncmp(axis, "LR", n)) {
24 return AXIS_RL;
25 } else if (!strncmp(axis, "FB", n) || !strncmp(axis, "BF", n)) {
26 return AXIS_FB;
27 }
28
29 return UINT8_ERROR;
30}
31
32STATIC void
33parse_coord_and_axis(
34 size_t n,
35 const char str[n],
36 coord_t **coord,
37 uint8_t *axis
38)
39{
40 size_t i;
41
42 for (i = 0; i < n; i++)
43 if (str[i] == '_')
44 break;
45
46 if (coord != NULL)
47 *coord = parse_coord(i, str);
48
49 if (axis != NULL)
50 *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, str+i+1);
51}
52
53STATIC int64_t
54dataid_coord(const char *ca, char dataid[static NISSY_DATAID_SIZE])
55{
56 coord_t *c;
57
58 parse_coord_and_axis(strlen(ca), ca, &c, NULL);
59
60 if (c == NULL) {
61 LOG("dataid_coord: cannot parse coordinate from '%s'\n", ca);
62 return NISSY_ERROR_INVALID_SOLVER;
63 }
64
65 strcpy(dataid, c->name);
66
67 return NISSY_OK;
68}

Generated with cgit - Back to sebastiano.tronto.net