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 (13727B)


      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
    280 );
    281 
    282 /*
    283 Check that the data is a valid data table for a solver.
    284 
    285 Parameters:
    286    solver    - The name of the solver.
    287    data_size - The size of the data buffer.
    288    data      - The data for the solver. Can be computed with gendata.
    289                This buffer must have 8-byte alignment.
    290 
    291 Return values:
    292    NISSY_OK         - The data is valid.
    293    NISSY_ERROR_DATA - The data is invalid.
    294 */
    295 long long
    296 nissy_checkdata(
    297 	const char *solver,
    298 	unsigned long long data_size,
    299 	const unsigned char *data
    300 );
    301 
    302 /*
    303 Solve the given cube using the given solver and options.
    304 
    305 Parameters:
    306    cube             - The cube to solver.
    307    solver           - The name of the solver.
    308    nissflag         - The flags for NISS (linear, inverse, mixed, or
    309                       combinations; see the constants at the top of this file).
    310    minmoves         - The minimum number of moves for a solution.
    311    maxmoves         - The maximum number of moves for a solution.
    312    maxsols          - The maximum number of solutions.
    313    optimal          - The maximum number of moves above the optimal solution.
    314    threads          - The number of threads to use. Must be less than or equal
    315                       to the value of the compile-time constant THREADS. If set
    316                       to 0, the default value THREADS will be used.
    317    data_size        - The size of the data buffer.
    318    data             - The data for the solver. Can be computed with gendata.
    319                       This buffer must have 8-byte alignment.
    320    sols_size        - The size of the solutions buffer.
    321    sols             - The return parameter for the solutions. The solutions are
    322                       separated by a '\n' (newline) and a '\0' (NULL character)
    323                       terminates the list.
    324    stats            - An array to store some statistics about the solve.
    325    poll_status      - A callback function that should return the current
    326                       requested status for the solver (e.g. run, stop, pause,
    327                       resume; see the constants at the top of this file). The
    328                       way this status is polled and honored is solver-specific.
    329                       If this parameter is NULL, the status will always assumed
    330                       to be "run".
    331    poll_status_data - Auxiliary data for the poll_status callback function.
    332 
    333 Return values:
    334    NISSY_OK                    - Cube solved succesfully.
    335    NISSY_ERROR_INVALID_CUBE    - The given cube is invalid.
    336    NISSY_ERROR_UNSOLVABLE_CUBE - The given cube is valid, but not solvable with
    337                                  the given solver.
    338    NISSY_ERROR_OPTIONS         - One or more of the given options are invalid.
    339    NISSY_ERROR_INVALID_SOLVER  - The given solver is not known.
    340    NISSY_ERROR_NULL_POINTER    - The 'solver' argument is null.
    341    NISSY_ERROR_DATA            - The data buffer is invalid.
    342    Any value >= 0              - The number of solutions found.
    343 */
    344 long long
    345 nissy_solve(
    346 	const char cube[static NISSY_SIZE_CUBE],
    347 	const char *solver, 
    348 	unsigned nissflag,
    349 	unsigned minmoves,
    350 	unsigned maxmoves,
    351 	unsigned maxsolutions,
    352 	unsigned optimal,
    353 	unsigned threads,
    354 	unsigned long long data_size,
    355 	const unsigned char *data,
    356 	unsigned sols_size,
    357 	char *sols,
    358 	long long stats[static NISSY_SIZE_SOLVE_STATS],
    359 	int (*poll_status)(void *),
    360 	void *poll_status_data
    361 );
    362 
    363 /*
    364 Parameters:
    365    moves  - The moves to be counted.
    366 
    367 Return values:
    368    NISSY_ERROR_INVALID_MOVES - The given moves are invalid.
    369    NISSY_ERROR_NULL_POINTER  - The 'moves' argument is NULL.
    370    Any value >= 0            - The number of moves.
    371 */
    372 long long
    373 nissy_countmoves(
    374 	const char *moves
    375 );
    376 
    377 /*
    378 Set a global logger function used by this library. Setting the logger to NULL
    379 disables logging.
    380 
    381 Parameters:
    382    logger_function - A pointer to a function that takes two parameters:
    383                      * A C string, the string to be printed.
    384                      * Any other data via a void pointer.
    385    user_data       - Any data that will be provided by the logger when
    386                      calling logger_function.
    387 
    388 Return values:
    389    NISSY_OK - Logger set succesfully. No warning or error is going to be given
    390               if the logger is invalid.
    391 */
    392 long long
    393 nissy_setlogger(
    394 	void (*logger_function)(const char *, void *),
    395 	void *user_data
    396 );