1

It would seem that a preceding query would be on point, but not really for me. One of the answers comes close, but it isn't complete as is. Since the answer is going to be an integer, all the factors in the denominator will cancel. Prime factors can be eliminated by any factor in the numerator that is a multiple. The problem is composites; canceling them out may involve multiple numerator factors that share primes. And there's the auxiliary problem of determining prime factors from composite ones (i.e. which composite factor(s) in the numerator should I cancel a composite factor in the denominator against).

I'm thinking of an analogy with computing the greatest common divisor of two positive integers. You could determine GCD by breaking both arguments into their prime factorizations, then use the minimum exponent for each prime. But using something like Euclid's algorithm is a lot easier. For a multinomial coefficient, I could run a Sieve of Eratosthenes up to the numerator's maximum factor, use that table to get all the applicable prime factorizations, then do a bunch of cancelling, but that seems like a lot of work. Is there a procedure similar to Euclid's GCD one that we can make for binomial coefficients?

CTMacUser
  • 201
  • I don't understand your question. Why are the linked question's answers not satisfactory? Why are you concerning yourself with prime factorization? As you say, we know that the binomial coefficient will always be an integer so there is no reason to manually verify that the factors in the denominator are also present in the numerator before attempting to cancel since we know that it must always be the case that they are. – JMoravitz Dec 03 '19 at 02:22
  • @JMoravitz, I'm asking how to do the canceling. For instance, we can calculate C(8, 4) with (8765)/(4321). I can eyeball that equation and see where to cancel all the factors in the denominator. A computer program can't do that in general, not without building a prime factorization table first. The alternative would be to perform a GCD sweep on each denominator factor against the numerator's factors, dividing out the common factors as I go, until all the denominator factors are reduced to 1. – CTMacUser Dec 03 '19 at 03:32
  • Why divide by each individually though? It seems easier to just divide by 24 in one fell swoop – JMoravitz Dec 03 '19 at 03:34
  • @JMoravitz, that can't work if the denominator product is still large enough to blow the integer type's maximum limit. – CTMacUser Dec 03 '19 at 04:25
  • I don't know what time complexity you need. But I think that, by using the recursive formula for binomial coefficient, you are sure that you will be able to do all intermediate computations as long as your final results fits in integer type. – Zoms96 Dec 03 '19 at 06:27

2 Answers2

1

Perhaps what you are looking for is Kummer's theorem. From the Wikipedia article:

Kummer's theorem states that for given integer $\,n\ge m\ge 0\,$ and a prime number $\,p\,$, the $p$-adic valuation $\,\nu_p({n \choose m})\,$ is equal to the number of carries when $\,m\,$ is added to $\,n-m\,$ in base $\,p.\,$

All that is now needed to calculate $\,N:={n\choose m}\,$ is the list of all primes $\,p\le n\,$ and thus $$ N = \prod_{p\le n} p^{\nu_p(N)}. $$ It is well known (see multinomial theorem) that any multinomial coefficient is a product of binomial coefficients and thus the $p$-adic valuation of a multinomial coefficient is the sum of $p$-adic valuations of some well defined binomial coefficents.

Of course, there are more elementary ways to compute binomial coefficients without depending on prime factorizations. Just use one of several kinds of recurrence relations. It all depends on your use case.

Somos
  • 35,251
  • 3
  • 30
  • 76
  • 1
    A little typo ? $N$ is the product of the $p$ at power $\nu _p$ – Damien Dec 03 '19 at 03:53
  • @Damien Oops! Will fix. – Somos Dec 03 '19 at 04:06
  • Your paragraph after the quote mentions needing the list of primes within n, my question is if there's a way to avoid doing that! (Like you could find the GCD if you had a prime factorization table, but there are faster ways that don't require that table.) Unless we can show that building up that prime list would still be faster than any workaround (like multiple GCD cancellation sweeps). – CTMacUser Dec 03 '19 at 04:30
  • 2
    @CTMacUser Building a list of primes up to some upper limit using a sieve goes back to Eratosthenes. It compares very favorably to any use of GCD in this paritcular use case. It all depends on your exact use case which you never specified in your question. – Somos Dec 03 '19 at 13:36
  • @Somos, I'm writing a type that prints all the permutations of a collection. I can provide a property giving the count in advance. I was thinking of just returning n!, but I realized that the loop prints only unique permutations, and automatically collapses away arrangements that differ in the placement of identical elements. So I need the multinomial formula to determine the count. – CTMacUser Dec 03 '19 at 19:04
  • @CTMacUser In that case, you are only using counts going up to a million or billion at the most. This is not huge and the the approach I suggested using prime factorizations is very doable. Computing multinomial coefficients is the least of your problems here. – Somos Dec 03 '19 at 19:43
1

If you want to do this fast, use prime factorisation, Kummer's theorem, and a balanced multiplication strategy. See e.g. https://codegolf.stackexchange.com/q/37270/194

If you want to keep it simple, the decomposition $$\binom{n}{k} = \frac{n-k+1}{k} \binom{n}{k-1}$$ and variants give some simple loops which don't require keeping track of what to cancel. E.g.

result = 1
for i = 0 to k-1:
    result = result * (n-i) / (i+1)
Peter Taylor
  • 13,425