#include #include #include #include /* Implementation of various combinatorial enumeration algorithms. */ /* Returns the key associated with the permutation in P. P is destroyed in the process. */ int perm_to_key(int* P, const int n) { int i, K=0, m=1, j; /* Convert to the compressed representation */ for (i=n-1; i>=0; --i) { for (j=i-1; j>=0; --j) if (P[j] > P[i]) --P[j]; } /* Get the key */ for (j=1; j=0; --j) { d = P[n + P[j]]; for (i=P[j]; i=0; --j) { P = 0; for (i=0; i B[0]) { p = 0; return NULL; } else { Q = (int*)malloc(sizeof(int)); Q[0] = n; *p = 1; return Q; } } /* The number of distinct values for the first position. */ M = (B[0] < n) ? B[0] : n; /* P[j] will hold the list for positions 1..k-1 when position 0 has value j. */ P = (int**)malloc((M+1)*sizeof(int*)); /* q[j] holds the number of rows in P[j]. */ q = (int*)malloc((M+1)*sizeof(int)); /* Keep track of the total number of rows. */ *p = 0; /* Loop over the possible values of the first component and recur to get the rest. */ for (j=0; j<=M; ++j) { m = n-j; P[j] = list_partitions(m, k-1, B+1, &q[j]); *p += q[j]; } /* Merge P into a single array. */ Q = (int*)malloc((*p)*k*sizeof(int)); R = Q; for (j=0; j<=M; ++j) { for (i=0; i