If you only need to find the number of ways to select the items, then using generating functions is a way to very efficiently compute that, even for fairly large values of N and k.
If you are not familiar with generating functions, you can read up on the math background here:
http://mathworld.wolfram.com/GeneratingFunction.html
and here:
http://math.arizona.edu/~faris/combinatoricsweb/generate.pdf
The solution hinges on the fact that the number of ways to choose k
items from 36, with each of 3 items repeated 12 times, can be determined from the product of the generating function:
g(x) = 1 + x + x^2 + x^3 + ... + x^12
with itself 3 times. The 12
comes from the fact the elements are repeated 12 times (NOT from the fact you are choosing 12), and multiplying by itself 3 times is because there are three different sets of elements. The number of ways to choose 12 elements is then just the coefficient of the power of x^12 in this product of polynomials (try it for smaller examples if you want to prove to yourself that it works).
The great thing about that is that MATLAB has a simple function conv
for multiplying polynomials:
>> g = ones(1,13); %% array of 13 ones, for a 12th degree polynomial with all `1` coefficents
>> prod = conv(g, conv(g, g)); %% multiply g by itself 3 times, as a polynomial
>> prod(13)
ans =
91
So there are 91 ways to select 12 elements from your list of 36. If you want to select 11 elements, that's z(12)
= 78. If you want to select 13 elements, that's z(14)
= 102.
Finally, if you had different numbers of elements in the sets, say 10 1
's, 12 2
's, and 14 3
's, then you would have 3 distinct polynomials of the same form, 1 + x + x^2 + ...
, with degrees 10, 12 and 14 respectively. Inspecting the coefficient of the degree k
term again gives you the number of ways to choose k
elements from this set.