/* pick.c -- evaluate N!/(n! (N-n)!) * * long p; * int N, n; * p = pick(N, n); * * pick returns the number of ways of picking n distinct elements from a * total of N. */ #include #include "common.h" #include "logs.h" double log(); /* natural logarithms */ int gcf(); /* greatest common factor */ long pick(N, n) int N, n; { register int i; register int f; register int g; register long p = 1L; if ( /* make sure values valid */ (n < 0) || (N < 0) || (N < n) ) return(0L); if (n > N-n) n = N-n; for(i=1; i<=n; i++) { f = N+1 - i; g = gcf(f, i); f /= g; p /= i/g; p *= f; } return(p); } /* logpick -- evaluate ln( N!/(n! (N-n)!) ) * * double lp; * int N, n; * lp = logpick(N, n); * * pick returns the natural logarithm of the number of ways of picking * n distinct elements from a total of N. It can be used where pick * would overflow. */ double logpick(N, n) int N, n; { register int i; register int f; register double lp = LOG1; if ( /* make sure values valid */ (n < 0) || (N < 0) || (N < n) ) return(LOG0); if (n > N-n) n = N-n; for(i=1; i<=n; i++) { f = N+1 - i; lp += logint(f) - logint(i); } if (lp < LOG1) lp = LOG1; return(lp); }