I need a function which can calculate the mathematical combination of (n, k) for a card game.
My current attempt is to use a function based on usual Factorial method :
    static long Factorial(long n)
    {
        return n < 2 ? 1 : n * Factorial(n - 1); 
    }
    static long Combinatory(long n , long k )
    {
        return Factorial(n) / (Factorial(k) * Factorial(n - k)); 
    }
It's working very well but the matter is when I use some range of number (n value max is 52 and k value max is 4), it keeps me returning a wrong value. E.g :
   long comb = Combinatory(52, 2) ; // return 1 which should be actually 1326
I know that it's because I overflow the long when I make Factorial(52) but the range result I need is not as big as it seems.
Is there any way to get over this issue ?
Instead of using the default combinatory formula n! / (k! x (n - k)!), use the recursive property of the combinatory function. 
    (n, k) = (n - 1, k) + (n - 1, k - 1)
Knowing that : (n, 0) = 1 and (n, n) = 1.
-> It will make you avoid using factorial and overflowing your long.
Here is sample of implementation you can do :
 static long Combinatory(long n, long k)
    {
        if (k == 0 || n == k )
            return 1;
        return Combinatory(n - 1, k) + Combinatory(n - 1, k - 1); 
    }
EDIT : With a faster iterative algorithm
    static long Combinatory(long n, long k)
    {
        if (n - k < k)
            k = n - k;
        long res = 1;
        for (int i = 1; i <= k; ++i)
        {
            res = (res * (n - i + 1)) / i;
        }
        return res;
    } 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With