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

Generated with cgit - Back to sebastiano.tronto.net