aboutsummaryrefslogtreecommitdiff
path: root/old/2021-11-10-beforeremovingchecker/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'old/2021-11-10-beforeremovingchecker/utils.c')
-rw-r--r--old/2021-11-10-beforeremovingchecker/utils.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/old/2021-11-10-beforeremovingchecker/utils.c b/old/2021-11-10-beforeremovingchecker/utils.c
new file mode 100644
index 0000000..f72a00e
--- /dev/null
+++ b/old/2021-11-10-beforeremovingchecker/utils.c
@@ -0,0 +1,274 @@
1#include "utils.h"
2
3void
4apply_permutation(int *perm, int *set, int n)
5{
6 int *aux = malloc(n * sizeof(int));
7 int i;
8
9 if (!is_perm(perm, n))
10 return;
11
12 for (i = 0; i < n; i++)
13 aux[i] = set[perm[i]];
14
15 memcpy(set, aux, n * sizeof(int));
16 free(aux);
17}
18
19int
20binomial(int n, int k)
21{
22 if (n < 0 || k < 0 || k > n)
23 return 0;
24
25 return factorial(n) / (factorial(k) * factorial(n-k));
26}
27
28int
29digit_array_to_int(int *a, int n, int b)
30{
31 int i, ret = 0, p = 1;
32
33 for (i = 0; i < n; i++, p *= b)
34 ret += a[i] * p;
35
36 return ret;
37}
38
39int
40factorial(int n)
41{
42 int i, ret = 1;
43
44 if (n < 0)
45 return 0;
46
47 for (i = 1; i <= n; i++)
48 ret *= i;
49
50 return ret;
51}
52
53void
54index_to_perm(int p, int n, int *r)
55{
56 int *a = malloc(n * sizeof(int));
57 int i, j, c;
58
59 for (i = 0; i < n; i++)
60 a[i] = 0;
61
62 if (p < 0 || p >= factorial(n))
63 for (i = 0; i < n; i++)
64 r[i] = -1;
65
66 for (i = 0; i < n; i++) {
67 c = 0;
68 j = 0;
69 while (c <= p / factorial(n-i-1))
70 c += a[j++] ? 0 : 1;
71 r[i] = j-1;
72 a[j-1] = 1;
73 p %= factorial(n-i-1);
74 }
75
76 free(a);
77}
78
79void
80index_to_subset(int s, int n, int k, int *r)
81{
82 int i, j, v;
83
84 if (s < 0 || s >= binomial(n, k)) {
85 for (i = 0; i < n; i++)
86 r[i] = -1;
87 return;
88 }
89
90 for (i = 0; i < n; i++) {
91 if (k == n-i) {
92 for (j = i; j < n; j++)
93 r[j] = 1;
94 return;
95 }
96
97 if (k == 0) {
98 for (j = i; j < n; j++)
99 r[j] = 0;
100 return;
101 }
102
103 v = binomial(n-i-1, k);
104 if (s >= v) {
105 r[i] = 1;
106 k--;
107 s -= v;
108 } else {
109 r[i] = 0;
110 }
111 }
112}
113
114void
115int_to_digit_array(int a, int b, int n, int *r)
116{
117 int i;
118
119 if (b <= 1)
120 for (i = 0; i < n; i++)
121 r[i] = 0;
122 else
123 for (i = 0; i < n; i++, a /= b)
124 r[i] = a % b;
125}
126
127void
128int_to_sum_zero_array(int x, int b, int n, int *a)
129{
130 int i, s = 0;
131
132 if (b <= 1) {
133 for (i = 0; i < n; i++)
134 a[i] = 0;
135 } else {
136 int_to_digit_array(x, b, n-1, a);
137 for (i = 0; i < n - 1; i++)
138 s = (s + a[i]) % b;
139 a[n-1] = (b - s) % b;
140 }
141}
142
143int
144invert_digits(int a, int b, int n)
145{
146 int i, ret, *r = malloc(n * sizeof(int));
147
148 int_to_digit_array(a, b, n, r);
149 for (i = 0; i < n; i++)
150 r[i] = (b-r[i]) % b;
151
152 ret = digit_array_to_int(r, n, b);
153 free(r);
154 return ret;
155}
156
157bool
158is_perm(int *a, int n)
159{
160 int *aux = malloc(n * sizeof(int));
161 int i;
162
163 for (i = 0; i < n; i++)
164 if (a[i] < 0 || a[i] >= n)
165 return false;
166 else
167 aux[a[i]] = 1;
168
169 for (i = 0; i < n; i++)
170 if (!aux[i])
171 return false;
172
173 free(aux);
174
175 return true;
176}
177
178bool
179is_subset(int *a, int n, int k)
180{
181 int i, sum = 0;
182
183 for (i = 0; i < n; i++)
184 sum += a[i] ? 1 : 0;
185
186 return sum == k;
187}
188
189int
190perm_sign(int *a, int n)
191{
192 int i, j, ret = 0;
193
194 if (!is_perm(a,n))
195 return -1;
196
197 for (i = 0; i < n; i++)
198 for (j = i+1; j < n; j++)
199 ret += (a[i] > a[j]) ? 1 : 0;
200
201 return ret % 2;
202}
203
204int
205perm_to_index(int *a, int n)
206{
207 int i, j, c, ret = 0;
208
209 if (!is_perm(a, n))
210 return -1;
211
212 for (i = 0; i < n; i++) {
213 c = 0;
214 for (j = i+1; j < n; j++)
215 c += (a[i] > a[j]) ? 1 : 0;
216 ret += factorial(n-i-1) * c;
217 }
218
219 return ret;
220}
221
222int
223powint(int a, int b)
224{
225 if (b < 0)
226 return 0;
227 if (b == 0)
228 return 1;
229
230 if (b % 2)
231 return a * powint(a, b-1);
232 else
233 return powint(a*a, b/2);
234}
235
236int
237subset_to_index(int *a, int n, int k)
238{
239 int i, ret = 0;
240
241 if (!is_subset(a, n, k))
242 return binomial(n, k);
243
244 for (i = 0; i < n; i++) {
245 if (k == n-i)
246 return ret;
247 if (a[i]) {
248 ret += binomial(n-i-1, k);
249 k--;
250 }
251 }
252
253 return ret;
254}
255
256void
257sum_arrays_mod(int *src, int *dst, int n, int m)
258{
259 int i;
260
261 for (i = 0; i < n; i++)
262 dst[i] = (m <= 0) ? 0 : (src[i] + dst[i]) % m;
263}
264
265void
266swap(int *a, int *b)
267{
268 int aux;
269
270 aux = *a;
271 *a = *b;
272 *b = aux;
273}
274

Generated with cgit - Back to sebastiano.tronto.net