h48

A prototype for an optimal Rubik's cube solver, work in progress.
git clone https://git.tronto.net/h48
Download | Log | Files | Refs | README | LICENSE

commit 8a91354f7b94c669c77fe628a81f9bfe9f599ef0
parent 7dbd34574f629cacf3b89292d2a06ad0ae612f26
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date:   Mon, 14 Oct 2024 00:05:43 +0200

Interface changes, progress with python

Diffstat:
MMakefile | 2+-
Mpython/nissy_module.c | 191++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mshell/shell.c | 45+++++++++++++--------------------------------
Msrc/core/cube.h | 4++--
Msrc/core/io_moves.h | 9+++++----
Msrc/core/moves.h | 7-------
Msrc/nissy.c | 115++++++++++++++++++++++++-------------------------------------------------------
Msrc/nissy.h | 130++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/solvers/h48/solve.h | 10++++++----
Msrc/solvers/h48/solve_multithread.h | 10++++++----
Mtools/100_checkdata/checkdata.c | 2+-
Mtools/200_stats_tables_h48/stats_tables_h48.c | 16++++++++--------
Mtools/300_solve_small/solve_small.c | 3++-
Mtools/nissy_extra.h | 5+++--
Mtools/tool.h | 25+++++++++++++------------
15 files changed, 330 insertions(+), 244 deletions(-)

