aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-03-30 18:40:02 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2024-03-30 18:40:02 +0100
commitc14e780551c4e7aa88d99b226b12f7cdd7b92527 (patch)
treedf663976f093b6446d8470c078bc105a541a9857
parentec564e62dcfe701b5ee3111b92c7d72ffd0dda6c (diff)
downloadnissy-core-c14e780551c4e7aa88d99b226b12f7cdd7b92527.tar.gz
nissy-core-c14e780551c4e7aa88d99b226b12f7cdd7b92527.zip
Added cocsep data generation, but it is very slow
-rw-r--r--TODO.txt9
-rw-r--r--cube.c203
-rw-r--r--test/061_inverse_trans/00_all.in0
-rw-r--r--test/061_inverse_trans/00_all.out0
-rw-r--r--test/061_inverse_trans/inverse_trans_tests.c38
-rw-r--r--test/100_gendata_cocsep/00_all.in0
-rw-r--r--test/100_gendata_cocsep/00_all.out1
-rw-r--r--test/100_gendata_cocsep/gendata_cocsep_tests.c14
-rw-r--r--test/test.h1
9 files changed, 243 insertions, 23 deletions
diff --git a/TODO.txt b/TODO.txt
index b6f5faa..8f636aa 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,8 +1,11 @@
1## (find better name) H48 solver, ideas 1TODO optimize cocsep generation (very slow!)
2 2TODO cocsep data: fix
3TODO implement lookup tables 3TODO cocsep data: add hash checks?
4TODO implement big pruning table for H48 solver
4TODO alternative: ARM NEON part 5TODO alternative: ARM NEON part
5 6
7## H48 optimal solver
8
6First compute co + csep. Use csep as a binary number (2^7 instead of 70, 9First compute co + csep. Use csep as a binary number (2^7 instead of 70,
7loose a factor of 1.8 but still fits in a few megabytes or less). Use 10loose a factor of 1.8 but still fits in a few megabytes or less). Use
8co + csep as an index in a table whose entries have: 6 bits for ttrep, 11co + csep as an index in a table whose entries have: 6 bits for ttrep,
diff --git a/cube.c b/cube.c
index fd6b0cf..58c8e7c 100644
--- a/cube.c
+++ b/cube.c
@@ -28,7 +28,33 @@
28#endif 28#endif
29 29
30/****************************************************************************** 30/******************************************************************************
31Section: constants, strings and other stuff 31Section: mathematical constants
32******************************************************************************/
33
34#define _2p11 2048U
35#define _2p12 4096U
36#define _3p7 2187U
37#define _3p8 6561U
38#define _12c4 495U
39#define _8c4 70U
40
41_static int64_t binomial[12][12] = {
42 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
43 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
44 {1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
45 {1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0},
46 {1, 4, 6, 4, 1, 0, 0, 0, 0, 0, 0, 0},
47 {1, 5, 10, 10, 5, 1, 0, 0, 0, 0, 0, 0},
48 {1, 6, 15, 20, 15, 6, 1, 0, 0, 0, 0, 0},
49 {1, 7, 21, 35, 35, 21, 7, 1, 0, 0, 0, 0},
50 {1, 8, 28, 56, 70, 56, 28, 8, 1, 0, 0, 0},
51 {1, 9, 36, 84, 126, 126, 84, 36, 9, 1, 0, 0},
52 {1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1, 0},
53 {1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1},
54};
55
56/******************************************************************************
57Section: moves definitions and tables
32******************************************************************************/ 58******************************************************************************/
33 59
34#define U 0U 60#define U 0U
@@ -378,7 +404,7 @@ _static cube_t solved = {
378#define _trans_cube_BLm_inverse fastcube( \ 404#define _trans_cube_BLm_inverse fastcube( \
379 38, 37, 39, 36, 67, 64, 66, 65, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0) 405 38, 37, 39, 36, 67, 64, 66, 65, 23, 20, 21, 22, 24, 27, 26, 25, 3, 2, 1, 0)
380 406
381static char *cornerstr[] = { 407_static char *cornerstr[] = {
382 [_c_ufr] = "UFR", 408 [_c_ufr] = "UFR",
383 [_c_ubl] = "UBL", 409 [_c_ubl] = "UBL",
384 [_c_dfl] = "DFL", 410 [_c_dfl] = "DFL",
@@ -389,7 +415,7 @@ static char *cornerstr[] = {
389 [_c_dbl] = "DBL" 415 [_c_dbl] = "DBL"
390}; 416};
391 417
392static char *cornerstralt[] = { 418_static char *cornerstralt[] = {
393 [_c_ufr] = "URF", 419 [_c_ufr] = "URF",
394 [_c_ubl] = "ULB", 420 [_c_ubl] = "ULB",
395 [_c_dfl] = "DLF", 421 [_c_dfl] = "DLF",
@@ -400,7 +426,7 @@ static char *cornerstralt[] = {
400 [_c_dbl] = "DLB" 426 [_c_dbl] = "DLB"
401}; 427};
402 428
403static char *edgestr[] = { 429_static char *edgestr[] = {
404 [_e_uf] = "UF", 430 [_e_uf] = "UF",
405 [_e_ub] = "UB", 431 [_e_ub] = "UB",
406 [_e_db] = "DB", 432 [_e_db] = "DB",
@@ -415,7 +441,7 @@ static char *edgestr[] = {
415 [_e_br] = "BR" 441 [_e_br] = "BR"
416}; 442};
417 443
418static char *movestr[] = { 444_static char *movestr[] = {
419 [U] = "U", 445 [U] = "U",
420 [U2] = "U2", 446 [U2] = "U2",
421 [U3] = "U'", 447 [U3] = "U'",
@@ -436,7 +462,7 @@ static char *movestr[] = {
436 [B3] = "B'", 462 [B3] = "B'",
437}; 463};
438 464
439static char *transstr[] = { 465_static char *transstr[] = {
440 [UFr] = "rotation UF", 466 [UFr] = "rotation UF",
441 [UFm] = "mirrored UF", 467 [UFm] = "mirrored UF",
442 [ULr] = "rotation UL", 468 [ULr] = "rotation UL",
@@ -487,19 +513,55 @@ static char *transstr[] = {
487 [BLm] = "mirrored BL", 513 [BLm] = "mirrored BL",
488}; 514};
489 515
490static int64_t binomial[12][12] = { 516static uint8_t inverse_trans_table[48] = {
491 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 517 [UFr] = UFr,
492 {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 518 [UFm] = UFm,
493 {1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 519 [ULr] = URr,
494 {1, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0}, 520 [ULm] = ULm,
495 {1, 4, 6, 4, 1, 0, 0, 0, 0, 0, 0, 0}, 521 [UBr] = UBr,
496 {1, 5, 10, 10, 5, 1, 0, 0, 0, 0, 0, 0}, 522 [UBm] = UBm,
497 {1, 6, 15, 20, 15, 6, 1, 0, 0, 0, 0, 0}, 523 [URr] = ULr,
498 {1, 7, 21, 35, 35, 21, 7, 1, 0, 0, 0, 0}, 524 [URm] = URm,
499 {1, 8, 28, 56, 70, 56, 28, 8, 1, 0, 0, 0}, 525 [DFr] = DFr,
500 {1, 9, 36, 84, 126, 126, 84, 36, 9, 1, 0, 0}, 526 [DFm] = DFm,
501 {1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1, 0}, 527 [DLr] = DLr,
502 {1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1}, 528 [DLm] = DRm,
529 [DBr] = DBr,
530 [DBm] = DBm,
531 [DRr] = DRr,
532 [DRm] = DLm,
533 [RUr] = FRr,
534 [RUm] = FLm,
535 [RFr] = LFr,
536 [RFm] = RFm,
537 [RDr] = BLr,
538 [RDm] = BRm,
539 [RBr] = RBr,
540 [RBm] = LBm,
541 [LUr] = FLr,
542 [LUm] = FRm,
543 [LFr] = RFr,
544 [LFm] = LFm,
545 [LDr] = BRr,
546 [LDm] = BLm,
547 [LBr] = LBr,
548 [LBm] = RBm,
549 [FUr] = FUr,
550 [FUm] = FUm,
551 [FRr] = RUr,
552 [FRm] = LUm,
553 [FDr] = BUr,
554 [FDm] = BUm,
555 [FLr] = LUr,
556 [FLm] = RUm,
557 [BUr] = FDr,
558 [BUm] = FDm,
559 [BRr] = LDr,
560 [BRm] = RDm,
561 [BDr] = BDr,
562 [BDm] = BDm,
563 [BLr] = RDr,
564 [BLm] = LDm,
503}; 565};
504 566
505/****************************************************************************** 567/******************************************************************************
@@ -536,6 +598,7 @@ _static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
536 598
537_static_inline int64_t coord_fast_co(cube_fast_t); 599_static_inline int64_t coord_fast_co(cube_fast_t);
538_static_inline int64_t coord_fast_csep(cube_fast_t); 600_static_inline int64_t coord_fast_csep(cube_fast_t);
601_static_inline int64_t coord_fast_cocsep(cube_fast_t);
539_static_inline int64_t coord_fast_eo(cube_fast_t); 602_static_inline int64_t coord_fast_eo(cube_fast_t);
540_static_inline int64_t coord_fast_esep(cube_fast_t); 603_static_inline int64_t coord_fast_esep(cube_fast_t);
541 604
@@ -694,6 +757,12 @@ coord_fast_csep(cube_fast_t c)
694} 757}
695 758
696_static_inline int64_t 759_static_inline int64_t
760coord_fast_cocsep(cube_fast_t c)
761{
762 return (coord_fast_co(c) << 7) + coord_fast_csep(c);
763}
764
765_static_inline int64_t
697coord_fast_eo(cube_fast_t c) 766coord_fast_eo(cube_fast_t c)
698{ 767{
699 cube_fast_t eo, shifted; 768 cube_fast_t eo, shifted;
@@ -779,6 +848,7 @@ _static_inline cube_fast_t compose_fast(cube_fast_t, cube_fast_t);
779 848
780_static_inline int64_t coord_fast_co(cube_fast_t); 849_static_inline int64_t coord_fast_co(cube_fast_t);
781_static_inline int64_t coord_fast_csep(cube_fast_t); 850_static_inline int64_t coord_fast_csep(cube_fast_t);
851_static_inline int64_t coord_fast_cocsep(cube_fast_t);
782_static_inline int64_t coord_fast_eo(cube_fast_t); 852_static_inline int64_t coord_fast_eo(cube_fast_t);
783_static_inline int64_t coord_fast_esep(cube_fast_t); 853_static_inline int64_t coord_fast_esep(cube_fast_t);
784 854
@@ -934,6 +1004,12 @@ coord_fast_csep(cube_fast_t c)
934} 1004}
935 1005
936_static_inline int64_t 1006_static_inline int64_t
1007coord_fast_cocsep(cube_fast_t c)
1008{
1009 return (coord_fast_co(c) << 7) + coord_fast_csep(c);
1010}
1011
1012_static_inline int64_t
937coord_fast_eo(cube_fast_t c) 1013coord_fast_eo(cube_fast_t c)
938{ 1014{
939 int i, p; 1015 int i, p;
@@ -1734,16 +1810,23 @@ transform(cube_fast_t c, uint8_t t)
1734} 1810}
1735 1811
1736/****************************************************************************** 1812/******************************************************************************
1737Section: moves and move sequences 1813Section: moves, move sequences and transformations
1738 1814
1739This section contains methods to work with moves and arrays of moves. They 1815This section contains methods to work with moves and arrays of moves. They
1740do not rely on the cube structure. 1816do not rely on the cube structure.
1741******************************************************************************/ 1817******************************************************************************/
1742 1818
1819_static_inline uint8_t inverse_trans(uint8_t);
1743_static_inline uint8_t movebase(uint8_t); 1820_static_inline uint8_t movebase(uint8_t);
1744_static_inline uint8_t moveaxis(uint8_t); 1821_static_inline uint8_t moveaxis(uint8_t);
1745 1822
1746_static_inline uint8_t 1823_static_inline uint8_t
1824inverse_trans(uint8_t t)
1825{
1826 return inverse_trans_table[t];
1827}
1828
1829_static_inline uint8_t
1747movebase(uint8_t move) 1830movebase(uint8_t move)
1748{ 1831{
1749 return move / 3; 1832 return move / 3;
@@ -1759,7 +1842,87 @@ moveaxis(uint8_t move)
1759Section: auxiliary procedures for H48 optimal solver (temporary) 1842Section: auxiliary procedures for H48 optimal solver (temporary)
1760******************************************************************************/ 1843******************************************************************************/
1761 1844
1845_static size_t gendata_cocsep(void *);
1846_static uint16_t dfs_cocsep(cube_fast_t, uint8_t, uint8_t, uint16_t *, uint32_t *);
1847
1848/*
1849Each element of the cocsep table is a uint32_t used as follows:
1850 - Lowest 8-bit block: pruning value
1851 - Second-lower 8-bit block: "ttrep" (transformation to representative)
1852 - Top 16-bit block: symcoord value
1853*/
1854_static size_t
1855gendata_cocsep(void *buf)
1856{
1857 uint32_t *buf32;
1858 uint16_t n, cc;
1859 uint8_t i, j;
1860 size_t tablesize;
1861
1862 tablesize = _3p7 << 7U;
1863
1864 buf32 = (uint32_t *)buf;
1865 memset(buf32, 0xFFU, 4*tablesize);
1866 memset(buf32 + tablesize, 0, 21*4);
1867
1868 for (i = 0, n = 0, cc = 0; cc != 0 || i == 0; i++) {
1869 DBG_LOG("gendata_cocsep: generating depth %" PRIu8 "\n", i);
1870 cc = dfs_cocsep(cubetofast(solvedcube()), 0, i, &n, buf32);
1871 buf32[tablesize+i+1] = (uint32_t)cc;
1872 }
1873 buf32[tablesize] = (uint32_t)n;
1874 i--;
1762 1875
1876 DBG_LOG("cocsep data computed, %" PRIu16 " symmetry classes\n", n);
1877 DBG_LOG("Pruning value distribution:\n");
1878 for (j = 0; j < i; j++)
1879 DBG_LOG("%" PRIu8 ":\t%" PRIu32 "\n", j, buf32[tablesize+j+1]);
1880
1881 return 4*(tablesize + i + 1);
1882}
1883
1884_static uint16_t
1885dfs_cocsep(
1886 cube_fast_t c,
1887 uint8_t depth,
1888 uint8_t maxdepth,
1889 uint16_t *n,
1890 uint32_t *buf32
1891)
1892{
1893 uint8_t m, t, tinv, olddepth;
1894 uint16_t cc;
1895 uint32_t oldvalue;
1896 uint64_t i;
1897 cube_fast_t d;
1898
1899 oldvalue = buf32[coord_fast_cocsep(c)];
1900 if (depth == maxdepth) {
1901 if ((oldvalue & 0xFFU) != 0xFFU)
1902 return 0;
1903
1904 for (t = 0, cc = 0; t < 48; t++) {
1905 d = transform(c, t);
1906 i = coord_fast_cocsep(d);
1907 tinv = inverse_trans(t);
1908 if ((buf32[i] & 0xFFU) == 0xFFU)
1909 cc++;
1910 buf32[i] = (*n << 16U) | (tinv << 8U) | depth;
1911 }
1912 (*n)++;
1913
1914 return cc;
1915 }
1916
1917 olddepth = (uint8_t)(oldvalue & 0xFFU);
1918 if (olddepth != depth)
1919 return 0;
1920
1921 for (m = 0, cc = 0; m < 18; m++)
1922 cc += dfs_cocsep(move(c, m), depth+1, maxdepth, n, buf32);
1923
1924 return cc;
1925}
1763 1926
1764/****************************************************************************** 1927/******************************************************************************
1765Section: solvers 1928Section: solvers
diff --git a/test/061_inverse_trans/00_all.in b/test/061_inverse_trans/00_all.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/061_inverse_trans/00_all.in
diff --git a/test/061_inverse_trans/00_all.out b/test/061_inverse_trans/00_all.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/061_inverse_trans/00_all.out
diff --git a/test/061_inverse_trans/inverse_trans_tests.c b/test/061_inverse_trans/inverse_trans_tests.c
new file mode 100644
index 0000000..77bd40b
--- /dev/null
+++ b/test/061_inverse_trans/inverse_trans_tests.c
@@ -0,0 +1,38 @@
1#include "../test.h"
2
3uint8_t readtrans(char *);
4uint8_t inverse_trans(uint8_t);
5cube_t applymoves(cube_t, char *);
6cube_t applytrans(cube_t, char *);
7extern char *transstr[];
8
9int main(void) {
10 uint8_t t, tinv;
11 cube_t cube;
12
13 for (t = 0; t < 48; t++) {
14 cube = solvedcube();
15 cube = applymoves(cube, "R");
16 cube = applymoves(cube, "U");
17 cube = applymoves(cube, "F");
18
19 cube = applytrans(cube, transstr[t]);
20 tinv = inverse_trans(t);
21 cube = applytrans(cube, transstr[tinv]);
22
23 if (iserror(cube)) {
24 printf("Error transforming cube\n");
25 } else if (!issolvable(cube)) {
26 printf("Transformed cube is not solvable\n");
27 } else {
28 cube = applymoves(cube, "F'");
29 cube = applymoves(cube, "U'");
30 cube = applymoves(cube, "R'");
31 if (!issolved(cube))
32 printf("%s: Error! Got %" PRIu8 "\n",
33 transstr[t], tinv);
34 }
35 }
36
37 return 0;
38}
diff --git a/test/100_gendata_cocsep/00_all.in b/test/100_gendata_cocsep/00_all.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/100_gendata_cocsep/00_all.in
diff --git a/test/100_gendata_cocsep/00_all.out b/test/100_gendata_cocsep/00_all.out
new file mode 100644
index 0000000..37b8c1d
--- /dev/null
+++ b/test/100_gendata_cocsep/00_all.out
@@ -0,0 +1 @@
1119788
diff --git a/test/100_gendata_cocsep/gendata_cocsep_tests.c b/test/100_gendata_cocsep/gendata_cocsep_tests.c
new file mode 100644
index 0000000..19dfa9f
--- /dev/null
+++ b/test/100_gendata_cocsep/gendata_cocsep_tests.c
@@ -0,0 +1,14 @@
1#include "../test.h"
2
3size_t gendata_cocsep(void *);
4
5int main(void) {
6 uint32_t buf[300000];
7 size_t result;
8
9 result = gendata_cocsep(buf);
10
11 printf("%zu\n", result);
12
13 return 0;
14}
diff --git a/test/test.h b/test/test.h
index 7c5400e..3cbfd10 100644
--- a/test/test.h
+++ b/test/test.h
@@ -22,5 +22,6 @@ typedef cube_t cube_fast_t;
22cube_t solvedcube(void); 22cube_t solvedcube(void);
23bool iserror(cube_t); 23bool iserror(cube_t);
24bool issolvable(cube_t); 24bool issolvable(cube_t);
25bool issolved(cube_t);
25cube_t readcube(char *, char *); 26cube_t readcube(char *, char *);
26void writecube(char *, cube_t, char *); 27void writecube(char *, cube_t, char *);

Generated with cgit - Back to sebastiano.tronto.net