aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-07-04 17:09:55 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-07-04 17:09:55 +0200
commit518d98ad5f9eec0cf4124375bdbb84d1296b3f3f (patch)
tree467b2b0387f23a0b379cf428c6883937ec18c134 /src
parent425eee24421bf0a19c7e0199d2e3ecba3318c8f4 (diff)
downloadnissy-core-518d98ad5f9eec0cf4124375bdbb84d1296b3f3f.tar.gz
nissy-core-518d98ad5f9eec0cf4124375bdbb84d1296b3f3f.zip
(almost) added getcube
Diffstat (limited to 'src')
-rw-r--r--src/constants.h4
-rw-r--r--src/cube.c1
-rw-r--r--src/cube.h7
-rw-r--r--src/cube_generic.h59
-rw-r--r--src/cube_public.h30
-rw-r--r--src/io_cube.h11
-rw-r--r--src/utils.h125
7 files changed, 205 insertions, 32 deletions
diff --git a/src/constants.h b/src/constants.h
index c8909d7..52e2810 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -2,10 +2,14 @@
2#define _bit_u32(i) (UINT32_C(1) << (uint32_t)(i)) 2#define _bit_u32(i) (UINT32_C(1) << (uint32_t)(i))
3#define _bit_u64(i) (UINT64_C(1) << (uint64_t)(i)) 3#define _bit_u64(i) (UINT64_C(1) << (uint64_t)(i))
4 4
5#define _max_factorial INT64_C(12)
6
5#define _2p11 INT64_C(2048) 7#define _2p11 INT64_C(2048)
6#define _2p12 INT64_C(4096) 8#define _2p12 INT64_C(4096)
7#define _3p7 INT64_C(2187) 9#define _3p7 INT64_C(2187)
8#define _3p8 INT64_C(6561) 10#define _3p8 INT64_C(6561)
11#define _12f INT64_C(479001600)
12#define _8f INT64_C(40320)
9#define _12c4 INT64_C(495) 13#define _12c4 INT64_C(495)
10#define _8c4 INT64_C(70) 14#define _8c4 INT64_C(70)
11 15
diff --git a/src/cube.c b/src/cube.c
index 54876a7..1f8711c 100644
--- a/src/cube.c
+++ b/src/cube.c
@@ -21,6 +21,7 @@ void (*nissy_log)(const char *, ...);
21#endif 21#endif
22 22
23#include "constants.h" 23#include "constants.h"
24#include "utils.h"
24 25
25#if defined(CUBE_AVX2) 26#if defined(CUBE_AVX2)
26#include <immintrin.h> 27#include <immintrin.h>
diff --git a/src/cube.h b/src/cube.h
index d3d096a..28737c4 100644
--- a/src/cube.h
+++ b/src/cube.h
@@ -41,8 +41,11 @@ int64_t nissy_convert(
41 char *result 41 char *result
42); 42);
43 43
44int64_t nissy_gencube( 44int64_t nissy_getcube(
45 uint8_t id[16], 45 int64_t ep,
46 int64_t eo,
47 int64_t cp,
48 int64_t co,
46 const char *options, 49 const char *options,
47 char result[static 22] 50 char result[static 22]
48); 51);
diff --git a/src/cube_generic.h b/src/cube_generic.h
index 7095c3a..c40844d 100644
--- a/src/cube_generic.h
+++ b/src/cube_generic.h
@@ -1,6 +1,7 @@
1#define _move(M, c) compose(c, _move_cube_ ## M) 1#define _move(M, c) compose(c, _move_cube_ ## M)
2#define _premove(M, c) compose(_move_cube_ ## M, c) 2#define _premove(M, c) compose(_move_cube_ ## M, c)
3 3
4_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
4_static cube_t solvedcube(void); 5_static cube_t solvedcube(void);
5_static bool isconsistent(cube_t); 6_static bool isconsistent(cube_t);
6_static bool issolvable(cube_t); 7_static bool issolvable(cube_t);
@@ -9,14 +10,24 @@ _static bool iserror(cube_t);
9_static cube_t applymoves(cube_t, const char *); 10_static cube_t applymoves(cube_t, const char *);
10_static cube_t applytrans(cube_t, const char *); 11_static cube_t applytrans(cube_t, const char *);
11_static cube_t frommoves(const char *); 12_static cube_t frommoves(const char *);
13_static void getcube_fix(int64_t *, int64_t *, int64_t *, int64_t *);
14_static cube_t getcube(int64_t, int64_t, int64_t, int64_t);
12 15
13_static int permsign(uint8_t *, int);
14_static cube_t move(cube_t, uint8_t); 16_static cube_t move(cube_t, uint8_t);
15_static cube_t transform_edges(cube_t, uint8_t); 17_static cube_t transform_edges(cube_t, uint8_t);
16_static cube_t transform_corners(cube_t, uint8_t); 18_static cube_t transform_corners(cube_t, uint8_t);
17_static cube_t transform(cube_t, uint8_t); 19_static cube_t transform(cube_t, uint8_t);
18 20
19_static cube_t 21_static cube_t
22cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
23{
24 return static_cube(
25 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
26 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
27 e[8], e[9], e[10], e[11]);
28}
29
30_static cube_t
20solvedcube(void) 31solvedcube(void)
21{ 32{
22 return solved; 33 return solved;
@@ -171,6 +182,39 @@ frommoves(const char *buf)
171 return applymoves(solved, buf); 182 return applymoves(solved, buf);
172} 183}
173 184
185_static void
186getcube_fix(int64_t *ep, int64_t *eo, int64_t *cp, int64_t *co)
187{
188 uint8_t e[12], c[8], aux;
189
190 *ep %= _12f;
191 *eo %= _2p11;
192 *cp %= _8f;
193 *cp %= _3p7;
194
195 indextoperm(*ep, 12, e);
196 indextoperm(*cp, 8, c);
197 if (permsign(e, 12) != permsign(c, 8)) {
198 aux = c[0];
199 c[0] = c[1];
200 c[1] = aux;
201 *cp = permtoindex(c, 8);
202 }
203}
204
205_static cube_t
206getcube(int64_t ep, int64_t eo, int64_t cp, int64_t co)
207{
208 uint8_t e[12], c[8];
209
210 indextoperm(ep, 12, e);
211 indextoperm(cp, 8, c);
212
213 /* TODO: orientation */
214
215 return cubefromarray(c, e);
216}
217
174_static cube_t 218_static cube_t
175applytrans(cube_t cube, const char *buf) 219applytrans(cube_t cube, const char *buf)
176{ 220{
@@ -184,19 +228,6 @@ applytrans(cube_t cube, const char *buf)
184 return transform(cube, t); 228 return transform(cube, t);
185} 229}
186 230
187_static int
188permsign(uint8_t *a, int n)
189{
190 int i, j;
191 uint8_t ret = 0;
192
193 for (i = 0; i < n; i++)
194 for (j = i+1; j < n; j++)
195 ret += a[i] > a[j] ? 1 : 0;
196
197 return ret % 2;
198}
199
200_static cube_t 231_static cube_t
201move(cube_t c, uint8_t m) 232move(cube_t c, uint8_t m)
202{ 233{
diff --git a/src/cube_public.h b/src/cube_public.h
index fe003c9..b537019 100644
--- a/src/cube_public.h
+++ b/src/cube_public.h
@@ -2,6 +2,16 @@
2 2
3_static int64_t write_result(cube_t, char [static 22]); 3_static int64_t write_result(cube_t, char [static 22]);
4 4
5/* TODO: add option to get DR, maybe C-only, E-only, eo... */
6#define GETCUBE_OPTIONS(S, F) { .option = S, .fix = F }
7struct {
8 char *option;
9 void (*fix)(int64_t *, int64_t *, int64_t *, int64_t *);
10} getcube_options[] = {
11 GETCUBE_OPTIONS("fix", getcube_fix),
12 GETCUBE_OPTIONS(NULL, NULL)
13};
14
5_static int64_t 15_static int64_t
6write_result(cube_t cube, char result[static 22]) 16write_result(cube_t cube, char result[static 22])
7{ 17{
@@ -105,15 +115,25 @@ nissy_convert(
105} 115}
106 116
107int64_t 117int64_t
108nissy_gencube( 118nissy_getcube(
109 uint8_t id[16], 119 int64_t ep,
120 int64_t eo,
121 int64_t cp,
122 int64_t co,
110 const char *options, 123 const char *options,
111 char result[static 22] 124 char result[static 22]
112) 125)
113{ 126{
114 /* TODO: compute cube from id % (number of positions) */ 127 int i;
115 /* options can be used for generating e.g. DR-state cube */ 128 cube_t c;
116 return -1; 129
130 for (i = 0; getcube_options[i].option != NULL; i++)
131 if (!strcmp(options, getcube_options[i].option))
132 getcube_options[i].fix(&ep, &eo, &cp, &co);
133
134 c = getcube(ep, eo, cp, co);
135
136 return write_result(c, result);
117} 137}
118 138
119int64_t 139int64_t
diff --git a/src/io_cube.h b/src/io_cube.h
index 95c1882..956494d 100644
--- a/src/io_cube.h
+++ b/src/io_cube.h
@@ -1,5 +1,3 @@
1_static cube_t cubefromarray(uint8_t [static 8], uint8_t [static 12]);
2
3_static uint8_t readco(const char *); 1_static uint8_t readco(const char *);
4_static uint8_t readcp(const char *); 2_static uint8_t readcp(const char *);
5_static uint8_t readeo(const char *); 3_static uint8_t readeo(const char *);
@@ -31,15 +29,6 @@ _static struct {
31 { .name = "NONE", .read = NULL, .write = NULL }, 29 { .name = "NONE", .read = NULL, .write = NULL },
32}; 30};
33 31
34_static_inline cube_t
35cubefromarray(uint8_t c[static 8], uint8_t e[static 12])
36{
37 return static_cube(
38 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
39 e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7],
40 e[8], e[9], e[10], e[11]);
41}
42
43cube_t 32cube_t
44readcube(const char *format, const char *buf) 33readcube(const char *format, const char *buf)
45{ 34{
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..0c0b4d1
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,125 @@
1_static int64_t factorial(int64_t);
2_static bool isperm(uint8_t *, int64_t);
3_static int64_t permtoindex(uint8_t *, int64_t);
4_static void indextoperm(int64_t, int64_t, uint8_t *);
5_static int permsign(uint8_t *, int64_t);
6
7_static int64_t
8factorial(int64_t n)
9{
10 int64_t i, ret;
11
12 if (n > _max_factorial) {
13 LOG("Error: won't compute factorial for n=%" PRId64 " because"
14 " it is larger than %" PRId64 "\n", n, _max_factorial);
15 return -1;
16 }
17
18 if (n < 0)
19 return 0;
20
21 for (i = 1, ret = 1; i <= n; i++)
22 ret *= i;
23
24 return ret;
25}
26
27_static bool
28isperm(uint8_t *a, int64_t n)
29{
30 int64_t i;
31 bool aux[_max_factorial+1];
32
33 if (n > _max_factorial) {
34 LOG("Error: won't compute 'isperm()' for n=%" PRId64 " because"
35 " it is larger than %" PRId64 "\n", n, _max_factorial);
36 return false;
37 }
38
39 memset(aux, false, n);
40
41 for (i = 0; i < n; i++) {
42 if (a[i] < 0 || a[i] >= n)
43 return false;
44 else
45 aux[a[i]] = true;
46 }
47
48 for (i = 0; i < n; i++)
49 if (!aux[i])
50 return false;
51
52 return true;
53}
54
55_static int64_t
56permtoindex(uint8_t *a, int64_t n)
57{
58 int64_t i, j, c, ret;
59
60 if (n > _max_factorial) {
61 LOG("Error: won't compute 'permtoindex()' for n=%" PRId64
62 " because it is larger than %" PRId64 "\n",
63 n, _max_factorial);
64 return -1;
65 }
66
67 if (!isperm(a, n))
68 return -1;
69
70 for (i = 0, ret = 0; i < n; i++) {
71 for (j = i+1, c = 0; j < n; j++)
72 c += (a[i] > a[j]) ? 1 : 0;
73 ret += factorial(n-i-1) * c;
74 }
75
76 return ret;
77}
78
79_static void
80indextoperm(int64_t p, int64_t n, uint8_t *r)
81{
82 int64_t i, j, c;
83 uint8_t a[_max_factorial+1];
84
85 if (n > _max_factorial) {
86 LOG("Error: won't compute 'permtoindex()' for n=%" PRId64
87 " because it is larger than %" PRId64 "\n",
88 n, _max_factorial);
89 goto indextoperm_error;
90 }
91
92 memset(a, 0, n);
93
94 if (p < 0 || p >= factorial(n))
95 goto indextoperm_error;
96
97 for (i = 0; i < n; i++) {
98 for (j = 0, c = 0; c <= p / factorial(n-i-1); j++)
99 c += a[j] ? 0 : 1;
100 r[i] = j-1;
101 a[j-1] = 1;
102 p %= factorial(n-i-1);
103 }
104
105 if (!isperm(r, n))
106 goto indextoperm_error;
107
108 return;
109
110indextoperm_error:
111 memset(r, _error, n);
112}
113
114_static int
115permsign(uint8_t *a, int64_t n)
116{
117 int i, j;
118 uint8_t ret;
119
120 for (i = 0, ret = 0; i < n; i++)
121 for (j = i+1; j < n; j++)
122 ret += a[i] > a[j] ? 1 : 0;
123
124 return ret % 2;
125}

Generated with cgit - Back to sebastiano.tronto.net