Ad

Write a function combination that takes two integers n and k and returns the number of k-Combinations for a set with n elements. This is the mathematical Combination function, equal to the binomial coefficient (See https://en.wikipedia.org/wiki/Combination for further details.)

The function must raise a ValueError if n or k are negative. Because n and k are cardinal numbers, and represent a number of elements in a set, they should not be negative here.

0 is an allowed value for either n or k, since you can be choosing values from the empty set. If k is 0, then combination should return 1.

Also, if n is less than k, then the result of combination should be 0, as per standard mathematical convention.

Code
Diff
  • from functools import reduce
    from operator import mul
    
    def combination(n: int, k: int) -> int:
        """
        Returns the result of the mathematical combination function
        (''`n` choose `k`'). See https://en.wikipedia.org/wiki/Combination for
        further details.
        
        :param n: the number of elements in the set
        :param k: the number of elements to be chosen from the set
        :raises ValueError: if either n or k are negative
        :return: how many different ways there are to choose `k` elements from a
            set of `n` elements; the number of `k`-combinations for a set with `n`
            elements.
        """
        if k < 0:
            raise ValueError("k must be non-negative.")
            
        if n < 0:
            raise ValueError("n must be non-negative.")
        
        if n < k:
            return 0
        
        total_permutations = reduce(mul, range(n, n - k, -1), 1)
        count_that_only_differ_by_order = reduce(mul, range(k, 0, -1), 1)
        return total_permutations // count_that_only_differ_by_order
    • class NonPositiveArgumentError(ValueError):
    • pass
    • from functools import reduce
    • from operator import mul
    • class WrongArgumentsOrderError(ValueError):
    • pass
    • class Compute:
    • def __init__(self, k: int, n: int) -> None:
    • self.n = n
    • self.k = k
    • def combination(n: int, k: int) -> int:
    • """
    • Returns the result of the mathematical combination function
    • (''`n` choose `k`'). See https://en.wikipedia.org/wiki/Combination for
    • further details.
    • @staticmethod
    • def get_factorial(x) -> int:
    • if not isinstance(x, int):
    • raise TypeError(f"n must be of type int, not {type(x)}.")
    • if x < 0:
    • raise NonPositiveArgumentError
    • res = 1
    • for i in range(1, x + 1):
    • res *= i
    • return res
    • def get_combination(self):
    • if not isinstance(self.k, int):
    • raise TypeError(f"k must be of type int, not {type(self.k)}.")
    • if not isinstance(self.n, int):
    • raise TypeError(f"n must be of type int, not {type(self.k)}.")
    • if self.k <= 0:
    • raise NonPositiveArgumentError("k must be positive.")
    • if self.n <= 0:
    • raise NonPositiveArgumentError("n must be positive.")
    • if self.n < self.k:
    • raise WrongArgumentsOrderError("n must be greater than or equal to k.")
    • else:
    • return self.get_factorial(self.n) / (self.get_factorial(self.n - self.k) * self.get_factorial(self.k))
    • :param n: the number of elements in the set
    • :param k: the number of elements to be chosen from the set
    • :raises ValueError: if either n or k are negative
    • :return: how many different ways there are to choose `k` elements from a
    • set of `n` elements; the number of `k`-combinations for a set with `n`
    • elements.
    • """
    • if k < 0:
    • raise ValueError("k must be non-negative.")
    • if n < 0:
    • raise ValueError("n must be non-negative.")
    • if n < k:
    • return 0
    • total_permutations = reduce(mul, range(n, n - k, -1), 1)
    • count_that_only_differ_by_order = reduce(mul, range(k, 0, -1), 1)
    • return total_permutations // count_that_only_differ_by_order