/* picks.c -- generate the N!/n! picks of n items from N * * int n, N; * int pick[n]; * int process_pick(); * if (picks(n, N, pick, process_pick)) error... * * picks generates the N!/n! different ways of picking n items from a * total of N and calls a user-supplied routine process_pick for each * one. process_pick is called using: * * int n, N; * int pick[n]; * if (process_pick(n, N, pick)) error... * * It should return 0 if there is no error, 1 if there is some sort of * error. If process_pick returns non-zero, picks will return * immediately, without processing any further picks, and its return * value will be whatever non-zero value process_picks returned. If the * values passed to pick are erroneous, (i.e., n<0, N<0, n>N), picks * immediately returns -1. * * picks passed to process_pick are arrays of n distinct integers, each ranging * from 0 to N-1, and sorted (i.e., pick[0] < pick[1] ... < pick[n-1]). */ #include #include "common.h" #define ERR (-1) #define OK (0) static int dopicks(); int picks(n, N, pick, process_pick) int n, N; int pick[]; int (*process_pick)(); { if ( /* make sure values valid */ (n < 0) || (N < 0) || (N < n) ) return(ERR); if (0 == n) { /* trivial case */ return((*process_pick)(n, N, pick)); } return(dopicks(n, N, n, N, pick, process_pick)); } /* dopicks -- recursively called internal routine to generate picks */ static int dopicks(n, N, cn, cN, pick, process_pick) int n, N; /* global n, N */ int cn, cN; /* current n, N */ register int pick[]; register int (*process_pick)(); { register int i; register int e; if (1 == cn) { /* bottom out if only one left */ for(i=0; i