組み合わせの列挙

nCrを列挙するコードです。こちらのサイトを参考にしました。
http://park7.wakwak.com/~efc21/cgi-bin/exqalounge.cgi?print+201004/10040015.txt
再帰でこんなにシンプルに書けるとは驚きです。
こういうアルゴリズムを考えつく人は本当にすごいと思います。
特に、コードをシンプルにするために、データの表記の方法から
考えるというのは計算幾何学屋らしいと思う。

int num = 0;

void combi(int A[], int p, int w, int n, int r)
{
	if(p > 0)
	{
		int i;
		for(i = 0;i <= w;i++)
		{
			A[p] = i;
			combi(A, p - 1, w - i, n, r);
		}
	} else {
		int i, j, m;
		num++;
		printf("%d:\t", num);
		m = 0;
		for(i = 1;i <= r;i++){
			for(j = 0;j < A[i];j++, m++)
				printf("0");
			printf("1");
			m++;
		}
		for(;m < n;m++)
			printf("0");
		printf("\n");
	}
}

int main(void)
{
	int n = 8;
	int r = 5;
	int K[256];

	combi(K, r, n-r, n, r);
	return 0;
}

結果はこんな感じ。

1:      11100000
2:      01110000
3:      00111000
4:      00011100
5:      00001110
6:      00000111
7:      10110000
8:      01011000
9:      00101100
10:     00010110
11:     00001011
12:     10011000
13:     01001100