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 );