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