nissy-nx

A Rubik's cube optimal solver
git clone https://git.tronto.net/nissy-nx
Download | Log | Files | Refs | README | LICENSE

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