nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

nissy.h (13707B)


      1 /*
      2 This is libnissy (temporarily also known as h48), a Rubik's cube library.
      3 
      4 All the functions return 0 or a positive integer in case of success and
      5 a negative integer in case of error, unless otherwise specified. See
      6 below for the list of error codes and their meaning.
      7 
      8 Cubes are passed as strings in the cccccccc=eeeeeeeeeeee=r format,
      9 see the README.md file for more information.
     10 
     11 Accepted moves are any of the following:
     12 U, D, R, L, F, B, Uw, Dw, Rw, Lw, Fw, Bw, M, S, E, x, y, z
     13 optionally followed by a 2, a ' or a 3.
     14 The standard NISS notation is also accepted: moves in parentheses () are
     15 inverted and used as premoves.
     16 
     17 A transformation must be given in the format
     18     (rotation|mirrored) (2 letters)
     19 for example 'rotation UF' or 'mirrored BL'.
     20 */
     21 
     22 
     23 /* Constants *****************************************************************/
     24 
     25 /* Some constants for size for I/O buffers */
     26 #define NISSY_SIZE_CUBE           24U
     27 #define NISSY_SIZE_TRANSFORMATION 12U
     28 #define NISSY_SIZE_SOLVE_STATS    10U
     29 #define NISSY_SIZE_DATAID         255U
     30 
     31 /* Flags for NISS options */
     32 #define NISSY_NISSFLAG_NORMAL  1U
     33 #define NISSY_NISSFLAG_INVERSE 2U
     34 #define NISSY_NISSFLAG_MIXED   4U
     35 #define NISSY_NISSFLAG_LINEAR \
     36     (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE)
     37 #define NISSY_NISSFLAG_ALL \
     38     (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED)
     39 
     40 /* Status for stopping / pausing / resuming a solver */
     41 #define NISSY_STATUS_RUN    0
     42 #define NISSY_STATUS_STOP   1
     43 #define NISSY_STATUS_PAUSE  2
     44 
     45 /* The solved cube */
     46 #define NISSY_SOLVED_CUBE "ABCDEFGH=ABCDEFGHIJKL=A"
     47 
     48 /* Error codes ***************************************************************/
     49 
     50 /*
     51 The value NISSY_OK denotes a success. If returned by solve, it means
     52 that no solution has been found.
     53 */
     54 #define NISSY_OK 0LL
     55 
     56 /*
     57 The value NISSY_WARNING_UNSOLVABLE is a warning. It means that the
     58 operation was completed succesfully, but the resulting cube is in an
     59 unsolvable state. This could be intended, for example if the user has
     60 provided an unsolvable cube as input.
     61 */
     62 #define NISSY_WARNING_UNSOLVABLE -1LL
     63 
     64 /*
     65 The value NISSY_ERROR_INVALID_CUBE means that the provided cube is
     66 invalid. It could be written in an unknown format, or be ill-formed.
     67 */
     68 #define NISSY_ERROR_INVALID_CUBE -10LL
     69 
     70 /*
     71 The value NISSY_ERROR_UNSOLVABLE_CUBE means that the provided cube is in
     72 an unsolvable state for the given solver. This could mean either that the
     73 cube is not solvable at all (for example in case it has a single twisted
     74 corner), or that it is not ready for the given step (for example if the
     75 caller wants to solve a DR finish without the cube being in DR state).
     76 */
     77 #define NISSY_ERROR_UNSOLVABLE_CUBE -11LL
     78 
     79 /*
     80 The value NISSY_ERROR_INVALID_MOVES means that the given moves are
     81 invalid.
     82 */
     83 #define NISSY_ERROR_INVALID_MOVES -20LL
     84 
     85 /*
     86 The value NISSY_ERROR_INVALID_TRANS means that the given transformation
     87 is invalid.
     88 */
     89 #define NISSY_ERROR_INVALID_TRANS -30LL
     90 
     91 /*
     92 The value NISSY_ERROR_INVALID_SOLVER means that the given solver is
     93 not known.
     94 */
     95 #define NISSY_ERROR_INVALID_SOLVER -50LL
     96 
     97 /*
     98 The value NISSY_ERROR_NULL_POINTER means that one of the provided pointer
     99 arguments is NULL. For example, it may be returned by solve when called
    100 with a solver that requires some pre-computed data, but the provided
    101 data is NULL.
    102 */
    103 #define NISSY_ERROR_NULL_POINTER -60LL
    104 
    105 /*
    106 The value NISSY_ERROR_BUFFER_SIZE means that one of the buffers provided
    107 is too small. For example, it could be too small to hold the result or
    108 too small to hold the data generated by gendata.
    109 */
    110 #define NISSY_ERROR_BUFFER_SIZE -61LL
    111 
    112 /*
    113 The value NISSY_ERROR_DATA means that the provided data is invalid. For
    114 example, it may be returned by solve when called with incompatible solver
    115 and data arguments.
    116 */
    117 #define NISSY_ERROR_DATA -70LL
    118 
    119 /*
    120 The value NISSY_ERROR_OPTIONS means that one or more of the given options
    121 are invalid. For example, it may be returned by solve when called with
    122 a negative maximum number of solutions.
    123 */
    124 #define NISSY_ERROR_OPTIONS -80LL
    125 
    126 /*
    127 The value NISSY_ERROR_UNKNOWN denotes an unexpected error. It probably
    128 means that there some bug in this library.  If you can, report any error
    129 of this kind to sebastiano@tronto.net. Thanks!
    130 */
    131 #define NISSY_ERROR_UNKNOWN -999LL
    132 
    133 
    134 /* Library functions *********************************************************/
    135 
    136 /*
    137 Compute the inverse of the given cube.
    138 
    139 Parameters:
    140    cube   - The cube to be inverted.
    141    result - The return parameter for the resulting cube.
    142 
    143 Return values:
    144    NISSY_OK                  - The cube was inverted succesfully.
    145    NISSY_WARNING_UNSOLVABLE  - The resulting cube is not solvable. This is
    146                                either because the given cube was not solvable,
    147                                or due to an unknown internal error.
    148    NISSY_ERROR_INVALID_CUBE  - The given cube is invalid.
    149    NISSY_ERROR_UNKNOWN       - An unknown error occurred.
    150 */
    151 long long
    152 nissy_inverse(
    153 	const char cube[static NISSY_SIZE_CUBE],
    154 	char result[static NISSY_SIZE_CUBE]
    155 );
    156 
    157 /*
    158 Apply the given sequence of moves on the given cube.
    159 
    160 Parameters:
    161    cube   - The cube to move.
    162    moves  - The moves to apply to the cube. Must be a NULL-terminated string.
    163    result - The return parameter for the resulting cube.
    164 
    165 Return values:
    166    NISSY_OK                  - The moves were applied succesfully.
    167    NISSY_WARNING_UNSOLVABLE  - The resulting cube is not solvable. This is
    168                                either because the given cube was not solvable,
    169                                or due to an unknown internal error.
    170    NISSY_ERROR_INVALID_CUBE  - The given cube is invalid.
    171    NISSY_ERROR_INVALID_MOVES - The given moves are invalid.
    172    NISSY_ERROR_NULL_POINTER  - The 'moves' argument is NULL.
    173 */
    174 long long
    175 nissy_applymoves(
    176 	const char cube[static NISSY_SIZE_CUBE],
    177 	const char *moves,
    178 	char result[static NISSY_SIZE_CUBE]
    179 );
    180 
    181 /*
    182 Apply the single given transformation to the given cube.
    183 
    184 Parameters:
    185    cube           - The cube to be transformed.
    186    transformation - The transformation in "(rotation|mirrored) __" format.
    187    result         - The return parameter for the resulting cube.
    188 
    189 Return values:
    190    NISSY_OK                  - The transformation was performed succesfully.
    191    NISSY_WARNING_UNSOLVABLE  - The resulting cube is not solvable. This is
    192                                probably due to an unknown internal error.
    193    NISSY_ERROR_INVALID_CUBE  - The given cube is invalid.
    194    NISSY_ERROR_INVALID_TRANS - The given transformation is invalid.
    195 */
    196 long long
    197 nissy_applytrans(
    198 	const char cube[static NISSY_SIZE_CUBE],
    199 	const char transformation[static NISSY_SIZE_TRANSFORMATION],
    200 	char result[static NISSY_SIZE_CUBE]
    201 );
    202 
    203 /*
    204 Get the cube with the given ep, eo, cp and co values. The values must be in the
    205 ranges specified below, but if the option "fix" is given any values outside its
    206 range will be adjusted before using it. The option "fix" also fixes parity and
    207 orientation issues, resulting always in a solvable cube.
    208 
    209 Parameters:
    210    ep      - The edge permutation, 0 <= ep < 479001600 (12!)
    211    eo      - The edge orientation, 0 <= eo < 2047 (2^11)
    212    cp      - The corner permutation, 0 <= cp < 40320 (8!)
    213    co      - The corner orientation, 0 <= co < 2187 (3^7)
    214    orient  - The orientation of the cube, 0 <= orient < 24
    215    options - Other options.
    216    result  - The return parameter for the resulting cube.
    217 
    218 Return values:
    219    NISSY_OK                 - The cube was generated succesfully.
    220    NISSY_WARNING_UNSOLVABLE - The resulting cube is unsolvable.
    221    NISSY_ERROR_OPTIONS      - One or more of the given parameters is invalid.
    222 */
    223 long long
    224 nissy_getcube(
    225 	long long ep,
    226 	long long eo,
    227 	long long cp,
    228 	long long co,
    229 	long long orient,
    230 	const char *options,
    231 	char result[static NISSY_SIZE_CUBE]
    232 );
    233 
    234 /*
    235 Compute the size of the data generated by nissy_gendata when called for
    236 the given solver, and other useful information.
    237 
    238 Parameters:
    239    solver - The name of the solver.
    240    dataid - An identifier for the data computed for the solver. Different
    241             solvers may use equivalent data. This identifier can be used
    242             e.g. as a filename or database key to save and retrieve the
    243             correct data for each solver, without duplication.
    244 
    245 Return values:
    246    NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
    247    NISSY_ERROR_NULL_POINTER   - The 'solver' argument is null.
    248    NISSY_ERROR_UNKNOWN        - An unknown error occurred.
    249    Any value >= 0             - The size of the data, in bytes.
    250 */
    251 long long
    252 nissy_solverinfo(
    253 	const char *solver,
    254 	char dataid[static NISSY_SIZE_DATAID]
    255 );
    256 
    257 /*
    258 Compute the data for the given solver and store it in generated_data.
    259 
    260 Parameters:
    261    solver    - The name of the solver.
    262    data_size - The size of the data buffer. It is advised to use
    263                nissy_solverinfo to check how much memory is needed.
    264    data      - The return parameter for the generated data.
    265                This buffer must have 8-byte alignment.
    266 
    267 Return values:
    268    NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
    269    NISSY_ERROR_NULL_POINTER   - The 'solver' argument is null.
    270    NISSY_ERROR_UNKNOWN        - An error occurred while generating the data.
    271    NISSY_ERROR_DATA           - The data buffer is invalid, for example because
    272                                 it is not 8-byte aligned.
    273    Any value >= 0             - The size of the data, in bytes.
    274 */
    275 long long
    276 nissy_gendata(
    277 	const char *solver,
    278 	unsigned long long data_size,
    279 	unsigned char data[data_size]
    280 );
    281 
    282 /*
    283 Check that the data is a valid data table for a solver.
    284 
    285 Parameters:
    286    data_size - The size of the data buffer.
    287    data      - The data for the solver. Can be computed with gendata.
    288                This buffer must have 8-byte alignment.
    289 
    290 Return values:
    291    NISSY_OK         - The data is valid.
    292    NISSY_ERROR_DATA - The data is invalid.
    293 */
    294 long long
    295 nissy_checkdata(
    296 	unsigned long long data_size,
    297 	const unsigned char data[data_size]
    298 );
    299 
    300 /*
    301 Solve the given cube using the given solver and options.
    302 
    303 Parameters:
    304    cube             - The cube to solver.
    305    solver           - The name of the solver.
    306    nissflag         - The flags for NISS (linear, inverse, mixed, or
    307                       combinations; see the constants at the top of this file).
    308    minmoves         - The minimum number of moves for a solution.
    309    maxmoves         - The maximum number of moves for a solution.
    310    maxsols          - The maximum number of solutions.
    311    optimal          - The maximum number of moves above the optimal solution.
    312    threads          - The number of threads to use. Must be less than or equal
    313                       to the value of the compile-time constant THREADS. If set
    314                       to 0, the default value THREADS will be used.
    315    data_size        - The size of the data buffer.
    316    data             - The data for the solver. Can be computed with gendata.
    317                       This buffer must have 8-byte alignment.
    318    sols_size        - The size of the solutions buffer.
    319    sols             - The return parameter for the solutions. The solutions are
    320                       separated by a '\n' (newline) and a '\0' (NULL character)
    321                       terminates the list.
    322    stats            - An array to store some statistics about the solve.
    323    poll_status      - A callback function that should return the current
    324                       requested status for the solver (e.g. run, stop, pause,
    325                       resume; see the constants at the top of this file). The
    326                       way this status is polled and honored is solver-specific.
    327                       If this parameter is NULL, the status will always assumed
    328                       to be "run".
    329    poll_status_data - Auxiliary data for the poll_status callback function.
    330 
    331 Return values:
    332    NISSY_OK                    - Cube solved succesfully.
    333    NISSY_ERROR_INVALID_CUBE    - The given cube is invalid.
    334    NISSY_ERROR_UNSOLVABLE_CUBE - The given cube is valid, but not solvable with
    335                                  the given solver.
    336    NISSY_ERROR_OPTIONS         - One or more of the given options are invalid.
    337    NISSY_ERROR_INVALID_SOLVER  - The given solver is not known.
    338    NISSY_ERROR_NULL_POINTER    - The 'solver' argument is null.
    339    NISSY_ERROR_DATA            - The data buffer is invalid.
    340    Any value >= 0              - The number of solutions found.
    341 */
    342 long long
    343 nissy_solve(
    344 	const char cube[static NISSY_SIZE_CUBE],
    345 	const char *solver, 
    346 	unsigned nissflag,
    347 	unsigned minmoves,
    348 	unsigned maxmoves,
    349 	unsigned maxsolutions,
    350 	unsigned optimal,
    351 	unsigned threads,
    352 	unsigned long long data_size,
    353 	const unsigned char data[data_size],
    354 	unsigned sols_size,
    355 	char sols[sols_size],
    356 	long long stats[static NISSY_SIZE_SOLVE_STATS],
    357 	int (*poll_status)(void *),
    358 	void *poll_status_data
    359 );
    360 
    361 /*
    362 Parameters:
    363    moves  - The moves to be counted.
    364 
    365 Return values:
    366    NISSY_ERROR_INVALID_MOVES - The given moves are invalid.
    367    NISSY_ERROR_NULL_POINTER  - The 'moves' argument is NULL.
    368    Any value >= 0            - The number of moves.
    369 */
    370 long long
    371 nissy_countmoves(
    372 	const char *moves
    373 );
    374 
    375 /*
    376 Set a global logger function used by this library. Setting the logger to NULL
    377 disables logging.
    378 
    379 Parameters:
    380    logger_function - A pointer to a function that takes two parameters:
    381                      * A C string, the string to be printed.
    382                      * Any other data via a void pointer.
    383    user_data       - Any data that will be provided by the logger when
    384                      calling logger_function.
    385 
    386 Return values:
    387    NISSY_OK - Logger set succesfully. No warning or error is going to be given
    388               if the logger is invalid.
    389 */
    390 long long
    391 nissy_setlogger(
    392 	void (*logger_function)(const char *, void *),
    393 	void *user_data
    394 );