#include "permutation_t/permutation_t.h" #define GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(type)\ bool IS_PERMUTATION_SET_THEORIC_##type(const PERMUTATION_##type *p){\ if(p == NULL) return false;\ size_t size = p->size;\ type j;\ size_t *count_array_i = calloc(size, sizeof(size_t));\ if(count_array_i == NULL){\ printf("can't alloc count_array_i\n"); \ return false;\ }\ for(size_t i = 0; i < size; ++i){\ j = p->perm[i];\ if((COMPARE_N_##type(&j, (type*)&size) >= 0) || count_array_i[j]){\ free(count_array_i); \ return false;\ }\ ++count_array_i[j];\ }\ free(count_array_i);\ return true; \ }\ GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_CHAR) GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_INT) GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_U_L_INT) GENERATE_PERMUTATION_FUNCTIONS_UNSIGNED(TYPE_SIZE_T) int sign(long int a){ if (a<0) return -1; return 1; } #define GENERATE_PERMUTATION_FUNCTIONS(type)\ PERMUTATION_##type * CREATE_PERMUTATION_##type(size_t size){\ if (size == 0) return NULL;\ PERMUTATION_##type *p = malloc(sizeof(PERMUTATION_##type));\ p->size = size;\ p->perm = malloc(size * sizeof(type));\ return p;\ }\ PERMUTATION_##type * INIT_PERMUTATION_##type(type *perm, size_t size){\ if (size == 0) return NULL;\ PERMUTATION_##type *p = malloc(sizeof(PERMUTATION_##type));\ p->size = size;\ p->perm = perm ; /*malloc(size*sizeof(type));\ for(size_t i=0;iperm[i] = perm[i];*/\ return p;\ }\ PERMUTATION_##type * INIT_COPY_PERMUTATION_##type(type *perm, size_t size){\ if (size == 0) return NULL;\ PERMUTATION_##type *p = CREATE_PERMUTATION_##type(size);\ for(size_t i=0;iperm[i] = perm[i];\ return p;\ }\ void free_permut_##type(PERMUTATION_##type * permut){\ if(permut){\ free(permut->perm);\ free(permut);\ /*permut=NULL;*/\ }\ }\ PERMUTATION_TYPE_SIZE_T * TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(const PERMUTATION_##type *p ){\ if (p == NULL) return NULL;\ PERMUTATION_TYPE_SIZE_T *t_p = malloc(sizeof(PERMUTATION_TYPE_SIZE_T));\ size_t size = p->size;\ t_p->size = size;\ t_p->perm = malloc(size * sizeof(TYPE_SIZE_T));\ type *sorted_perm = malloc(size * sizeof(type));\ COPY_ARRAY_##type(sorted_perm,(const type*)p->perm, size);\ qsort(sorted_perm, size, sizeof(type), COMPARE_N_##type);\ for(size_t i=0; i< size; ++i)\ PRINT_DEBUG_("sorted_perm[%ld] : %s \n",i, type##_TO_STR(sorted_perm[i]));\ for(size_t j = 0; j < size; ++j){\ for(size_t i = 0; i < size; ++i){\ if(COMPARE_N_##type(&(p->perm[j]), &(sorted_perm[i])) == 0){\ t_p->perm[j]=i; break;\ }\ }\ }\ free(sorted_perm);\ return t_p; \ }\ \ bool IS_PERMUTATION_##type(const PERMUTATION_##type *p){\ if(p == NULL) return false;\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ bool ret = IS_PERMUTATION_SET_THEORIC_TYPE_SIZE_T(t_p);\ free(t_p);\ return ret; \ }\ \ int signature_##type(const PERMUTATION_##type *p){\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ int ss = 1;\ for (size_t i = 0; i < t_p->size; ++i) {\ for (size_t j = i + 1; j < t_p->size; ++j) {\ ss *= sign((long int)(t_p->perm[j]) - (long int)(t_p->perm[i]));/* sign(j - i);*/\ }\ }\ return ss;\ }\ \ \ /*complexité sz*sz/2 */\ size_t TabToPlaceAlgo_##type(const PERMUTATION_##type *p){\ size_t sz = p->size;\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ size_t *tb= t_p->perm;\ size_t pl;\ size_t* tPlace = calloc(sz,sizeof(size_t));\ for (long int i = sz - 1; i >= 0; i--) {\ pl = 0;\ for (size_t j = i + 1; j < sz; j++) {\ if (tb[j] < tb[i]) {\ pl++;\ }\ if (pl == tb[i]) break;\ }\ tPlace[tb[i]] = pl;\ }\ size_t q = 0;\ for (size_t i = 0; i < sz;i++) {\ q = (i + 1) * q + tPlace[i];\ }\ free(tPlace);\ return q;\ }\ /*complexité sz*sz/2 */\ size_t TabToPlaceOpt1_##type(const PERMUTATION_##type *p){\ size_t sz = p->size;\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ size_t *tb= t_p->perm;\ size_t mx;\ size_t* tPlace = malloc(sz*sizeof(size_t));\ for (long int i = sz - 1; i >= 0; i--) {\ if (i == sz - 1) {\ mx = tb[i];\ tPlace[mx] = 0;\ }\ else if (mx > tb[i]) {\ size_t pli = 0; /* si c est le plus à droite 0 si pas de superieur à lui, on incremente si on trouve plus petit*/\ for (long int j = sz - 1; j > i; j--) {\ if (tb[i] > tb[j]) {\ pli++;\ }\ else if (tb[i] == tb[j]) {\ PRINT_DEBUG_("%s\n","something wrong here, tb[i]==tb[j]");\ }\ }\ tPlace[tb[i]] = pli;\ }\ else if (mx < tb[i]) {\ mx = tb[i];\ tPlace[mx] = sz - 1 - i;\ }\ else {\ PRINT_DEBUG_("%s\n","something wrong here, tb[i]==mx");\ \ }\ }\ size_t q = 0;\ for (long int i = 0; i < sz; i++) {\ q = (i + 1) * q + tPlace[i];\ }\ free(tPlace);\ return q;\ }\ /* complexité sz*(sz+1)*/\ size_t TabToPlaceNotab_##type(const PERMUTATION_##type *p){\ size_t sz = p->size;\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ size_t *tb= t_p->perm;\ size_t mx = sz - 1;\ size_t q = 0;\ size_t pl;\ for (long int i = 0; i < sz; i++) {\ size_t j;\ for (j = 0; j < sz;j++) {\ if (tb[j] == i) break;\ }\ pl = 0;\ j++;\ for (;j < sz;j++) {\ if (tb[j] < i) {\ pl++;\ }\ if (pl == i) break;\ }\ q = (i + 1) * q + pl;\ }\ return q;\ }\ /*complexité sz*sz/2 */\ PERMUTATION_TYPE_SIZE_T * PlaceToTab_##type(PERMUTATION_##type *p, size_t pl){\ size_t sz = p->size;\ /*PERMUTATION_TYPE_SIZE_T *t_p = CREATE_PERMUTATION_TYPE_SIZE_T(sz);*/\ PERMUTATION_TYPE_SIZE_T *t_p = TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(p);\ type *save_perm = malloc(sz*sizeof(type));\ long int *tb= t_p->perm;\ size_t a = pl;\ size_t pltbi;\ for (long int i = 0;i < sz;i++) {\ save_perm[tb[i]]=p->perm[i];/*to save initial order (rank 0) of p->perm */\ /*PRINT_DEBUG_("%ld => %s \n",tb[i],type##_TO_STR(p->perm[i]));*/\ tb[i]=0;\ }\ \ for (long int i = sz - 1; i >= 0; i--) {\ pltbi = a % (i + 1);\ a /= (i + 1);\ if (i == sz - 1) {\ tb[sz - 1 - pltbi] = i;\ }\ else {\ long int lt = 0, j = sz - 1;\ while (lt < pltbi && j >= 0) {\ if (tb[j--] < i) {\ lt++;\ }\ }\ while (tb[j] > i) {\ j--;\ }\ tb[j] = i;\ }\ }\ \ for (long int i = 0;i < sz;i++) p->perm[i] = save_perm[tb[i]];\ free(save_perm);\ return t_p;\ }\ \ GENERATE_PERMUTATION_FUNCTIONS(TYPE_CHAR) GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_CHAR) GENERATE_PERMUTATION_FUNCTIONS(TYPE_INT) GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_INT) GENERATE_PERMUTATION_FUNCTIONS(TYPE_L_INT) GENERATE_PERMUTATION_FUNCTIONS(TYPE_U_L_INT) GENERATE_PERMUTATION_FUNCTIONS(TYPE_SIZE_T) GENERATE_PERMUTATION_FUNCTIONS(TYPE_FLOAT) GENERATE_PERMUTATION_FUNCTIONS(TYPE_DOUBLE) GENERATE_PERMUTATION_FUNCTIONS(TYPE_L_DOUBLE) GENERATE_PERMUTATION_FUNCTIONS(TYPE_STRING) /* why TRANSLATE ? * 2,7,4,1 is a permutation of 1,2,4,7 *it is equivalent of 1,3,2,0 in set_theoric(4)=0,1,2,3 this function calculate the permutation equivalent in set_theoric 2,4,2,5 is translate to 0,1,0,2 2,4,7,5 is translate to 0,1,3,2 PERMUTATION_TYPE_SIZE_T * TRANSLATE_TO_SET_THEORIC_SIZE_T_##type(const PERMUTATION_##type *p ); * */ /* if need optimization in translate #define GENERATE_UNSIGNED_SIZE_WITH_TYPED(type_unsigned, type)\ PERMUTATION_##type_unsigned * TRANSLATE_TO_SET_THEORIC_##type_unsigned_##type(PERMUTATION_##type *p ){\ if (p == NULL) return NULL;\ PERMUTATION_##type_unsigned *t_p = malloc(sizeof(PERMUTATION_##type_unsigned));\ type_unsigned size = p->size;\ t_p->perm = malloc(size * sizeof(type_unsigned));\ type *sorted_perm = malloc(size * sizeof(type));\ COPY_ARRAY_##type(sorted_perm, p->perm, size);\ qsort(sorted_perm, size, sizeof(type), COMPARE_N_##type);\ type_unsigned *rec_index_visited = malloc(size * sizeof(type_unsigned));\ type_unsigned cur_rec = 0; bool found_rec;\ for(type_unsigned i = 0; i < size; ++i){\ for(type_unsigned j = 0; j < size; ++j){\ if(COMPARE_N_##type(&(p->perm[j]), &(sorted_perm[i])) == 0){\ found_rec = false;\ for(type_unsigned k = 0; k < cur_rec; ++k){\ if(rec_index_visited[k] == j){\ found_rec == true; break; } } \ if(found_rec == false){\ t_p->perm[i] = j;\ rec_index_visited[cur++] = j; \ break; } } } } \ free(rec_index_visited);\ free(sorted_perm);\ return t_p; }\ */