diff --git a/Makefile b/Makefile @@ -40,7 +40,7 @@ shelltest: debugshell ./shell/test.sh python: nissy.o - ${CC} -shared ${PYTHON3_INCLUDES} -o nissy_python_module.so \ + ${CC} ${CFLAGS} -shared ${PYTHON3_INCLUDES} -o nissy_python_module.so \ nissy.o python/nissy_module.c .PHONY: all clean test tool debugtool shell debugshell shelltest python diff --git a/python/nissy_module.c b/python/nissy_module.c @@ -1,34 +1,201 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> +#include <stdbool.h> #include "../src/nissy.h" -/* TODO from here */ +#define MAX_CUBE_STR_LEN 1024 /* Update when adding formats */ -static PyObject *compose(PyObject *self, PyObject *args) { +static bool +check_error(long long err) +{ + char err_string[255]; + + switch (err) { + case NISSY_OK: /* Fallthrough */ + case NISSY_WARNING_UNSOLVABLE: + return true; + case NISSY_ERROR_INVALID_CUBE: + case NISSY_ERROR_UNSOLVABLE_CUBE: /* Fallthrough */ + case NISSY_ERROR_INVALID_MOVES: + case NISSY_ERROR_INVALID_TRANS: + case NISSY_ERROR_INVALID_FORMAT: + case NISSY_ERROR_INVALID_SOLVER: + case NISSY_ERROR_NULL_POINTER: + case NISSY_ERROR_BUFFER_SIZE: + case NISSY_ERROR_DATA: + case NISSY_ERROR_OPTIONS: + case NISSY_ERROR_UNKNOWN: + default: + sprintf(err_string, "Error from libnissy (%lld)", err); + PyErr_SetString(PyExc_Exception, err_string); + return false; + } + +} + +static PyObject * +string_result(long long err, const char *result) +{ + return check_error(err) ? PyUnicode_FromString(result) : NULL; +} + +static PyObject * +string_result_free(long long err, char *result) +{ + PyObject *ret; + + ret = PyUnicode_FromString(result); + free(result); + + return check_error(err) ? ret : NULL; +} + +static PyObject * +long_result(long long result) +{ + check_error(result); + return PyLong_FromLong(result); +} + +static PyObject * +compose(PyObject *self, PyObject *args) +{ + long long err; const char *cube, *permutation; char result[NISSY_SIZE_B32]; if (!PyArg_ParseTuple(args, "ss", &cube, &permutation)) return NULL; - nissy_compose(cube, permutation, result); - return PyUnicode_FromString(result); + err = nissy_compose(cube, permutation, result); + return string_result(err, result); +} + +static PyObject * +inverse(PyObject *self, PyObject *args) +{ + long long err; + const char *cube; + char result[NISSY_SIZE_B32]; + + if (!PyArg_ParseTuple(args, "s", &cube)) + return NULL; + + err = nissy_inverse(cube, result); + return string_result(err, result); +} + +static PyObject * +applymoves(PyObject *self, PyObject *args) +{ + long long err; + const char *cube, *moves; + char result[NISSY_SIZE_B32]; + + if (!PyArg_ParseTuple(args, "ss", &cube, &moves)) + return NULL; + + err = nissy_applymoves(cube, moves, result); + return string_result(err, result); +} + +static PyObject * +applytrans(PyObject *self, PyObject *args) +{ + long long err; + const char *cube, *trans; + char result[NISSY_SIZE_B32]; + + if (!PyArg_ParseTuple(args, "ss", &cube, &trans)) + return NULL; + + err = nissy_applytrans(cube, trans, result); + return string_result(err, result); +} + +static PyObject * +convert(PyObject *self, PyObject *args) +{ + long long err; + const char *fin, *fout, *cube; + char result[MAX_CUBE_STR_LEN]; + + if (!PyArg_ParseTuple(args, "sss", &fin, &fout, &cube)) + return NULL; + + err = nissy_convert(fin, fout, cube, MAX_CUBE_STR_LEN, result); + return string_result(err, result); +} + +static PyObject * +getcube(PyObject *self, PyObject *args) +{ + long long ep, eo, cp, co, err; + const char *options; + char result[NISSY_SIZE_B32]; + + if (!PyArg_ParseTuple(args, "LLLLs", &ep, &eo, &cp, &co, &options)) + return NULL; + + err = nissy_getcube(ep, eo, cp, co, options, result); + return string_result(err, result); +} + +static PyObject * +datasize(PyObject *self, PyObject *args) +{ + long long result; + const char *solver; + + if (!PyArg_ParseTuple(args, "s", &solver)) + return NULL; + + result = nissy_datasize(solver); + return long_result(result); } -static PyMethodDef NissyMethods[] = { - { "compose", compose, METH_VARARGS, "Compose two cubes." }, +/* TODO: gendata, checkdata and solve */ + +static PyMethodDef nissy_methods[] = { + { "compose", compose, METH_VARARGS, NULL }, + { "inverse", inverse, METH_VARARGS, NULL }, + { "applymoves", applymoves, METH_VARARGS, NULL }, + { "applytrans", applytrans, METH_VARARGS, NULL }, + { "convert", convert, METH_VARARGS, NULL }, + { "getcube", getcube, METH_VARARGS, NULL }, + { "datasize", datasize, METH_VARARGS, NULL }, { NULL, NULL, 0, NULL } }; static struct PyModuleDef nissy_python_module = { - PyModuleDef_HEAD_INIT, - "nissy", - NULL, - -1, - NissyMethods + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "nissy", + .m_doc = NULL, + .m_size = -1, + .m_methods = nissy_methods, + .m_slots = NULL, + .m_traverse = NULL, + .m_clear = NULL, + .m_free = NULL }; +static void +log_stdout(const char *str, ...) +{ + va_list args; + + va_start(args, str); + vfprintf(stderr, str, args); + va_end(args); +} + PyMODINIT_FUNC PyInit_nissy_python_module(void) { - return PyModule_Create(&nissy_python_module); + PyObject *module; + + nissy_setlogger(log_stdout); + module = PyModule_Create(&nissy_python_module); + PyModule_AddStringConstant(module, "solvedcube", NISSY_SOLVED_CUBE); + + return module; } diff --git a/shell/shell.c b/shell/shell.c @@ -50,10 +50,10 @@ typedef struct { char *str_trans; char *str_solver; char *str_nisstype; - int8_t minmoves; - int8_t maxmoves; - int8_t optimal; - int64_t maxsolutions; + unsigned int minmoves; + unsigned int maxmoves; + unsigned int optimal; + unsigned int maxsolutions; } args_t; static int64_t compose_exec(args_t *); @@ -70,8 +70,7 @@ static int64_t solve_scramble_exec(args_t *); static int64_t help_exec(args_t *); static int parse_args(int, char **, args_t *); -static bool parse_int8(char *, int8_t *); -static bool parse_int64(char *, int64_t *); +static bool parse_uint(char *, unsigned int *); static bool set_cube(int, char **, args_t *); static bool set_cube_perm(int, char **, args_t *); @@ -292,14 +291,8 @@ applytrans_exec(args_t *args) static int64_t frommoves_exec(args_t *args) { - char result[22]; - int64_t ret; - - ret = nissy_frommoves(args->str_moves, result); - if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE) - printf("%s\n", result); - - return ret; + sprintf(args->cube, NISSY_SOLVED_CUBE); + return applymoves_exec(args); } static int64_t @@ -591,21 +584,9 @@ parse_args(int argc, char **argv, args_t *args) } bool -parse_int8(char *argv, int8_t *result) -{ - bool noerror; - int64_t n; - - noerror = parse_int64(argv, &n); - *result = (int8_t)n; - - return noerror && n >= INT8_MIN && n <= INT8_MAX; -} - -bool -parse_int64(char *argv, int64_t *result) +parse_uint(char *argv, int8_t *result) { - *result = strtoll(argv, NULL, 10); + *result = strtol(argv, NULL, 10); /* TODO: figure out how errno works and use it */ return true; @@ -704,25 +685,25 @@ set_str_nisstype(int argc, char **argv, args_t *args) static bool set_minmoves(int argc, char **argv, args_t *args) { - return parse_int8(argv[0], &args->minmoves); + return parse_uint(argv[0], &args->minmoves); } static bool set_maxmoves(int argc, char **argv, args_t *args) { - return parse_int8(argv[0], &args->maxmoves); + return parse_uint(argv[0], &args->maxmoves); } static bool set_optimal(int argc, char **argv, args_t *args) { - return parse_int8(argv[0], &args->optimal); + return parse_uint(argv[0], &args->optimal); } static bool set_maxsolutions(int argc, char **argv, args_t *args) { - return parse_int64(argv[0], &args->maxsolutions); + return parse_uint(argv[0], &args->maxsolutions); } void diff --git a/src/core/cube.h b/src/core/cube.h @@ -4,7 +4,7 @@ STATIC bool isconsistent(cube_t); STATIC bool issolvable(cube_t); STATIC bool issolved(cube_t); STATIC bool iserror(cube_t); -STATIC void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *); +STATIC void getcube_fix(long long *, long long *, long long *, long long *); STATIC cube_t getcube(int64_t, int64_t, int64_t, int64_t); /* This is used only in tests, use SOLVED_CUBE directly everywhere else */ @@ -128,7 +128,7 @@ iserror(cube_t cube) } STATIC void -getcube_fix(int64_t *ep, int64_t *eo, int64_t *cp, int64_t *co) +getcube_fix(long long *ep, long long *eo, long long *cp, long long *co) { uint8_t e[12], c[8], coarr[8]; diff --git a/src/core/io_moves.h b/src/core/io_moves.h @@ -43,6 +43,7 @@ writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) { int i; uint64_t len; + int64_t written; const char *s; char *b; @@ -51,16 +52,16 @@ writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) return NISSY_ERROR_BUFFER_SIZE; } - for (i = 0, b = buf; i < n; i++, b++, buf_size--) { + for (i = 0, b = buf, written = 0; i < n; i++, b++, written++) { s = movestr[m[i]]; len = strlen(s); - if (len >= buf_size) { + if (len + written >= buf_size) { LOG("Error: the given buffer is too small for " "writing the given moves.\n"); goto writemoves_error; } memcpy(b, s, len); - buf_size -= len; + written += len; b += len; *b = ' '; } @@ -69,7 +70,7 @@ writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) b--; /* Remove last space */ *b = '\0'; - return buf_size; + return written; writemoves_error: *buf = '\0'; diff --git a/src/core/moves.h b/src/core/moves.h @@ -15,7 +15,6 @@ STATIC void invertmoves(uint8_t *, uint8_t, uint8_t *); STATIC int readmoves(const char *, int, uint8_t *); STATIC cube_t applymoves(cube_t, const char *); -STATIC cube_t frommoves(const char *); #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ RET_ERROR, ARG_ACTION) \ @@ -246,9 +245,3 @@ applymoves(cube_t cube, const char *buf) return cube; } - -STATIC cube_t -frommoves(const char *buf) -{ - return applymoves(SOLVED_CUBE, buf); -} diff --git a/src/nissy.c b/src/nissy.c @@ -12,7 +12,7 @@ #include "solvers/solvers.h" int parse_h48_solver(const char *, uint8_t [static 1], uint8_t [static 1]); -STATIC int64_t write_result(cube_t, char [static NISSY_SIZE_B32]); +STATIC long long write_result(cube_t, char [static NISSY_SIZE_B32]); STATIC bool distribution_equal(const uint64_t [static INFO_DISTRIBUTION_LEN], const uint64_t [static INFO_DISTRIBUTION_LEN], uint8_t); STATIC bool checkdata(const char *, const tableinfo_t *); @@ -20,7 +20,7 @@ STATIC bool checkdata(const char *, const tableinfo_t *); #define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F } struct { char *option; - void (*fix)(int64_t *, int64_t *, int64_t *, int64_t *); + void (*fix)(long long *, long long *, long long *, long long *); } getcube_options[] = { GETCUBE_OPTIONS("fix", getcube_fix), GETCUBE_OPTIONS(NULL, NULL) @@ -105,7 +105,7 @@ distribution_equal( return wrong == 0; } -STATIC int64_t +STATIC long long write_result(cube_t cube, char result[static NISSY_SIZE_B32]) { writecube("B32", cube, NISSY_SIZE_B32, result); @@ -118,7 +118,7 @@ write_result(cube_t cube, char result[static NISSY_SIZE_B32]) return NISSY_OK; } -int64_t +long long nissy_compose( const char cube[static NISSY_SIZE_B32], const char permutation[static NISSY_SIZE_B32], @@ -126,7 +126,7 @@ nissy_compose( ) { cube_t c, p, res; - int64_t err; + long long err; c = readcube("B32", cube); @@ -159,14 +159,14 @@ nissy_compose_error: return err; } -int64_t +long long nissy_inverse( const char cube[static NISSY_SIZE_B32], char result[static NISSY_SIZE_B32] ) { cube_t c, res; - int64_t err; + long long err; c = readcube("B32", cube); @@ -191,7 +191,7 @@ nissy_inverse_error: return err; } -int64_t +long long nissy_applymoves( const char cube[static NISSY_SIZE_B32], const char *moves, @@ -199,7 +199,7 @@ nissy_applymoves( ) { cube_t c, res; - int64_t err; + long long err; if (moves == NULL) { LOG("Error: 'moves' argument is NULL\n"); @@ -230,7 +230,7 @@ nissy_applymoves_error: return err; } -int64_t +long long nissy_applytrans( const char cube[static NISSY_SIZE_B32], const char transformation[static NISSY_SIZE_TRANSFORMATION], @@ -238,7 +238,7 @@ nissy_applytrans( ) { cube_t c, res; - int64_t err; + long long err; c = readcube("B32", cube); @@ -263,47 +263,17 @@ nissy_applytrans_error: return err; } -int64_t -nissy_frommoves( - const char *moves, - char result[static NISSY_SIZE_B32] -) -{ - cube_t res; - int64_t err; - - if (moves == NULL) { - LOG("Error: 'moves' argument is NULL\n"); - err = NISSY_ERROR_NULL_POINTER; - goto nissy_frommoves_error; - } - - res = applymoves(SOLVED_CUBE, moves); - - if (!isconsistent(res)) { - /* Assume we got a reasonable error message from applymoves */ - err = NISSY_ERROR_INVALID_MOVES; - goto nissy_frommoves_error; - } - - return write_result(res, result); - -nissy_frommoves_error: - writecube("B32", ZERO_CUBE, NISSY_SIZE_B32, result); - return err; -} - -int64_t +long long nissy_convert( const char *format_in, const char *format_out, const char *cube_string, - uint64_t result_size, + unsigned result_size, char result[result_size] ) { cube_t c; - int64_t err; + long long err; if (format_in == NULL) { LOG("Error: 'format_in' argument is NULL\n"); @@ -337,12 +307,12 @@ nissy_convert_error: return err; } -int64_t +long long nissy_getcube( - int64_t ep, - int64_t eo, - int64_t cp, - int64_t co, + long long ep, + long long eo, + long long cp, + long long co, const char *options, char result[static NISSY_SIZE_B32] ) @@ -371,7 +341,7 @@ nissy_getcube( return write_result(c, result); } -int64_t +long long nissy_datasize( const char *solver ) @@ -385,7 +355,7 @@ nissy_datasize( return nissy_gendata(solver, 0, NULL); } -int64_t +long long nissy_datainfo( uint64_t data_size, const char data[data_size], @@ -394,7 +364,7 @@ nissy_datainfo( { uint8_t i; tableinfo_t info; - int64_t ret; + long long ret; ret = readtableinfo(data_size, data, &info); if (ret != 0) @@ -434,10 +404,10 @@ nissy_datainfo( return NISSY_OK; } -int64_t +long long nissy_gendata( const char *solver, - uint64_t data_size, + unsigned long long data_size, char data[data_size] ) { @@ -463,9 +433,9 @@ nissy_gendata( } } -int64_t +long long nissy_checkdata( - uint64_t data_size, + unsigned long long data_size, const char data[data_size] ) { @@ -488,18 +458,18 @@ nissy_checkdata( return NISSY_OK; } -int64_t +long long nissy_solve( const char cube[static NISSY_SIZE_B32], const char *solver, - uint8_t nissflag, - int8_t minmoves, - int8_t maxmoves, - int64_t maxsols, - int8_t optimal, - uint64_t data_size, + unsigned nissflag, + unsigned minmoves, + unsigned maxmoves, + unsigned maxsols, + int optimal, + unsigned long long data_size, const char data[data_size], - uint64_t sols_size, + unsigned sols_size, char sols[sols_size] ) { @@ -524,21 +494,6 @@ nissy_solve( return NISSY_ERROR_UNSOLVABLE_CUBE; } - if (minmoves < 0) { - LOG("solve: 'minmoves' is negative, setting it to 0\n"); - minmoves = 0; - } - - if (maxmoves < 0) { - LOG("solve: 'maxmoves' is negative, setting it to 20\n"); - maxmoves = 20; - } - - if (maxsols < 0) { - LOG("solve: 'maxsols' is negative, stopping\n"); - return NISSY_ERROR_OPTIONS; - } - if (maxsols == 0) { LOG("solve: 'maxsols' is 0, returning no solution\n"); return 0; @@ -565,7 +520,7 @@ nissy_solve( } } -int64_t +long long nissy_setlogger( void (*log)(const char *, ...) ) diff --git a/src/nissy.h b/src/nissy.h @@ -1,13 +1,6 @@ /* This is libnissy (temporarily also known as h48), a Rubik's cube library. -If you include this file, you should also use the following includes: - -#include <inttypes.h> -#include <stdarg.h> -#include <stdbool.h> -#include <string.h> - All the functions return 0 or a positive integer in case of success and a negative integer in case of error, unless otherwise specified. See at the bottom of this file for the list of error codes and their meaning. @@ -24,20 +17,29 @@ A transformation must be given in the format for example 'rotation UF' or 'mirrored BL'. */ + +/* Constants *****************************************************************/ + /* Some constants for size for I/O buffers */ -#define NISSY_SIZE_B32 UINT64_C(22) -#define NISSY_SIZE_H48 UINT64_C(88) -#define NISSY_SIZE_TRANSFORMATION UINT64_C(12) +#define NISSY_SIZE_B32 22U +#define NISSY_SIZE_H48 88U +#define NISSY_SIZE_TRANSFORMATION 12U /* Flags for NISS options */ -#define NISSY_NISSFLAG_NORMAL UINT8_C(1) -#define NISSY_NISSFLAG_INVERSE UINT8_C(2) -#define NISSY_NISSFLAG_MIXED UINT8_C(4) -#define NISSY_NISSFLAG_LINEAR \ +#define NISSY_NISSFLAG_NORMAL 1U +#define NISSY_NISSFLAG_INVERSE 2U +#define NISSY_NISSFLAG_MIXED 4U +#define NISSY_NISSFLAG_LINEAR \ (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE) -#define NISSY_NISSFLAG_ALL \ +#define NISSY_NISSFLAG_ALL \ (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED) +/* The solved cube in B32 format */ +#define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL" + + +/* Library functions *********************************************************/ + /* Apply the secod argument as a permutation on the first argument. @@ -56,7 +58,7 @@ Return values: NISSY_ERROR_INVALID_CUBE - At least one of the given cubes is invalid. NISSY_ERROR_UNKNOWN - An unknown error occurred. */ -int64_t nissy_compose( +long long nissy_compose( const char cube[static NISSY_SIZE_B32], const char permutation[static NISSY_SIZE_B32], char result[static NISSY_SIZE_B32] @@ -77,7 +79,7 @@ Return values: NISSY_ERROR_INVALID_CUBE - The given cube is invalid. NISSY_ERROR_UNKNOWN - An unknown error occurred. */ -int64_t nissy_inverse( +long long nissy_inverse( const char cube[static NISSY_SIZE_B32], char result[static NISSY_SIZE_B32] ); @@ -99,7 +101,7 @@ Return values: NISSY_ERROR_INVALID_MOVES - The given moves are invalid. NISSY_ERROR_NULL_POINTER - The 'moves' argument is NULL. */ -int64_t nissy_applymoves( +long long nissy_applymoves( const char cube[static NISSY_SIZE_B32], const char *moves, char result[static NISSY_SIZE_B32] @@ -120,33 +122,13 @@ Return values: NISSY_ERROR_INVALID_CUBE - The given cube is invalid. NISSY_ERROR_INVALID_TRANS - The given transformation is invalid. */ -int64_t nissy_applytrans( +long long nissy_applytrans( const char cube[static NISSY_SIZE_B32], const char transformation[static NISSY_SIZE_TRANSFORMATION], char result[static NISSY_SIZE_B32] ); /* -Apply the given moves to the solved cube. - -Parameters: - moves - The moves to be applied to the solved cube. Must be a - NULL-terminated string. - result - Return parameter for the resulting cube, in B32 format. - -Return values: - NISSY_OK - The moves were performed succesfully. - NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is - probably due to an unknown internal error. - NISSY_ERROR_INVALID_MOVES - The given moves are invalid. - NISSY_ERROR_NULL_POINTER - The 'moves' argument is NULL. -*/ -int64_t nissy_frommoves( - const char *moves, - char result[static NISSY_SIZE_B32] -); - -/* Convert the given cube between the two given formats. Parameters: @@ -165,11 +147,11 @@ Return values: NISSY_ERROR_NULL_POINTER - At least one of 'format_in', 'format_out' or 'cube_string' arguments is NULL. */ -int64_t nissy_convert( +long long nissy_convert( const char *format_in, const char *format_out, const char *cube_string, - uint64_t result_size, + unsigned result_size, char result[result_size] ); @@ -192,11 +174,11 @@ Return values: NISSY_WARNING_UNSOLVABLE - The resulting cube is unsolvable. NISSY_ERROR_OPTIONS - One or more of the given parameters is invalid. */ -int64_t nissy_getcube( - int64_t ep, - int64_t eo, - int64_t cp, - int64_t co, +long long nissy_getcube( + long long ep, + long long eo, + long long cp, + long long co, const char *options, char result[static NISSY_SIZE_B32] ); @@ -214,7 +196,7 @@ Return values: NISSY_ERROR_UNKNOWN - An unknown error occurred. Any value >= 0 - The size of the data, in bytes. */ -int64_t nissy_datasize( +long long nissy_datasize( const char *solver ); @@ -233,9 +215,9 @@ Return values: NISSY_ERROR_UNKNOWN - An error occurred while generating the data. Any value >= 0 - The size of the data, in bytes. */ -int64_t nissy_gendata( +long long nissy_gendata( const char *solver, - uint64_t data_size, + unsigned long long data_size, char data[data_size] ); @@ -250,8 +232,8 @@ Return values: NISSY_OK - The data is valid. NISSY_ERROR_DATA - The data is invalid. */ -int64_t nissy_checkdata( - uint64_t data_size, +long long nissy_checkdata( + unsigned long long data_size, const char data[data_size] ); @@ -284,17 +266,17 @@ Return values: NISSY_ERROR_NULL_POINTER - The 'solver' argument is null. Any value >= 0 - The number of solutions found. */ -int64_t nissy_solve( +long long nissy_solve( const char cube[static NISSY_SIZE_B32], const char *solver, - uint8_t nissflag, - int8_t minmoves, - int8_t maxmoves, - int64_t maxsolutions, - int8_t optimal, - uint64_t data_size, + unsigned nissflag, + unsigned minmoves, + unsigned maxmoves, + unsigned maxsolutions, + int optimal, + unsigned long long data_size, const char data[data_size], - uint64_t sols_size, + unsigned sols_size, char sols[sols_size] ); @@ -308,18 +290,18 @@ Return values: NISSY_OK - Logger set succesfully. No warning or error is goind to be given if the logger is NULL or invalid. */ -int64_t nissy_setlogger( +long long nissy_setlogger( void (*logger_function)(const char *, ...) ); -/* Error codes */ +/* Error codes ***************************************************************/ /* The value NISSY_OK denotes a success. If returned by solve, it means that no solution has been found. */ -#define NISSY_OK INT64_C(0) +#define NISSY_OK 0LL /* The value NISSY_WARNING_UNSOLVABLE is a warning. It means that the @@ -327,44 +309,44 @@ operation was completed succesfully, but the resulting cube is in an unsolvable state. This could be intended, for example if the user has provided an unsolvable cube as input. */ -#define NISSY_WARNING_UNSOLVABLE INT64_C(-1) +#define NISSY_WARNING_UNSOLVABLE -1LL /* The value NISSY_ERROR_INVALID_CUBE means that the provided cube is invalid. It could be written in an unknown format, or in a format different from what specified, or simply ill-formed. */ -#define NISSY_ERROR_INVALID_CUBE INT64_C(-10) +#define NISSY_ERROR_INVALID_CUBE -10LL /* The value NISSY_ERROR_UNSOLVABLE_CUBE means that the provided cube is in an unsolvable state. */ -#define NISSY_ERROR_UNSOLVABLE_CUBE INT64_C(-11) +#define NISSY_ERROR_UNSOLVABLE_CUBE -11LL /* The value NISSY_ERROR_INVALID_MOVES means that the given moves are invalid. */ -#define NISSY_ERROR_INVALID_MOVES INT64_C(-20) +#define NISSY_ERROR_INVALID_MOVES -20LL /* The value NISSY_ERROR_INVALID_TRANS means that the given transformation is invalid. */ -#define NISSY_ERROR_INVALID_TRANS INT64_C(-30) +#define NISSY_ERROR_INVALID_TRANS -30LL /* The value NISSY_ERROR_INVALID_FORMAT means that the given format is not known. */ -#define NISSY_ERROR_INVALID_FORMAT INT64_C(-40) +#define NISSY_ERROR_INVALID_FORMAT -40LL /* The value NISSY_ERROR_INVALID_SOLVER means that the given solver is not known. */ -#define NISSY_ERROR_INVALID_SOLVER INT64_C(-50) +#define NISSY_ERROR_INVALID_SOLVER -50LL /* The value NISSY_ERROR_NULL_POINTER means that one of the provided pointer @@ -372,32 +354,32 @@ arguments is NULL. For example, it may be returned by solve when called with a solver that requires some pre-computed data, but the provided data is NULL. */ -#define NISSY_ERROR_NULL_POINTER INT64_C(-60) +#define NISSY_ERROR_NULL_POINTER -60LL /* The value NISSY_ERROR_BUFFER_SIZE means that one of the buffers provided is too small. For example, it could be too small to hold the result or too small to hold the data generated by gendata. */ -#define NISSY_ERROR_BUFFER_SIZE INT64_C(-61) +#define NISSY_ERROR_BUFFER_SIZE -61LL /* The value NISSY_ERROR_DATA means that the provided data is invalid. For example, it may be returned by solve when called with incompatible solver and data arguments. */ -#define NISSY_ERROR_DATA INT64_C(-70) +#define NISSY_ERROR_DATA -70LL /* The value NISSY_ERROR_OPTIONS means that one or more of the given options are invalid. For example, it may be returned by solve when called with a negative maximum number of solutions. */ -#define NISSY_ERROR_OPTIONS INT64_C(-80) +#define NISSY_ERROR_OPTIONS -80LL /* The value NISSY_ERROR_UNKNOWN denotes an unexpected error. It probably means that there some bug in this library. If you can, report any error of this kind to sebastiano@tronto.net. Thanks! */ -#define NISSY_ERROR_UNKNOWN INT64_C(-999) +#define NISSY_ERROR_UNKNOWN -999LL diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h @@ -65,12 +65,13 @@ solve_h48_appendsolution(dfsarg_solveh48_t *arg) if (strl < 0) goto solve_h48_appendsolution_error; - *arg->nextsol += strl; - arg->solutions_size -= strl; + *arg->nextsol += strl-1; + arg->solutions_size -= strl-1; if (arg->npremoves) { **arg->nextsol = ' '; (*arg->nextsol)++; + arg->solutions_size--; invertmoves(arg->premoves, arg->npremoves, invertedpremoves); strl = writemoves(invertedpremoves, @@ -78,13 +79,14 @@ solve_h48_appendsolution(dfsarg_solveh48_t *arg) if (strl < 0) goto solve_h48_appendsolution_error; - *arg->nextsol += strl; - arg->solutions_size -= strl; + *arg->nextsol += strl-1; + arg->solutions_size -= strl-1; } LOG("Solution found: %s\n", solution); **arg->nextsol = '\n'; (*arg->nextsol)++; + arg->solutions_size--; (*arg->nsols)++; solve_h48_appendsolution_error: diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h @@ -36,13 +36,14 @@ solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) if (strl < 0) goto solve_h48_appendsolution_thread_error; - *arg->nextsol += strl; - arg->solutions_size -= strl; + *arg->nextsol += strl-1; + arg->solutions_size -= strl-1; if (arg->npremoves) { **arg->nextsol = ' '; (*arg->nextsol)++; + arg->solutions_size--; invertmoves(arg->premoves, arg->npremoves, invertedpremoves); strl = writemoves(invertedpremoves, @@ -50,13 +51,14 @@ solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) if (strl < 0) goto solve_h48_appendsolution_thread_error; - *arg->nextsol += strl; - arg->solutions_size -= strl; + *arg->nextsol += strl-1; + arg->solutions_size -= strl-1; } LOG("Solution found: %s\n", solution); **arg->nextsol = '\n'; (*arg->nextsol)++; + arg->solutions_size--; (*arg->nsols)++; solve_h48_appendsolution_thread_error: diff --git a/tools/100_checkdata/checkdata.c b/tools/100_checkdata/checkdata.c @@ -5,7 +5,7 @@ char *solver, *filename; static void run(void) { - int64_t size, result; + long long int size, result; char *buf; FILE *f; diff --git a/tools/200_stats_tables_h48/stats_tables_h48.c b/tools/200_stats_tables_h48/stats_tables_h48.c @@ -17,11 +17,11 @@ typedef struct { int64_t v[12][100]; } thread_arg_t; -uint64_t rand64(void) { - uint64_t i, ret; +uint64_t randll(void) { + long long int i, ret; for (i = 0, ret = 0; i < 64; i++) - ret |= (uint64_t)(rand() % 2) << i; + ret |= (long long int)(rand() % 2) << i; return ret; } @@ -30,16 +30,16 @@ static void * run_thread(void *arg) { char s[12], cube[22]; - int64_t ep, eo, cp, co; + long long int ep, eo, cp, co; int i, j; thread_arg_t *a = (thread_arg_t *)arg; for (i = 0; i < a->n; i++) { - ep = rand64(); - eo = rand64(); - cp = rand64(); - co = rand64(); + ep = randll(); + eo = randll(); + cp = randll(); + co = randll(); nissy_getcube(ep, eo, cp, co, "fix", cube); nissy_solve(cube, "h48stats", NISSY_NISSFLAG_NORMAL, 0, MAXMOVES, 1, -1, size, buf, 12, s); diff --git a/tools/300_solve_small/solve_small.c b/tools/300_solve_small/solve_small.c @@ -23,7 +23,8 @@ void run(void) { for (i = 0; scrambles[i] != NULL; i++) { printf("%d. %s\n", i+1, scrambles[i]); printf("Solving scramble %s\n", scrambles[i]); - if (nissy_frommoves(scrambles[i], cube) == -1) { + if (nissy_applymoves(NISSY_SOLVED_CUBE, scrambles[i], cube) + == -1) { printf("Invalid scramble\n"); continue; } diff --git a/tools/nissy_extra.h b/tools/nissy_extra.h @@ -10,5 +10,6 @@ for testing purposes only. size_t gendata_h48_derive(uint8_t, const void *, void *); int parse_h48_solver(const char *, uint8_t [static 1], uint8_t [static 1]); -int64_t nissy_datainfo(uint64_t, const char *, void (*)(const char *, ...)); -int64_t nissy_derivedata(const char *, const void *, void *); +long long int nissy_datainfo( + uint64_t, const char *, void (*)(const char *, ...)); +long long int nissy_derivedata(const char *, const void *, void *); diff --git a/tools/tool.h b/tools/tool.h @@ -13,8 +13,9 @@ static void log_stderr(const char *, ...); static void log_stdout(const char *, ...); static double timerun(void (*)(void)); static void writetable(const char *, int64_t, const char *); -static int64_t generatetable(const char *, char **); -static int64_t derivetable(const char *, const char *, const char *, char **); +static long long int generatetable(const char *, char **); +static long long int derivetable( + const char *, const char *, const char *, char **); static int getdata(const char *, char **, const char *); static void gendata_run(const char *, uint64_t[static 21]); static void derivedata_run( @@ -84,10 +85,10 @@ writetable(const char *buf, int64_t size, const char *filename) } } -static int64_t +static long long int generatetable(const char *solver, char **buf) { - int64_t size, gensize; + long long int size, gensize; size = nissy_datasize(solver); if (size == -1) { @@ -101,7 +102,7 @@ generatetable(const char *solver, char **buf) if (gensize != size) { printf("Error generating table"); if (gensize != -1) - printf(" (got %" PRId64 " bytes)", gensize); + printf(" (got %lld bytes)", gensize); printf("\n"); return -2; } @@ -109,7 +110,7 @@ generatetable(const char *solver, char **buf) return gensize; } -static int64_t +static long long int derivetable( const char *solver_large, const char *solver_small, @@ -118,7 +119,7 @@ derivetable( ) { uint8_t h, k; - int64_t size, gensize; + long long int size, gensize; char *fulltable; if (getdata(solver_large, &fulltable, filename_large) != 0) { @@ -161,7 +162,7 @@ getdata( char **buf, const char *filename ) { - int64_t size, sizeread; + long long int size, sizeread; FILE *f; if ((f = fopen(filename, "rb")) == NULL) { @@ -201,7 +202,7 @@ gendata_run( const char *solver, uint64_t expected[static 21] ) { - int64_t size; + long long int size; char *buf, filename[1024]; sprintf(filename, "tables/%s", solver); @@ -214,7 +215,7 @@ gendata_run( default: nissy_datainfo(size, buf, write_stdout); printf("\n"); - printf("Succesfully generated %" PRId64 " bytes. " + printf("Succesfully generated %lld bytes. " "See above for details on the tables.\n", size); /* TODO: check that the table is correct */ @@ -234,7 +235,7 @@ derivedata_run( const char *filename_small ) { - int64_t size; + long long int size; char *buf; buf = NULL; @@ -247,7 +248,7 @@ derivedata_run( default: nissy_datainfo(size, buf, write_stdout); printf("\n"); - printf("Succesfully generated %" PRId64 " bytes. " + printf("Succesfully generated %lld bytes. " "See above for details on the tables.\n", size); writetable(buf, size, filename_small);