nissy-classic

Stable branch of nissy
git clone https://git.tronto.net/nissy-classic
Download | Log | Files | Refs | README | LICENSE

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