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

nissy.h (14025B)


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