//////// // Utilities for factorial, permutation, and other numeric functions // #include "Utilities.h" #include // has long division stuff static int DoInitNow=1; // flag to test if init has been done static long factTable[MaxArrayAndArg+1]; // the saved values of the function, 0...MFA // computes 'em and puts 'em in a table for later access void InitFactorial(); void InitFactorial(){ DoInitNow=0; // turn off initialization flag factTable[0]=1; for (int i=1;i<=MaxArrayAndArg;i++) factTable[i]=i*factTable[i-1]; } // pulls the factorial out of the table. Calls InitFactorial if we haven't yet. long Factorial(int n){ if (DoInitNow) InitFactorial(); if (n>MaxArrayAndArg) return(-1); return(factTable[n]); } // The calling routine has an array of ints something like this: // int inArray[N=4] = [1,2,3,0], say. // Given the first digit, there are 3! ways the next three // can be rearraged, so I let the first digit be count 1*3! towards the answer. // I then renumber the remaining [2,3,0] to [1,2,0], by // subtracting 1 from all the numbers greater than the 1 // we've already found. // The first procedure is then repeated // on each successive sub-array. We must have N < MaxSize // or we simply exit with an error of -1. long Permutation2Number(int inArray[], int N){ int localArray[MaxArrayAndArg]; // local copy of the input. long answer=0; if (N>MaxArrayAndArg) return(-1); // error exit for (int i=0;ilocalArray[i]) localArray[j]=localArray[j]-1; } return(answer); } // The inverse function, which fills in outArray to the permuation // given by the input long int x. // On the first loop, the input // x is divided by (N-1)!, (N-2)!, and so on to get // the 1st, 2nd, etc. digits before renumbering. // Then on the second loop we go right to left, opposite of the original encoding, // increasing the numbers bigger than what has already // been seen, so that all the numbers are different. void Number2Permutation(int outArray[], long x, int N){ ldiv_t dividend; for (int i=0;i=0;i--) for (int j=i+1;j=outArray[i]) outArray[j]=outArray[j]+1; } } // Convert a number in a given base to a long int. // On input, the N entries in inArray are each 0...(Base-1). // If N>MaxArrayAndArg, then -1 is returned to signal the error. long Base2Number(int inArray[], int Base, int N){ long answer=0; long ithPower=1; for (int i=N-1;i>=0;i--){ answer = answer+ithPower*inArray[i]; ithPower=ithPower*Base; } return(answer); } long longPower(long x, int n); // returns x^n. long longPower(long x, int n){ long answer=1; for (int i=0;i