commit ce3f1cc0ef9f46d70ab5387b1458e9098b40711d parent 0550a16c1cce868bbc3f3b5ad59f80e35cf2a6cd Author: Sebastiano Tronto <sebastiano@tronto.net> Date: Sat, 22 Mar 2025 06:43:11 +0100 Some safety with move arrays, small refactor appendchar Diffstat:
23 files changed, 168 insertions(+), 170 deletions(-)
diff --git a/src/core/cube.h b/src/core/cube.h @@ -87,7 +87,7 @@ issolvable(cube_t cube) for (i = 0; i < 8; i++) cp[i] = corner[i] & PBITS; - if (permsign(ep, 12) != permsign(cp, 8)) + if (permsign(12, ep) != permsign(8, cp)) goto issolvable_parity; eo = 0; @@ -139,13 +139,13 @@ getcube_fix(long long *ep, long long *eo, long long *cp, long long *co) indextoperm(*ep, 12, e); indextoperm(*cp, 8, c); - if (permsign(e, 12) != permsign(c, 8)) { + if (permsign(12, e) != permsign(8, c)) { SWAP(c[0], c[1]); - *cp = permtoindex(c, 8); + *cp = permtoindex(8, c); sumzerotodigits(*co, 8, 3, coarr); SWAP(coarr[0], coarr[1]); - *co = digitstosumzero(coarr, 8, 3); + *co = digitstosumzero(8, coarr, 3); } } diff --git a/src/core/io_cube.h b/src/core/io_cube.h @@ -1,5 +1,5 @@ STATIC cube_t readcube(const char *, const char *); -STATIC int64_t writecube(const char *, cube_t, uint64_t, char *); +STATIC int64_t writecube(const char *, cube_t, size_t n, char [n]); STATIC void log_available_formats(void); STATIC uint8_t readco(const char *); STATIC uint8_t readcp(const char *); @@ -10,10 +10,10 @@ STATIC cube_t readcube_H48(const char *); STATIC uint8_t readpiece_LST(const char **); STATIC cube_t readcube_LST(const char *); -STATIC int64_t writepiece_LST(uint8_t, uint64_t, char *); -STATIC int64_t writecube_B32(cube_t, uint64_t, char *); -STATIC int64_t writecube_H48(cube_t, uint64_t, char *); -STATIC int64_t writecube_LST(cube_t, uint64_t, char *); +STATIC int64_t writepiece_LST(uint8_t, size_t n, char [n]); +STATIC int64_t writecube_B32(cube_t, size_t n, char [n]); +STATIC int64_t writecube_H48(cube_t, size_t n, char [n]); +STATIC int64_t writecube_LST(cube_t, size_t n, char [n]); STATIC uint8_t b32toedge(char); STATIC uint8_t b32tocorner(char); @@ -23,7 +23,7 @@ STATIC char cornertob32(uint8_t); STATIC struct { const char *name; cube_t (*read)(const char *); - int64_t (*write)(cube_t, uint64_t, char *); + int64_t (*write)(cube_t, size_t n, char [n]); } ioformat[] = { { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, @@ -47,7 +47,7 @@ readcube(const char *format, const char *buf) } STATIC int64_t -writecube(const char *format, cube_t cube, uint64_t buf_size, char *buf) +writecube(const char *format, cube_t cube, size_t buf_size, char buf[buf_size]) { int i; @@ -233,10 +233,10 @@ readcube_LST(const char *buf) } STATIC int64_t -writepiece_LST(uint8_t piece, uint64_t buf_size, char *buf) +writepiece_LST(uint8_t piece, size_t buf_size, char buf[buf_size]) { char digits[3]; - uint64_t i, len; + size_t i, len; if (piece > 99 || buf_size < 3) return 0; @@ -263,7 +263,7 @@ writepiece_LST(uint8_t piece, uint64_t buf_size, char *buf) } STATIC int64_t -writecube_B32(cube_t cube, uint64_t buf_size, char *buf) +writecube_B32(cube_t cube, size_t buf_size, char buf[buf_size]) { int i; uint8_t corner[8], edge[12]; @@ -291,7 +291,7 @@ writecube_B32(cube_t cube, uint64_t buf_size, char *buf) } STATIC int64_t -writecube_H48(cube_t cube, uint64_t buf_size, char *buf) +writecube_H48(cube_t cube, size_t buf_size, char buf[buf_size]) { uint8_t piece, perm, orient, corner[8], edge[12]; int i; @@ -331,7 +331,7 @@ writecube_H48(cube_t cube, uint64_t buf_size, char *buf) } STATIC int64_t -writecube_LST(cube_t cube, uint64_t buf_size, char *buf) +writecube_LST(cube_t cube, size_t buf_size, char buf[buf_size]) { int i; uint64_t ptr; diff --git a/src/core/io_moves.h b/src/core/io_moves.h @@ -1,6 +1,6 @@ STATIC uint8_t readmove(char); STATIC uint8_t readmodifier(char); -STATIC int64_t writemoves(uint8_t *, int, uint64_t, char *); +STATIC int64_t writemoves(size_t n, uint8_t [n], size_t m, char [m]); STATIC uint8_t readmove(char c) @@ -39,11 +39,14 @@ readmodifier(char c) } STATIC int64_t -writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) +writemoves( + size_t nmoves, + uint8_t m[nmoves], + size_t buf_size, + char buf[buf_size] +) { - int i; - uint64_t len; - int64_t written; + size_t i, len, written; const char *s; char *b; @@ -52,7 +55,7 @@ writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) return NISSY_ERROR_BUFFER_SIZE; } - for (i = 0, b = buf, written = 0; i < n; i++, b++, written++) { + for (i = 0, b = buf, written = 0; i < nmoves; i++, b++, written++) { s = movestr[m[i]]; len = strlen(s); if (len + written >= buf_size) { @@ -70,7 +73,7 @@ writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) b--; /* Remove last space */ *b = '\0'; - return written; + return (int64_t)written; writemoves_error: *buf = '\0'; diff --git a/src/core/moves.h b/src/core/moves.h @@ -1,8 +1,8 @@ #define MOVE(M, c) compose(c, MOVE_CUBE_ ## M) #define PREMOVE(M, c) compose(MOVE_CUBE_ ## M, c) -STATIC_INLINE bool allowednextmove(uint8_t *, uint8_t); -STATIC_INLINE uint32_t allowednextmove_mask(uint8_t *, uint8_t); +STATIC_INLINE bool allowednextmove(size_t n, const uint8_t [n]); +STATIC_INLINE uint32_t allowednextmove_mask(size_t n, const uint8_t [n]); STATIC_INLINE uint8_t movebase(uint8_t); STATIC_INLINE uint8_t moveaxis(uint8_t); @@ -13,9 +13,9 @@ STATIC_INLINE uint32_t disable_moves(uint32_t, uint8_t); STATIC cube_t move(cube_t, uint8_t); STATIC cube_t premove(cube_t, uint8_t); STATIC uint8_t inverse_move(uint8_t); -STATIC void invertmoves(uint8_t *, uint8_t, uint8_t *); -STATIC void sortparallel(uint8_t *, uint8_t); -STATIC bool are_lastmoves_singlecw(int n, uint8_t [n]); +STATIC void invertmoves(size_t n, const uint8_t [n], uint8_t [n]); +STATIC void sortparallel(size_t n, uint8_t [n]); +STATIC bool are_lastmoves_singlecw(size_t n, uint8_t [n]); STATIC int readmoves(const char *, int, uint8_t *); STATIC cube_t applymoves(cube_t, const char *); @@ -40,14 +40,13 @@ STATIC cube_t applymoves(cube_t, const char *); } STATIC bool -allowednextmove(uint8_t *moves, uint8_t n) +allowednextmove(size_t n, const uint8_t moves[n]) { - return n == 0 ? true : - allowednextmove_mask(moves, n-1) & (1 << moves[n-1]); + return n == 0 || allowednextmove_mask(n-1, moves) & (1 << moves[n-1]); } STATIC uint32_t -allowednextmove_mask(uint8_t *moves, uint8_t n) +allowednextmove_mask(size_t n, const uint8_t moves[n]) { uint32_t result; uint8_t base1, base2, axis1, axis2; @@ -79,7 +78,7 @@ allowednextmove_mask(uint8_t *moves, uint8_t n) STATIC_INLINE uint32_t disable_moves(uint32_t current_result, uint8_t base_index) { - return current_result & ~(7 << base_index); + return current_result & ~MM_SIDE(base_index); } STATIC_INLINE uint8_t @@ -236,17 +235,17 @@ TODO check if the issue is resolved #pragma GCC push_options #pragma GCC optimize ("O2") STATIC void -invertmoves(uint8_t *moves, uint8_t nmoves, uint8_t *ret) +invertmoves(size_t n, const uint8_t moves[n], uint8_t ret[n]) { uint8_t i; - for (i = 0; i < nmoves; i++) - ret[i] = inverse_move(moves[nmoves - i - 1]); + for (i = 0; i < n; i++) + ret[i] = inverse_move(moves[n - i - 1]); } #pragma GCC pop_options STATIC void -sortparallel(uint8_t *moves, uint8_t n) +sortparallel(size_t n, uint8_t moves[n]) { uint8_t i; @@ -257,7 +256,7 @@ sortparallel(uint8_t *moves, uint8_t n) } STATIC bool -are_lastmoves_singlecw(int n, uint8_t moves[n]) +are_lastmoves_singlecw(size_t n, uint8_t moves[n]) { bool two; diff --git a/src/solvers/coord/common.h b/src/solvers/coord/common.h @@ -4,9 +4,9 @@ coord_t *all_coordinates[] = { }; STATIC void append_coord_name(const coord_t *, char *); -STATIC coord_t *parse_coord(const char *, int); -STATIC uint8_t parse_axis(const char *, int); -STATIC void parse_coord_and_axis(const char *, int, coord_t **, uint8_t *); +STATIC coord_t *parse_coord(size_t n, const char [n]); +STATIC uint8_t parse_axis(size_t n, const char [n]); +STATIC void parse_coord_and_axis(size_t n, const char [n], coord_t **, uint8_t *); STATIC int64_t dataid_coord(const char *, char [static NISSY_DATAID_SIZE]); STATIC void @@ -22,7 +22,7 @@ append_coord_name(const coord_t *coord, char *str) } STATIC coord_t * -parse_coord(const char *coord, int n) +parse_coord(size_t n, const char coord[n]) { int i; @@ -34,7 +34,7 @@ parse_coord(const char *coord, int n) } STATIC uint8_t -parse_axis(const char *axis, int n) +parse_axis(size_t n, const char axis[n]) { if (!strncmp(axis, "UD", n) || !strncmp(axis, "DU", n)) { return AXIS_UD; @@ -48,19 +48,24 @@ parse_axis(const char *axis, int n) } STATIC void -parse_coord_and_axis(const char *str, int n, coord_t **coord, uint8_t *axis) +parse_coord_and_axis( + size_t n, + const char str[n], + coord_t **coord, + uint8_t *axis +) { - int i; + size_t i; for (i = 0; i < n; i++) if (str[i] == '_') break; if (coord != NULL) - *coord = parse_coord(str, i); + *coord = parse_coord(i, str); if (axis != NULL) - *axis = i == n ? UINT8_ERROR : parse_axis(str+i+1, n-i-1); + *axis = i == n ? UINT8_ERROR : parse_axis(n-i-1, str+i+1); } STATIC int64_t @@ -68,7 +73,7 @@ dataid_coord(const char *ca, char dataid[static NISSY_DATAID_SIZE]) { coord_t *c; - parse_coord_and_axis(ca, strlen(ca), &c, NULL); + parse_coord_and_axis(strlen(ca), ca, &c, NULL); if (c == NULL) { LOG("dataid_coord: cannot parse coordinate from '%s'\n", ca); diff --git a/src/solvers/coord/gendata.h b/src/solvers/coord/gendata.h @@ -11,7 +11,7 @@ gendata_coord_dispatch(const char *coordstr, void *buf) { coord_t *coord; - parse_coord_and_axis(coordstr, strlen(coordstr), &coord, NULL); + parse_coord_and_axis(strlen(coordstr), coordstr, &coord, NULL); if (coord == NULL) { LOG("Could not parse coordinate '%s'\n", coord); @@ -137,7 +137,7 @@ getdistribution_coord( memset(distr, 0, INFO_DISTRIBUTION_LEN * sizeof(uint64_t)); - if((c = parse_coord(coord, strlen(coord))) == NULL) + if((c = parse_coord(strlen(coord), coord)) == NULL) return; for (i = 0; i < c->max; i++) { diff --git a/src/solvers/coord/solve.h b/src/solvers/coord/solve.h @@ -1,10 +1,8 @@ -#define MAXLEN_COORDSOL 20 - typedef struct { cube_t cube; uint8_t depth; uint8_t nmoves; - uint8_t moves[MAXLEN_COORDSOL]; + uint8_t moves[MAXLEN]; coord_t *coord; const void *coord_data; const uint8_t *ptable; @@ -13,23 +11,22 @@ typedef struct { int64_t maxsolutions; int optimal; uint8_t *shortest_sol; - uint64_t solutions_size; - uint64_t *solutions_used; + size_t solutions_size; + size_t *solutions_used; char **solutions; } dfsarg_solve_coord_t; STATIC int64_t solve_coord(cube_t, coord_t *, uint8_t, uint8_t, uint8_t, - uint8_t, uint64_t, int, int, uint64_t, const void *, uint64_t, char *); + uint8_t, uint64_t, int, int, uint64_t, const void *, size_t, char *); STATIC int64_t solve_coord_dispatch(cube_t, const char *, uint8_t, uint8_t, - uint8_t, uint64_t, int, int, uint64_t, const void *, uint64_t, char *); -STATIC bool solve_coord_appendchar(char *, uint64_t, uint64_t *, char); + uint8_t, uint64_t, int, int, uint64_t, const void *, size_t, char *); STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *); STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *); STATIC int64_t solve_coord_appendsolution(dfsarg_solve_coord_t *arg) { - uint8_t i, t, tmoves[MAXLEN_COORDSOL]; + uint8_t i, t, tmoves[MAXLEN]; int64_t strl; uint64_t l; char *m; @@ -44,18 +41,18 @@ solve_coord_appendsolution(dfsarg_solve_coord_t *arg) for (i = 0; i < arg->nmoves; i++) tmoves[i] = transform_move(arg->moves[i], t); - sortparallel(tmoves, arg->nmoves); + sortparallel(arg->nmoves, tmoves); l = arg->solutions_size - *arg->solutions_used; m = *arg->solutions + *arg->solutions_used; - strl = writemoves(tmoves, arg->nmoves, l, m); + strl = writemoves(arg->nmoves, tmoves, l, m); if (strl < 0) goto solve_coord_appendsolution_error; *arg->solutions_used += MAX(0, strl-1); - if (!solve_coord_appendchar( - *arg->solutions, arg->solutions_size, arg->solutions_used, '\n')) + if (!appendchar( + arg->solutions_size, *arg->solutions, arg->solutions_used, '\n')) goto solve_coord_appendsolution_error; (*arg->nsols)++; @@ -68,18 +65,6 @@ solve_coord_appendsolution_error: return NISSY_ERROR_BUFFER_SIZE; } -STATIC bool -solve_coord_appendchar(char *s, uint64_t s_size, uint64_t *s_used, char c) -{ - if (s_size == *s_used) - return false; - - s[*s_used] = c; - (*s_used)++; - - return true; -} - STATIC int64_t solve_coord_dfs(dfsarg_solve_coord_t *arg) { @@ -104,7 +89,7 @@ solve_coord_dfs(dfsarg_solve_coord_t *arg) backup_cube = arg->cube; ret = 0; - mm = allowednextmove_mask(arg->moves, arg->nmoves); + mm = allowednextmove_mask(arg->nmoves, arg->moves); arg->nmoves++; for (m = 0; m < 18; m++) { if (!(mm & (1 << m))) @@ -135,7 +120,7 @@ solve_coord_dispatch( int threads, uint64_t data_size, const void *data, - uint64_t sols_size, + size_t solutions_size, char *sols ) { @@ -143,7 +128,7 @@ solve_coord_dispatch( uint8_t axis; parse_coord_and_axis( - coord_and_axis, strlen(coord_and_axis), &coord, &axis); + strlen(coord_and_axis), coord_and_axis, &coord, &axis); if (coord == NULL) { LOG("Could not parse coordinate from '%s'\n", coord_and_axis); @@ -156,7 +141,8 @@ solve_coord_dispatch( } return solve_coord(cube, coord, axis, nissflag, minmoves, maxmoves, - maxsolutions, optimal, threads, data_size, data, sols_size, sols); + maxsolutions, optimal, threads, data_size, data, + solutions_size, sols); } STATIC int64_t @@ -172,14 +158,14 @@ solve_coord( int threads, uint64_t data_size, const void *data, - uint64_t sols_size, + size_t solutions_size, char *sols ) { int8_t d; uint8_t t, shortest_sol; int64_t nsols, ndepth; - uint64_t sols_used; + size_t solutions_used; cube_t c; const void *coord_data; const uint8_t *ptable; @@ -200,8 +186,8 @@ solve_coord( } nsols = 0; - sols_used = 0; - shortest_sol = MAXLEN_COORDSOL + 1; + solutions_used = 0; + shortest_sol = MAXLEN + 1; t = coord->axistrans[axis]; c = transform(cube, t); @@ -215,16 +201,15 @@ solve_coord( .maxsolutions = (int64_t)maxsolutions, .optimal = optimal, .shortest_sol = &shortest_sol, - .solutions_size = sols_size, - .solutions_used = &sols_used, + .solutions_size = solutions_size, + .solutions_used = &solutions_used, .solutions = &sols, }; if (coord->coord(c, coord_data) == 0) { if (minmoves == 0) { nsols = 1; - if (!solve_coord_appendchar( - sols, sols_size, &sols_used, '\n')) + if (!appendchar(solutions_size, sols, &solutions_used, '\n')) goto solve_coord_error_buffer; } goto solve_coord_done; @@ -254,7 +239,7 @@ solve_coord( } solve_coord_done: - if (!solve_coord_appendchar(sols, sols_size, &sols_used, '\0')) + if (!appendchar(solutions_size, sols, &solutions_used, '\0')) goto solve_coord_error_buffer; return nsols; diff --git a/src/solvers/coord/types_macros.h b/src/solvers/coord/types_macros.h @@ -11,5 +11,5 @@ typedef struct { uint32_t moves_mask; uint64_t trans_mask; uint8_t axistrans[3]; - bool (*is_admissible)(int n, uint8_t [n]); + bool (*is_admissible)(size_t n, uint8_t [n]); } coord_t; diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h @@ -533,7 +533,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t *arg) /* Depth d+3 */ for (m[2] = 0; m[2] < 18; m[2]++) { markarg.depth = d+3; - if (!allowednextmove(m, 3)) { + if (!allowednextmove(3, m)) { m[2] += 2; continue; } @@ -548,7 +548,7 @@ gendata_h48k2_dfs(h48k2_dfs_arg_t *arg) /* Depth d+4 */ for (m[3] = 0; m[3] < 18; m[3]++) { markarg.depth = d+4; - if (!allowednextmove(m, 4)) { + if (!allowednextmove(4, m)) { m[3] += 2; continue; } diff --git a/src/solvers/h48/gendata_types_macros.h b/src/solvers/h48/gendata_types_macros.h @@ -28,7 +28,6 @@ #define H48_SHIFT(i, k) ((uint8_t)(k) * (uint8_t)((i) % H48_COEFF(k))) #define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) -#define MAXLEN 20 #define CHUNKS COCSEP_CLASSES /* diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h @@ -32,8 +32,8 @@ typedef struct { const uint8_t *h48data; const uint8_t *h48data_fallback_h0k4; const void *h48data_fallback_eoesep; - uint64_t solutions_size; - uint64_t *solutions_used; + size_t solutions_size; + size_t *solutions_used; char **solutions; uint32_t movemask_normal; uint32_t movemask_inverse; @@ -58,7 +58,6 @@ typedef struct { STATIC int64_t solve_h48_appendsolution(dfsarg_solve_h48_t *); STATIC int64_t solve_h48_appendallsym(dfsarg_solve_h48_t *); -STATIC bool solve_h48_appendchar(dfsarg_solve_h48_t *, char); STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t *); STATIC int64_t solve_h48_maketasks( dfsarg_solve_h48_t *, dfsarg_solve_h48_maketasks_t *, @@ -66,7 +65,7 @@ STATIC int64_t solve_h48_maketasks( STATIC void *solve_h48_runthread(void *); STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t *); STATIC int64_t solve_h48(cube_t, int8_t, int8_t, uint64_t, int8_t, int8_t, - uint64_t, const void *, uint64_t, char *, + uint64_t, const void *, size_t, char *, long long [static NISSY_SIZE_SOLVE_STATS]); STATIC int64_t @@ -76,15 +75,15 @@ solve_h48_appendsolution(dfsarg_solve_h48_t *arg) arg->nmoves + arg->npremoves > *arg->shortest_sol + arg->optimal) return 0; - invertmoves(arg->premoves, arg->npremoves, arg->moves + arg->nmoves); + invertmoves(arg->npremoves, arg->premoves, arg->moves + arg->nmoves); /* Sort parallel moves for consistency */ - sortparallel(arg->moves, arg->nmoves + arg->npremoves); + sortparallel(arg->nmoves + arg->npremoves, arg->moves); /* Do not append the solution in case premoves cancel with normal */ - if (arg->npremoves > 0 && !allowednextmove(arg->moves, arg->nmoves+1)) + if (arg->npremoves > 0 && !allowednextmove(arg->nmoves+1, arg->moves)) return 0; - if (arg->npremoves > 1 && !allowednextmove(arg->moves, arg->nmoves+2)) + if (arg->npremoves > 1 && !allowednextmove(arg->nmoves+2, arg->moves)) return 0; return solve_h48_appendallsym(arg); @@ -109,7 +108,7 @@ solve_h48_appendallsym(dfsarg_solve_h48_t *arg) all[j][i] = transform_move(arg->moves[i], t); /* Sort parallel moves for consistency */ - sortparallel(all[j], n); + sortparallel(n, all[j]); /* Check for duplicate solutions */ for (k = 0; k < j; k++) { @@ -133,7 +132,7 @@ solve_h48_appendallsym(dfsarg_solve_h48_t *arg) for (k = 0; k < j && *arg->nsols < arg->maxsolutions; k++) { l = arg->solutions_size - *arg->solutions_used; m = *arg->solutions + *arg->solutions_used; - strl = writemoves(all[k], n, l, m); + strl = writemoves(n, all[k], l, m); if (strl < 0) goto solve_h48_appendallsym_error; @@ -141,7 +140,8 @@ solve_h48_appendallsym(dfsarg_solve_h48_t *arg) *arg->solutions_used += MAX(0, strl-1); - if (!solve_h48_appendchar(arg, '\n')) + if (!appendchar(arg->solutions_size, + *arg->solutions, arg->solutions_used, '\n')) goto solve_h48_appendallsym_error; (*arg->nsols)++; @@ -156,18 +156,6 @@ solve_h48_appendallsym_error: return NISSY_ERROR_BUFFER_SIZE; } -STATIC bool -solve_h48_appendchar(dfsarg_solve_h48_t *arg, char c) -{ - if (arg->solutions_size <= *arg->solutions_used) - return false; - - *(*arg->solutions + *arg->solutions_used) = c; - (*arg->solutions_used)++; - - return true; -} - STATIC_INLINE bool solve_h48_stop(dfsarg_solve_h48_t *arg) { @@ -283,9 +271,9 @@ solve_h48_dfs(dfsarg_solve_h48_t *arg) ulbi = arg->use_lb_inverse; ret = 0; - mm_normal = allowednextmove_mask(arg->moves, arg->nmoves) & + mm_normal = allowednextmove_mask(arg->nmoves, arg->moves) & arg->movemask_normal; - mm_inverse = allowednextmove_mask(arg->premoves, arg->npremoves) & + mm_inverse = allowednextmove_mask(arg->npremoves, arg->premoves) & arg->movemask_inverse; if (popcount_u32(mm_normal) <= popcount_u32(mm_inverse)) { arg->nmoves++; @@ -397,7 +385,7 @@ solve_h48_maketasks( return NISSY_OK; } - mm = allowednextmove_mask(maketasks_arg->moves, maketasks_arg->nmoves); + mm = allowednextmove_mask(maketasks_arg->nmoves, maketasks_arg->moves); maketasks_arg->nmoves++; backup_cube = maketasks_arg->cube; @@ -435,7 +423,7 @@ solve_h48( int8_t threads, uint64_t data_size, const void *data, - uint64_t solutions_size, + size_t solutions_size, char *solutions, long long stats[static NISSY_SIZE_SOLVE_STATS] ) @@ -447,7 +435,8 @@ solve_h48( solve_h48_task_t tasks[STARTING_CUBES]; dfsarg_solve_h48_maketasks_t maketasks_arg; long double fallback_rate, lookups_per_node; - uint64_t solutions_used, symmask, offset; + uint64_t symmask, offset; + size_t solutions_used; int64_t nodes_visited, table_lookups, table_fallbacks; tableinfo_t info, fbinfo, fbinfo2; const uint32_t *cocsepdata; @@ -561,7 +550,8 @@ solve_h48( } solve_h48_done: - if (!solve_h48_appendchar(&arg[0], '\0')) + if (!appendchar(arg[0].solutions_size, *arg[0].solutions, + arg[0].solutions_used, '\0')) goto solve_h48_error_solutions_buffer; nodes_visited = table_lookups = table_fallbacks = 0; diff --git a/src/solvers/solutions.h b/src/solvers/solutions.h @@ -0,0 +1,14 @@ +#define MAXLEN 20 + +STATIC bool appendchar(size_t n, char [n], size_t *, char); + +STATIC bool +appendchar(size_t n, char s[n], size_t *used, char c) +{ + if (n <= *used) + return false; + + s[(*used)++] = c; + + return true; +} diff --git a/src/solvers/solvers.h b/src/solvers/solvers.h @@ -1,3 +1,4 @@ +#include "solutions.h" #include "tables.h" #include "h48/h48.h" #include "coord/coord.h" diff --git a/src/utils/constants.h b/src/utils/constants.h @@ -102,8 +102,10 @@ STATIC int64_t binomial[12][12] = { #define MM_ALLMOVES UINT32_C(0x3FFFF) #define MM_NOHALFTURNS UINT32_C(0x2DB6D) +#define MM_SIDE(m) (UINT32_C(7) << (uint32_t)(m)) #define TM_ALLTRANS UINT64_C(0xFFFFFFFFFFFF) +#define TM_SINGLE_UFr UINT64_C(1) #define CORNER_UFR UINT8_C(0) #define CORNER_UBL UINT8_C(1) diff --git a/src/utils/math.h b/src/utils/math.h @@ -4,12 +4,12 @@ #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) STATIC int64_t factorial(int64_t); -STATIC bool isperm(uint8_t *, int64_t); -STATIC int64_t permtoindex(uint8_t *, int64_t); -STATIC void indextoperm(int64_t, int64_t, uint8_t *); -STATIC int permsign(uint8_t *, int64_t); -STATIC int64_t digitstosumzero(uint8_t *, uint8_t, uint8_t); -STATIC void sumzerotodigits(int64_t, uint8_t, uint8_t, uint8_t *); +STATIC bool isperm(size_t n, const uint8_t [n]); +STATIC int64_t permtoindex(size_t n, const uint8_t [n]); +STATIC void indextoperm(int64_t, size_t n, uint8_t [n]); +STATIC int permsign(size_t n, const uint8_t [n]); +STATIC int64_t digitstosumzero(size_t n, const uint8_t [n], uint8_t); +STATIC void sumzerotodigits(int64_t, size_t n, uint8_t, uint8_t [n]); STATIC int64_t factorial(int64_t n) @@ -32,13 +32,13 @@ factorial(int64_t n) } STATIC bool -isperm(uint8_t *a, int64_t n) +isperm(size_t n, const uint8_t a[n]) { - int64_t i; + size_t i; bool aux[FACTORIAL_MAX+1]; - if (n > FACTORIAL_MAX) { - LOG("Error: won't compute 'isperm()' for n=%" PRId64 " because" + if (n > (size_t)FACTORIAL_MAX) { + LOG("Error: won't compute 'isperm()' for n=%zu because" " it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); return false; } @@ -60,18 +60,18 @@ isperm(uint8_t *a, int64_t n) } STATIC int64_t -permtoindex(uint8_t *a, int64_t n) +permtoindex(size_t n, const uint8_t a[n]) { - int64_t i, j, c, ret; + size_t i, j; + int64_t c, ret; - if (n > FACTORIAL_MAX) { - LOG("Error: won't compute 'permtoindex()' for n=%" PRId64 - " because it is larger than %" PRId64 "\n", - n, FACTORIAL_MAX); + if (n > (size_t)FACTORIAL_MAX) { + LOG("Error: won't compute 'permtoindex()' for n=%zu because " + "it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); return -1; } - if (!isperm(a, n)) + if (!isperm(n, a)) return -1; for (i = 0, ret = 0; i < n; i++) { @@ -84,15 +84,15 @@ permtoindex(uint8_t *a, int64_t n) } STATIC void -indextoperm(int64_t p, int64_t n, uint8_t *r) +indextoperm(int64_t p, size_t n, uint8_t r[n]) { - int64_t i, j, c; + int64_t c; + size_t i, j; uint8_t a[FACTORIAL_MAX+1]; if (n > FACTORIAL_MAX) { - LOG("Error: won't compute 'permtoindex()' for n=%" PRId64 - " because it is larger than %" PRId64 "\n", - n, FACTORIAL_MAX); + LOG("Error: won't compute 'indextoperm()' for n=%zu because " + "it is larger than %" PRId64 "\n", n, FACTORIAL_MAX); goto indextoperm_error; } @@ -109,7 +109,7 @@ indextoperm(int64_t p, int64_t n, uint8_t *r) p %= factorial(n-i-1); } - if (!isperm(r, n)) + if (!isperm(n, r)) goto indextoperm_error; return; @@ -119,10 +119,9 @@ indextoperm_error: } STATIC int -permsign(uint8_t *a, int64_t n) +permsign(size_t n, const uint8_t a[n]) { - int i, j; - uint8_t ret; + size_t i, j, ret; for (i = 0, ret = 0; i < n; i++) for (j = i+1; j < n; j++) @@ -132,13 +131,13 @@ permsign(uint8_t *a, int64_t n) } STATIC int64_t -digitstosumzero(uint8_t *a, uint8_t n, uint8_t b) +digitstosumzero(size_t n, const uint8_t a[n], uint8_t b) { int64_t ret, p; - uint8_t i, sum; + size_t i, sum; if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) { - LOG("Won't compute 'sumzero' for n=%" PRIu8 "and b=%" PRIu8 + LOG("Won't compute 'sumzero' for n=%zu and b=%" PRIu8 " (use n=8 b=3 or n=12 b=2)\n", n, b); return -1; } @@ -162,15 +161,15 @@ digitstosumzero(uint8_t *a, uint8_t n, uint8_t b) } STATIC void -sumzerotodigits(int64_t d, uint8_t n, uint8_t b, uint8_t *a) +sumzerotodigits(int64_t d, size_t n, uint8_t b, uint8_t a[n]) { uint8_t sum; - int64_t i; + size_t i; if (!((n == 8 && b == 3 ) || (n == 12 && b == 2))) { LOG("Won't compute 'digits' for n=%" PRIu8 "and b=%" PRIu8 " (use n=8 b=3 or n=12 b=2)\n"); - goto digitstosumzero_error; + goto sumzerotodigits_error; } for (i = 1, sum = 0; i < n; i++, d /= (int64_t)b) { @@ -181,6 +180,6 @@ sumzerotodigits(int64_t d, uint8_t n, uint8_t b, uint8_t *a) return; -digitstosumzero_error: +sumzerotodigits_error: memset(a, UINT8_ERROR, n); } diff --git a/test/010_math_permtoindex/permtoindex_tests.c b/test/010_math_permtoindex/permtoindex_tests.c @@ -1,6 +1,6 @@ #include "../test.h" -int64_t permtoindex(uint8_t *, int64_t); +int64_t permtoindex(size_t n, const uint8_t [n]); void run(void) { char str[STRLENMAX]; @@ -14,6 +14,6 @@ void run(void) { a[i] = atoi(str); } - p = permtoindex(a, n); + p = permtoindex(n, a); printf("%" PRId64 "\n", p); } diff --git a/test/011_math_indextoperm/indextoperm_tests.c b/test/011_math_indextoperm/indextoperm_tests.c @@ -1,6 +1,6 @@ #include "../test.h" -void indextoperm(int64_t, int64_t, uint8_t *); +void indextoperm(int64_t, size_t n, uint8_t [n]); void run(void) { char str[STRLENMAX]; diff --git a/test/012_math_permsign/permsign_tests.c b/test/012_math_permsign/permsign_tests.c @@ -1,6 +1,6 @@ #include "../test.h" -int permsign(uint8_t *, int64_t); +int permsign(size_t n, const uint8_t [n]); void run(void) { char str[STRLENMAX]; @@ -16,6 +16,6 @@ void run(void) { a[i] = atoi(str); } - p = permsign(a, n); + p = permsign(n, a); printf("%d\n", p); } diff --git a/test/013_math_digitstosumzero/digitstosumzero_tests.c b/test/013_math_digitstosumzero/digitstosumzero_tests.c @@ -1,10 +1,11 @@ #include "../test.h" -int64_t digitstosumzero(uint8_t *, uint8_t, uint8_t); +int64_t digitstosumzero(size_t n, uint8_t [n], uint8_t); void run(void) { char str[STRLENMAX]; - uint8_t i, n, b, a[100]; + uint8_t i, b, a[100]; + size_t n; int64_t p; fgets(str, STRLENMAX, stdin); @@ -16,6 +17,6 @@ void run(void) { a[i] = atoi(str); } - p = digitstosumzero(a, n, b); + p = digitstosumzero(n, a, b); printf("%" PRId64 "\n", p); } diff --git a/test/014_math_sumzerotodigits/sumzerotodigits.c b/test/014_math_sumzerotodigits/sumzerotodigits.c @@ -1,6 +1,6 @@ #include "../test.h" -void sumzerotodigits(int64_t, uint8_t, uint8_t, uint8_t *); +void sumzerotodigits(int64_t, size_t n, uint8_t, uint8_t [n]); void run(void) { char str[STRLENMAX]; diff --git a/test/032_invertmoves/invertmoves_tests.c b/test/032_invertmoves/invertmoves_tests.c @@ -3,8 +3,8 @@ #define MAXMOVES 20 int64_t readmoves(const char *, int, uint8_t *); -void writemoves(uint8_t *, int, uint64_t, char *); -void invertmoves(uint8_t *, uint8_t, uint8_t *); +void writemoves(size_t n, uint8_t [n], size_t m, char [m]); +void invertmoves(size_t n, const uint8_t [n], uint8_t [n]); void run(void) { char movestr[STRLENMAX], outstr[STRLENMAX]; @@ -14,8 +14,8 @@ void run(void) { fgets(movestr, STRLENMAX, stdin); c = readmoves(movestr, MAXMOVES, moves); - invertmoves(moves, c, ret); - writemoves(ret, c, STRLENMAX, outstr); + invertmoves(c, moves, ret); + writemoves(c, ret, STRLENMAX, outstr); printf("%s\n", outstr); } diff --git a/test/080_allowednext/allowednext_tests.c b/test/080_allowednext/allowednext_tests.c @@ -1,6 +1,6 @@ #include "../test.h" -bool allowednextmove(uint8_t *, uint8_t); +bool allowednextmove(size_t n, const uint8_t [n]); static char *moves[] = { "U", "U2", "U'", @@ -31,5 +31,5 @@ void run(void) { n > 2 ? moves[m[n-3]] : "-", n > 1 ? moves[m[n-2]] : "-", n > 0 ? moves[m[n-1]] : "-"); - printf("%s\n", allowednextmove(m, n) ? "true" : "false"); + printf("%s\n", allowednextmove(n, m) ? "true" : "false"); } diff --git a/test/test.h b/test/test.h @@ -25,7 +25,7 @@ bool isconsistent(cube_t); bool issolvable(cube_t); bool issolved(cube_t); cube_t readcube(char *, char *); -int64_t writecube(char *, cube_t, uint64_t, char *); +int64_t writecube(char *, cube_t, size_t n, char [n]); /* Test function to be implemented by all tests */ void run(void);