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