aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cube.c87
-rw-r--r--cube.h40
-rw-r--r--debugcube.obin0 -> 113064 bytes
-rw-r--r--test/000_basic/basic_tests.c11
-rw-r--r--test/001_cube_conversion/cube_conversion_tests.c4
-rw-r--r--test/020_io_H48_read_write/io_H48_tests.c4
-rw-r--r--test/023_io_LST_write/io_LST_tests.c4
-rw-r--r--test/024_io_LST_read/io_LST_tests.c4
-rw-r--r--test/030_move/move_tests.c4
-rw-r--r--test/040_inverse_cube/inverse_tests.c8
-rw-r--r--test/050_compose/compose_tests.c4
-rw-r--r--test/060_transform/transform_tests.c4
-rw-r--r--test/061_inverse_trans/inverse_trans_tests.c8
-rw-r--r--test/last.err0
-rw-r--r--test/last.out1
-rw-r--r--test/test.h21
16 files changed, 72 insertions, 132 deletions
diff --git a/cube.c b/cube.c
index 9ca9e68..663f271 100644
--- a/cube.c
+++ b/cube.c
@@ -229,26 +229,6 @@ Some of these routines depend on the efficient functions implemented in the
229previous sections, while some other operate directly on the cube. 229previous sections, while some other operate directly on the cube.
230******************************************************************************/ 230******************************************************************************/
231 231
232#define _premove(M, c) compose_fast(_move_cube_ ## M, c)
233
234#define _foreach_move(_m, _c, _d, instruction) \
235 for (_m = 0; _m < 18; _m++) { _d = move(_c, _m); instruction }
236#define _foreach_trans(_t, _c, _d, instruction) \
237 for (_t = 0; _t < 48; _t++) { _d = transform(_c, _t); instruction }
238
239cube_t solvedcube(void);
240bool isconsistent(cube_t);
241bool issolvable(cube_t);
242bool issolved(cube_t cube);
243bool equal(cube_t, cube_t);
244bool iserror(cube_t);
245cube_t compose(cube_t, cube_t);
246cube_t inverse(cube_t);
247cube_t applymoves(cube_t, char *);
248cube_t applytrans(cube_t, char *);
249cube_t readcube(char *, char *);
250void writecube(char *, cube_t, char *);
251
252_static int permsign(uint8_t *, int); 232_static int permsign(uint8_t *, int);
253_static uint8_t readco(char *); 233_static uint8_t readco(char *);
254_static uint8_t readcp(char *); 234_static uint8_t readcp(char *);
@@ -269,13 +249,23 @@ _static cube_fast_t move(cube_fast_t, move_t);
269_static cube_fast_t transform(cube_fast_t, trans_t); 249_static cube_fast_t transform(cube_fast_t, trans_t);
270 250
271cube_t 251cube_t
272solvedcube(void) 252cube_new(void)
273{ 253{
274 return solved; 254 return solved;
275} 255}
276 256
257cube_t
258cube_clone(cube_t c)
259{
260 cube_t ret;
261
262 memcpy(&ret, &c, sizeof(cube_t));
263
264 return ret;
265}
266
277bool 267bool
278isconsistent(cube_t cube) 268cube_consistent(cube_t cube)
279{ 269{
280 uint8_t i, p, e, piece; 270 uint8_t i, p, e, piece;
281 bool found[12]; 271 bool found[12];
@@ -329,12 +319,12 @@ inconsistent_co:
329} 319}
330 320
331bool 321bool
332issolvable(cube_t cube) 322cube_solvable(cube_t cube)
333{ 323{
334 uint8_t i, eo, co, piece, edges[12], corners[8]; 324 uint8_t i, eo, co, piece, edges[12], corners[8];
335 325
336 DBG_ASSERT(isconsistent(cube), false, 326 DBG_ASSERT(cube_consistent(cube), false,
337 "issolvable: cube is inconsistent\n"); 327 "cube_solvable: cube is inconsistent\n");
338 328
339 for (i = 0; i < 12; i++) 329 for (i = 0; i < 12; i++)
340 edges[i] = cube.edge[i] & _pbits; 330 edges[i] = cube.edge[i] & _pbits;
@@ -342,7 +332,7 @@ issolvable(cube_t cube)
342 corners[i] = cube.corner[i] & _pbits; 332 corners[i] = cube.corner[i] & _pbits;
343 333
344 if (permsign(edges, 12) != permsign(corners, 8)) 334 if (permsign(edges, 12) != permsign(corners, 8))
345 goto issolvable_parity; 335 goto solvable_parity;
346 336
347 eo = 0; 337 eo = 0;
348 for (i = 0; i < 12; i++) { 338 for (i = 0; i < 12; i++) {
@@ -350,7 +340,7 @@ issolvable(cube_t cube)
350 eo += (piece & _eobit) >> _eoshift; 340 eo += (piece & _eobit) >> _eoshift;
351 } 341 }
352 if (eo % 2 != 0) 342 if (eo % 2 != 0)
353 goto issolvable_eo; 343 goto solvable_eo;
354 344
355 co = 0; 345 co = 0;
356 for (i = 0; i < 8; i++) { 346 for (i = 0; i < 8; i++) {
@@ -358,29 +348,29 @@ issolvable(cube_t cube)
358 co += (piece & _cobits) >> _coshift; 348 co += (piece & _cobits) >> _coshift;
359 } 349 }
360 if (co % 3 != 0) 350 if (co % 3 != 0)
361 goto issolvable_co; 351 goto solvable_co;
362 352
363 return true; 353 return true;
364 354
365issolvable_parity: 355solvable_parity:
366 DBG_LOG("EP and CP parities are different\n"); 356 DBG_LOG("EP and CP parities are different\n");
367 return false; 357 return false;
368issolvable_eo: 358solvable_eo:
369 DBG_LOG("Odd number of flipped edges\n"); 359 DBG_LOG("Odd number of flipped edges\n");
370 return false; 360 return false;
371issolvable_co: 361solvable_co:
372 DBG_LOG("Sum of corner orientation is not multiple of 3\n"); 362 DBG_LOG("Sum of corner orientation is not multiple of 3\n");
373 return false; 363 return false;
374} 364}
375 365
376bool 366bool
377issolved(cube_t cube) 367cube_solved(cube_t cube)
378{ 368{
379 return equal(cube, solved); 369 return cube_equal(cube, solved);
380} 370}
381 371
382bool 372bool
383equal(cube_t c1, cube_t c2) 373cube_equal(cube_t c1, cube_t c2)
384{ 374{
385 int i; 375 int i;
386 bool ret; 376 bool ret;
@@ -395,28 +385,28 @@ equal(cube_t c1, cube_t c2)
395} 385}
396 386
397bool 387bool
398iserror(cube_t cube) 388cube_error(cube_t cube)
399{ 389{
400 return equal(cube, zero); 390 return cube_equal(cube, zero);
401} 391}
402 392
403cube_t 393cube_t
404compose(cube_t c1, cube_t c2) 394cube_compose(cube_t c1, cube_t c2)
405{ 395{
406 DBG_ASSERT(isconsistent(c1) && isconsistent(c2), 396 DBG_ASSERT(cube_consistent(c1) && cube_consistent(c2),
407 zero, "compose error: inconsistent cube\n") 397 zero, "cube_compose error: inconsistent cube\n")
408 398
409 return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2))); 399 return fasttocube(compose_fast(cubetofast(c1), cubetofast(c2)));
410} 400}
411 401
412cube_t 402cube_t
413inverse(cube_t cube) 403cube_inverse(cube_t cube)
414{ 404{
415 cube_t ret; 405 cube_t ret;
416 uint8_t i, piece, orien; 406 uint8_t i, piece, orien;
417 407
418 DBG_ASSERT(isconsistent(cube), zero, 408 DBG_ASSERT(cube_consistent(cube), zero,
419 "inverse error: inconsistent cube\n"); 409 "cube_inverse error: inconsistent cube\n");
420 410
421 ret = zero; 411 ret = zero;
422 412
@@ -442,7 +432,7 @@ applymoves(cube_t cube, char *buf)
442 uint8_t r, m; 432 uint8_t r, m;
443 char *b; 433 char *b;
444 434
445 DBG_ASSERT(isconsistent(cube), zero, 435 DBG_ASSERT(cube_consistent(cube), zero,
446 "move error: inconsistent cube\n"); 436 "move error: inconsistent cube\n");
447 437
448 fast = cubetofast(cube); 438 fast = cubetofast(cube);
@@ -473,7 +463,7 @@ applytrans(cube_t cube, char *buf)
473 cube_fast_t fast; 463 cube_fast_t fast;
474 uint8_t t; 464 uint8_t t;
475 465
476 DBG_ASSERT(isconsistent(cube), zero, 466 DBG_ASSERT(cube_consistent(cube), zero,
477 "transformation error: inconsistent cube\n"); 467 "transformation error: inconsistent cube\n");
478 468
479 t = readtrans(buf); 469 t = readtrans(buf);
@@ -506,7 +496,7 @@ writecube(char *format, cube_t cube, char *buf)
506 char *errormsg; 496 char *errormsg;
507 size_t len; 497 size_t len;
508 498
509 if (!isconsistent(cube)) { 499 if (!cube_consistent(cube)) {
510 errormsg = "ERROR: cannot write inconsistent cube"; 500 errormsg = "ERROR: cannot write inconsistent cube";
511 goto writecube_error; 501 goto writecube_error;
512 } 502 }
@@ -837,13 +827,6 @@ transform(cube_fast_t c, trans_t t)
837 invertco_fast(compose_fast(compose_fast(tcube, c), tinv)); 827 invertco_fast(compose_fast(compose_fast(tcube, c), tinv));
838} 828}
839 829
840/******************************************************************************
841Section: moves, move sequences and transformations
842
843This section contains methods to work with moves and arrays of moves. They
844do not rely on the cube structure.
845******************************************************************************/
846
847_static_inline uint8_t inverse_trans(uint8_t); 830_static_inline uint8_t inverse_trans(uint8_t);
848_static_inline uint8_t movebase(uint8_t); 831_static_inline uint8_t movebase(uint8_t);
849_static_inline uint8_t moveaxis(uint8_t); 832_static_inline uint8_t moveaxis(uint8_t);
diff --git a/cube.h b/cube.h
index 72447a7..f70e04a 100644
--- a/cube.h
+++ b/cube.h
@@ -16,13 +16,6 @@ corners is with respect to U/D.
16 16
17The permutation of the center pieces is not stored. This means that the 17The permutation of the center pieces is not stored. This means that the
18cube is assumed to be in a fixed orientation. 18cube is assumed to be in a fixed orientation.
19
20TODO: define EO and CO better, explain how to use them
21TODO: encode centers?
22
23The exact cube type structure depends on your system's configuration. If
24you operate on the cube only via the functions provided below, you don't
25need to worry about this.
26******************************************************************************/ 19******************************************************************************/
27 20
28typedef struct { 21typedef struct {
@@ -30,30 +23,15 @@ typedef struct {
30 uint8_t edge[12]; 23 uint8_t edge[12];
31} cube_t; 24} cube_t;
32 25
33/* Returns a copy of the solved cube */ 26cube_t cube_new(void);
34cube_t solvedcube(void); 27cube_t cube_clone(cube_t);
35 28bool cube_consistent(cube_t);
36/* Basic checks on the cube */ 29bool cube_solvable(cube_t);
37bool isconsistent(cube_t); 30bool cube_solved(cube_t);
38bool issolvable(cube_t); 31bool cube_equal(cube_t, cube_t);
39bool issolved(cube_t); 32bool cube_error(cube_t);
40bool equal(cube_t, cube_t); 33cube_t cube_compose(cube_t, cube_t);
41 34cube_t cube_inverse(cube_t);
42/* All functions can return an error value, use iserror() to check this */
43bool iserror(cube_t);
44
45/* Apply the second cube on the first as a move sequence */
46cube_t compose(cube_t, cube_t);
47
48/* Invert the cube */
49cube_t inverse(cube_t);
50
51/* Check if a cube represent a valid state (possibly unsolvable) */
52
53/* TODO comment on these and the format for moves and trans */
54/* For trans, only one trans is supported */
55cube_t applymoves(cube_t, char *);
56cube_t applytrans(cube_t, char *);
57 35
58/****************************************************************************** 36/******************************************************************************
59Read / write utilities 37Read / write utilities
diff --git a/debugcube.o b/debugcube.o
new file mode 100644
index 0000000..a37ffff
--- /dev/null
+++ b/debugcube.o
Binary files differ
diff --git a/test/000_basic/basic_tests.c b/test/000_basic/basic_tests.c
index c4434c5..53ccc9f 100644
--- a/test/000_basic/basic_tests.c
+++ b/test/000_basic/basic_tests.c
@@ -1,27 +1,24 @@
1#include "../test.h" 1#include "../test.h"
2 2
3bool issolved(cube_t);
4bool equal(cube_t, cube_t);
5
6void 3void
7check(cube_t cube, char *name) 4check(cube_t cube, char *name)
8{ 5{
9 printf("%s is%s solvable\n", name, issolvable(cube) ? "" : " NOT"); 6 printf("%s is%s solvable\n", name, cube_solvable(cube) ? "" : " NOT");
10 printf("%s is%s solved\n", name, issolved(cube) ? "" : " NOT"); 7 printf("%s is%s solved\n", name, cube_solved(cube) ? "" : " NOT");
11} 8}
12 9
13void 10void
14check2(cube_t cube1, char *name1, cube_t cube2, char *name2) 11check2(cube_t cube1, char *name1, cube_t cube2, char *name2)
15{ 12{
16 printf("%s and %s are%s equal\n", name1, name2, 13 printf("%s and %s are%s equal\n", name1, name2,
17 equal(cube1, cube2) ? "" : " NOT"); 14 cube_equal(cube1, cube2) ? "" : " NOT");
18} 15}
19 16
20int main(void) { 17int main(void) {
21 cube_t zero, solved; 18 cube_t zero, solved;
22 19
23 memset(&zero, 0, sizeof(cube_t)); 20 memset(&zero, 0, sizeof(cube_t));
24 solved = solvedcube(); 21 solved = cube_new();
25 check(solved, "Solved"); 22 check(solved, "Solved");
26 check(zero, "Zero"); 23 check(zero, "Zero");
27 24
diff --git a/test/001_cube_conversion/cube_conversion_tests.c b/test/001_cube_conversion/cube_conversion_tests.c
index 589eb82..fe8a68f 100644
--- a/test/001_cube_conversion/cube_conversion_tests.c
+++ b/test/001_cube_conversion/cube_conversion_tests.c
@@ -14,9 +14,9 @@ int main(void) {
14 fast = cubetofast(cube); 14 fast = cubetofast(cube);
15 cube2 = fasttocube(fast); 15 cube2 = fasttocube(fast);
16 16
17 if (iserror(cube)) { 17 if (cube_error(cube)) {
18 printf("Error reading cube\n"); 18 printf("Error reading cube\n");
19 } else if (iserror(cube2)) { 19 } else if (cube_error(cube2)) {
20 printf("Error converting cube\n"); 20 printf("Error converting cube\n");
21 } else { 21 } else {
22 writecube("H48", cube2, cubestr); 22 writecube("H48", cube2, cubestr);
diff --git a/test/020_io_H48_read_write/io_H48_tests.c b/test/020_io_H48_read_write/io_H48_tests.c
index 705356c..222e4d4 100644
--- a/test/020_io_H48_read_write/io_H48_tests.c
+++ b/test/020_io_H48_read_write/io_H48_tests.c
@@ -11,9 +11,9 @@ int main(void) {
11 11
12 cube = readcube("H48", str); 12 cube = readcube("H48", str);
13 13
14 if (iserror(cube)) { 14 if (cube_error(cube)) {
15 printf("Error reading cube\n"); 15 printf("Error reading cube\n");
16 } else if (!issolvable(cube)) { 16 } else if (!cube_solvable(cube)) {
17 printf("Cube is not solvable\n"); 17 printf("Cube is not solvable\n");
18 } else { 18 } else {
19 writecube("H48", cube, str); 19 writecube("H48", cube, str);
diff --git a/test/023_io_LST_write/io_LST_tests.c b/test/023_io_LST_write/io_LST_tests.c
index df35632..8a3ce22 100644
--- a/test/023_io_LST_write/io_LST_tests.c
+++ b/test/023_io_LST_write/io_LST_tests.c
@@ -11,9 +11,9 @@ int main(void) {
11 11
12 cube = readcube("H48", str); 12 cube = readcube("H48", str);
13 13
14 if (iserror(cube)) { 14 if (cube_error(cube)) {
15 printf("Error reading cube\n"); 15 printf("Error reading cube\n");
16 } else if (!issolvable(cube)) { 16 } else if (!cube_solvable(cube)) {
17 printf("Cube is not solvable\n"); 17 printf("Cube is not solvable\n");
18 } else { 18 } else {
19 writecube("LST", cube, str); 19 writecube("LST", cube, str);
diff --git a/test/024_io_LST_read/io_LST_tests.c b/test/024_io_LST_read/io_LST_tests.c
index 506a23d..81d4c54 100644
--- a/test/024_io_LST_read/io_LST_tests.c
+++ b/test/024_io_LST_read/io_LST_tests.c
@@ -11,9 +11,9 @@ int main(void) {
11 11
12 cube = readcube("LST", str); 12 cube = readcube("LST", str);
13 13
14 if (iserror(cube)) { 14 if (cube_error(cube)) {
15 printf("Error reading cube\n"); 15 printf("Error reading cube\n");
16 } else if (!issolvable(cube)) { 16 } else if (!cube_solvable(cube)) {
17 printf("Cube is not solvable\n"); 17 printf("Cube is not solvable\n");
18 } else { 18 } else {
19 writecube("H48", cube, str); 19 writecube("H48", cube, str);
diff --git a/test/030_move/move_tests.c b/test/030_move/move_tests.c
index 73e9dbe..39458ba 100644
--- a/test/030_move/move_tests.c
+++ b/test/030_move/move_tests.c
@@ -12,9 +12,9 @@ int main(void) {
12 12
13 cube = applymoves(cube, movestr); 13 cube = applymoves(cube, movestr);
14 14
15 if (iserror(cube)) { 15 if (cube_error(cube)) {
16 printf("Error moving cube\n"); 16 printf("Error moving cube\n");
17 } else if (!issolvable(cube)) { 17 } else if (!cube_solvable(cube)) {
18 printf("Moved cube is not solvable\n"); 18 printf("Moved cube is not solvable\n");
19 } else { 19 } else {
20 writecube("H48", cube, cubestr); 20 writecube("H48", cube, cubestr);
diff --git a/test/040_inverse_cube/inverse_tests.c b/test/040_inverse_cube/inverse_tests.c
index 2ff3bc7..ca7e481 100644
--- a/test/040_inverse_cube/inverse_tests.c
+++ b/test/040_inverse_cube/inverse_tests.c
@@ -1,18 +1,16 @@
1#include "../test.h" 1#include "../test.h"
2 2
3cube_t inverse(cube_t);
4
5int main(void) { 3int main(void) {
6 char str[STRLENMAX]; 4 char str[STRLENMAX];
7 cube_t cube, inv; 5 cube_t cube, inv;
8 6
9 fgets(str, STRLENMAX, stdin); 7 fgets(str, STRLENMAX, stdin);
10 cube = readcube("H48", str); 8 cube = readcube("H48", str);
11 inv = inverse(cube); 9 inv = cube_inverse(cube);
12 10
13 if (iserror(inv)) { 11 if (cube_error(inv)) {
14 printf("Error inverting cube\n"); 12 printf("Error inverting cube\n");
15 } else if (!issolvable(inv)) { 13 } else if (!cube_solvable(inv)) {
16 printf("Inverted cube is not solvable\n"); 14 printf("Inverted cube is not solvable\n");
17 } else { 15 } else {
18 writecube("H48", inv, str); 16 writecube("H48", inv, str);
diff --git a/test/050_compose/compose_tests.c b/test/050_compose/compose_tests.c
index 0ea4eff..c0bbbef 100644
--- a/test/050_compose/compose_tests.c
+++ b/test/050_compose/compose_tests.c
@@ -13,9 +13,9 @@ int main(void) {
13 13
14 c3 = compose(c1, c2); 14 c3 = compose(c1, c2);
15 15
16 if (iserror(c3)) { 16 if (cube_error(c3)) {
17 printf("Error composing cubes\n"); 17 printf("Error composing cubes\n");
18 } else if (!issolvable(c3)) { 18 } else if (!cube_solvable(c3)) {
19 printf("Composed cube is not solvable\n"); 19 printf("Composed cube is not solvable\n");
20 } else { 20 } else {
21 writecube("H48", c3, str); 21 writecube("H48", c3, str);
diff --git a/test/060_transform/transform_tests.c b/test/060_transform/transform_tests.c
index f95ad67..8680a0b 100644
--- a/test/060_transform/transform_tests.c
+++ b/test/060_transform/transform_tests.c
@@ -12,9 +12,9 @@ int main(void) {
12 12
13 cube = applytrans(cube, transtr); 13 cube = applytrans(cube, transtr);
14 14
15 if (iserror(cube)) { 15 if (cube_error(cube)) {
16 printf("Error transforming cube\n"); 16 printf("Error transforming cube\n");
17 } else if (!issolvable(cube)) { 17 } else if (!cube_solvable(cube)) {
18 printf("Transformed cube is not solvable\n"); 18 printf("Transformed cube is not solvable\n");
19 } else { 19 } else {
20 writecube("H48", cube, cubestr); 20 writecube("H48", cube, cubestr);
diff --git a/test/061_inverse_trans/inverse_trans_tests.c b/test/061_inverse_trans/inverse_trans_tests.c
index 77bd40b..7de8f66 100644
--- a/test/061_inverse_trans/inverse_trans_tests.c
+++ b/test/061_inverse_trans/inverse_trans_tests.c
@@ -11,7 +11,7 @@ int main(void) {
11 cube_t cube; 11 cube_t cube;
12 12
13 for (t = 0; t < 48; t++) { 13 for (t = 0; t < 48; t++) {
14 cube = solvedcube(); 14 cube = cube_new();
15 cube = applymoves(cube, "R"); 15 cube = applymoves(cube, "R");
16 cube = applymoves(cube, "U"); 16 cube = applymoves(cube, "U");
17 cube = applymoves(cube, "F"); 17 cube = applymoves(cube, "F");
@@ -20,15 +20,15 @@ int main(void) {
20 tinv = inverse_trans(t); 20 tinv = inverse_trans(t);
21 cube = applytrans(cube, transstr[tinv]); 21 cube = applytrans(cube, transstr[tinv]);
22 22
23 if (iserror(cube)) { 23 if (cube_error(cube)) {
24 printf("Error transforming cube\n"); 24 printf("Error transforming cube\n");
25 } else if (!issolvable(cube)) { 25 } else if (!cube_solvable(cube)) {
26 printf("Transformed cube is not solvable\n"); 26 printf("Transformed cube is not solvable\n");
27 } else { 27 } else {
28 cube = applymoves(cube, "F'"); 28 cube = applymoves(cube, "F'");
29 cube = applymoves(cube, "U'"); 29 cube = applymoves(cube, "U'");
30 cube = applymoves(cube, "R'"); 30 cube = applymoves(cube, "R'");
31 if (!issolved(cube)) 31 if (!cube_solved(cube))
32 printf("%s: Error! Got %" PRIu8 "\n", 32 printf("%s: Error! Got %" PRIu8 "\n",
33 transstr[t], tinv); 33 transstr[t], tinv);
34 } 34 }
diff --git a/test/last.err b/test/last.err
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/last.err
diff --git a/test/last.out b/test/last.out
new file mode 100644
index 0000000..102ac1b
--- /dev/null
+++ b/test/last.out
@@ -0,0 +1 @@
UL1 UB0 DL1 UR0 BL1 DR1 BR0 DB0 FL1 UF0 FR1 DF0 DFR2 DFL0 DBL0 UFL0 UBR1 UBL0 UFR2 DBR1
diff --git a/test/test.h b/test/test.h
index 3cbfd10..92ed0db 100644
--- a/test/test.h
+++ b/test/test.h
@@ -4,24 +4,7 @@
4#include <stdlib.h> 4#include <stdlib.h>
5#include <string.h> 5#include <string.h>
6 6
7#define STRLENMAX 10000 7#include "../cube.h"
8
9typedef struct {
10 uint8_t corner[8];
11 uint8_t edge[12];
12} cube_t;
13 8
14#ifdef CUBE_AVX2 9#define STRLENMAX 10000
15#include <immintrin.h>
16typedef __m256i cube_fast_t;
17#else
18typedef cube_t cube_fast_t; 10typedef cube_t cube_fast_t;
19#endif
20
21/* Basic functions used in most tests */
22cube_t solvedcube(void);
23bool iserror(cube_t);
24bool issolvable(cube_t);
25bool issolved(cube_t);
26cube_t readcube(char *, char *);
27void writecube(char *, cube_t, char *);

Generated with cgit - Back to sebastiano.tronto.net