aboutsummaryrefslogtreecommitdiff
path: root/src/utils.h
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/utils.h
parent425eee24421bf0a19c7e0199d2e3ecba3318c8f4 (diff)
downloadnissy-core-518d98ad5f9eec0cf4124375bdbb84d1296b3f3f.tar.gz
nissy-core-518d98ad5f9eec0cf4124375bdbb84d1296b3f3f.zip
(almost) added getcube
Diffstat (limited to 'src/utils.h')
-rw-r--r--src/utils.h125
1 files changed, 125 insertions, 0 deletions
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