/************************************************************************ This ANSI C program prints all (n choose m) = n!/m!/(n-m)! combinations of 'n' different items on the standard output. usage: choose n m [nitems] where 1 <= m <= n are two integers, and the items can optionally be given 1-character representations. If the 'nitems' are not provided explicitly, the alphabetical letters 'a', 'b', 'c' etc are chosen. Richard J Mathar, 11/23/2003 examples: choose 10 4 prints 210 lines abcd abce abcf abcg abch abci abcj abde abdf abdg ... choose 10 3 prints 120 lines abc abd abe abf abg abh abi abj acd ace ... fhj fij ghi ghj gij hij choose 8 4 AEIOULMN prints 70 lines AEIO AEIU AEIL AEIM AEIN AEOU AEOL AEOM AEON AEUL AEUM .. OUMN OLMN ULMN *******************************************************************/ #include #include #include void combin(const char const *letts,int mark, int n, int mleft, int *taken) { if( mleft > n -mark ) return ; else if( mleft > 0) { taken[mark]=1 ; combin(letts,mark+1,n,mleft-1,taken) ; taken[mark]=0 ; combin(letts,mark+1,n,mleft,taken) ; } else { for(int i=0 ; i < n; i++) if( taken[i] ) printf("%c",letts[i]) ; printf("\n") ; } } int main(int argc, char *argv[]) { int n,m ,*taken; char * letts ; if (argc < 3 ) { printf("usage: %s n m [letters]\n",argv[0]) ; exit(EXIT_FAILURE) ; } n=atoi(argv[1]) ; m=atoi(argv[2]) ; if( m > n) { printf("Second argument %d must be <= first one %d\n",m,n) ; exit(EXIT_FAILURE) ; } if (argc == 3 ) { letts = malloc(n*sizeof(char)) ; for(int i=0 ; i < n; i++) letts[i] = i+'a' ; } else { if( n != strlen(argv[3]) ) { printf("Third argument does not have %d characters\n",n) ; exit(EXIT_FAILURE) ; } letts = argv[3] ; } taken=malloc(n*sizeof(int)) ; combin(letts,0,n,m,taken) ; free(taken) ; if( argc == 3) free(letts) ; }