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