Combination and factorial
int is IMO not an appropriate type in this domain. I would use ulong or maybe BigInteger

If you for instance run the following test, both CombinationFact() and CombinationFast() runs out of range:

  n = 52;
  k = 9;
  Console.WriteLine($"Combin({n}, {k}) = {CombinationFact(n, k)}");
  Console.WriteLine($"Combin({n}, {k}) = {CombinationFast(n, k)}");




I would use throw new ArgumentOutOfRangeException(nameof(n));

instead of throw new IndexOutOfRangeException();



You don't need the extra variable combinations:


  int combination = (int)(Factorial(n) / Factorial(k) / Factorial(n - k)); 
              return combination;


Just return the result of the calculation:

  return (int)(Factorial(n) / Factorial(k) / Factorial(n - k)); 




Both of your algorithms is rather limited in use due to the int-conversion, but you could change the fast version to something like:

public ulong CombinationFast(ulong n, ulong k)
{
  ulong count = n;

  for (ulong x = 1; x &lt;= k - 1; x++)
  {
    count *= (n - x);
    count /= x;
  }

  return count / k;
}


Update

Because 10!/(4!(10-4)!) == (10!/6!(10-6)!) it is possible to optimize the calculation for k &gt; n/2:

public ulong CombinationFast(ulong n, ulong k)
{
  if (k &gt; n / 2)
    k = n - k;

  ulong count = n;

  for (ulong x = 1; x &lt;= k - 1; x++)
  {
    count *= (n - x);
    count /= x;
  }

  return count / k;
}


The above algorithms is an implementation of this expression.

A more literal version should maybe be:

public ulong CombinationFast(ulong n, ulong k)
{
  if (k &gt; n / 2)
    k = n - k;

  ulong count = 1;

  for (ulong x = 0; x &lt; k; x++)
  {
    count *= (n - x);
    count /= (x + 1);
  }

  return count;
}