You don't need space for 40!/20!, for example:
let ans = 1
for (let i=1; i<21; ++i) {
ans *= (41 - i)
ans /= i
}
The same idea can be trivially tweaked to compute any binomial coefficient without ever storing an integer greater than the final result.
Good point. But what if `i` does not divide `ans` evenly? I suppose you could use floats and then round.
It always divides it evenly, that's why it works.
After the i-th iteration of the for loop, ans will contain n!/((n-i)!i!) which is exactly \binom{n}{i}, an integer.
Technically "ans" can grow above the final result in my example, but even that could be fixed if one really wants (e.g. i must divide either ans or n-i, you play a bit with divmod to figure out which division you do first.)