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


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