mirror of
https://github.com/TheAlgorithms/C-Plus-Plus.git
synced 2026-04-13 17:50:45 +08:00
feat: Add ncr mod p code (#1325)
* feat: Add ncr mod p code (#1323) * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Added all functions inside a class + added more asserts * updating DIRECTORY.md * clang-format and clang-tidy fixes forf6df24a5* Replace int64_t to uint64_t + add namespace + detailed documentation * clang-format and clang-tidy fixes fore09a0579* Add extra namespace + add const& in function arguments * clang-format and clang-tidy fixes for8111f881* Update ncr_modulo_p.cpp * clang-format and clang-tidy fixes for2ad2f721* Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update math/ncr_modulo_p.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for5b69ba5c* updating DIRECTORY.md * clang-format and clang-tidy fixes fora8401d4bCo-authored-by: David Leal <halfpacho@gmail.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
This commit is contained in:
@@ -21,75 +21,76 @@
|
||||
* @brief Mathematical algorithms
|
||||
*/
|
||||
namespace math {
|
||||
/**
|
||||
* @namespace fibonacci_sum
|
||||
* @brief Functions for the sum of the Fibonacci Sequence: \f$\mathrm{F}(n) +
|
||||
* \mathrm{F}(n+1) + .. + \mathrm{F}(m)\f$
|
||||
*/
|
||||
namespace fibonacci_sum {
|
||||
using matrix = std::vector<std::vector<uint64_t> >;
|
||||
/**
|
||||
* @namespace fibonacci_sum
|
||||
* @brief Functions for the sum of the Fibonacci Sequence: \f$\mathrm{F}(n) +
|
||||
* \mathrm{F}(n+1) + .. + \mathrm{F}(m)\f$
|
||||
*/
|
||||
namespace fibonacci_sum {
|
||||
using matrix = std::vector<std::vector<uint64_t> >;
|
||||
|
||||
/**
|
||||
* Function to multiply two matrices
|
||||
* @param T matrix 1
|
||||
* @param A martix 2
|
||||
* @returns resultant matrix
|
||||
*/
|
||||
math::fibonacci_sum::matrix multiply(const math::fibonacci_sum::matrix &T, const math::fibonacci_sum::matrix &A) {
|
||||
math::fibonacci_sum::matrix result(2, std::vector<uint64_t>(2, 0));
|
||||
/**
|
||||
* Function to multiply two matrices
|
||||
* @param T matrix 1
|
||||
* @param A martix 2
|
||||
* @returns resultant matrix
|
||||
*/
|
||||
math::fibonacci_sum::matrix multiply(const math::fibonacci_sum::matrix &T,
|
||||
const math::fibonacci_sum::matrix &A) {
|
||||
math::fibonacci_sum::matrix result(2, std::vector<uint64_t>(2, 0));
|
||||
|
||||
// multiplying matrices
|
||||
result[0][0] = T[0][0]*A[0][0] + T[0][1]*A[1][0];
|
||||
result[0][1] = T[0][0]*A[0][1] + T[0][1]*A[1][1];
|
||||
result[1][0] = T[1][0]*A[0][0] + T[1][1]*A[1][0];
|
||||
result[1][1] = T[1][0]*A[0][1] + T[1][1]*A[1][1];
|
||||
// multiplying matrices
|
||||
result[0][0] = T[0][0] * A[0][0] + T[0][1] * A[1][0];
|
||||
result[0][1] = T[0][0] * A[0][1] + T[0][1] * A[1][1];
|
||||
result[1][0] = T[1][0] * A[0][0] + T[1][1] * A[1][0];
|
||||
result[1][1] = T[1][0] * A[0][1] + T[1][1] * A[1][1];
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute A^n where A is a matrix.
|
||||
* @param T matrix
|
||||
* @param ex power
|
||||
* @returns resultant matrix
|
||||
*/
|
||||
math::fibonacci_sum::matrix power(math::fibonacci_sum::matrix T, uint64_t ex) {
|
||||
math::fibonacci_sum::matrix A{{1, 1}, {1, 0}};
|
||||
if (ex == 0 || ex == 1) {
|
||||
return T;
|
||||
}
|
||||
/**
|
||||
* Function to compute A^n where A is a matrix.
|
||||
* @param T matrix
|
||||
* @param ex power
|
||||
* @returns resultant matrix
|
||||
*/
|
||||
math::fibonacci_sum::matrix power(math::fibonacci_sum::matrix T, uint64_t ex) {
|
||||
math::fibonacci_sum::matrix A{{1, 1}, {1, 0}};
|
||||
if (ex == 0 || ex == 1) {
|
||||
return T;
|
||||
}
|
||||
|
||||
T = power(T, ex / 2);
|
||||
T = multiply(T, T);
|
||||
if (ex & 1) {
|
||||
T = multiply(T, A);
|
||||
}
|
||||
return T;
|
||||
}
|
||||
T = power(T, ex / 2);
|
||||
T = multiply(T, T);
|
||||
if (ex & 1) {
|
||||
T = multiply(T, A);
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute sum of fibonacci sequence from 0 to n.
|
||||
* @param n number
|
||||
* @returns uint64_t ans, the sum of sequence
|
||||
*/
|
||||
uint64_t result(uint64_t n) {
|
||||
math::fibonacci_sum::matrix T{{1, 1}, {1, 0}};
|
||||
T = power(T, n);
|
||||
uint64_t ans = T[0][1];
|
||||
ans = (ans - 1);
|
||||
return ans;
|
||||
}
|
||||
/**
|
||||
* Function to compute sum of fibonacci sequence from 0 to n.
|
||||
* @param n number
|
||||
* @returns uint64_t ans, the sum of sequence
|
||||
*/
|
||||
uint64_t result(uint64_t n) {
|
||||
math::fibonacci_sum::matrix T{{1, 1}, {1, 0}};
|
||||
T = power(T, n);
|
||||
uint64_t ans = T[0][1];
|
||||
ans = (ans - 1);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to compute sum of fibonacci sequence from n to m.
|
||||
* @param n start of sequence
|
||||
* @param m end of sequence
|
||||
* @returns uint64_t the sum of sequence
|
||||
*/
|
||||
uint64_t fiboSum(uint64_t n, uint64_t m) {
|
||||
return (result(m + 2) - result(n + 1));
|
||||
}
|
||||
} // namespace fibonacci_sum
|
||||
/**
|
||||
* Function to compute sum of fibonacci sequence from n to m.
|
||||
* @param n start of sequence
|
||||
* @param m end of sequence
|
||||
* @returns uint64_t the sum of sequence
|
||||
*/
|
||||
uint64_t fiboSum(uint64_t n, uint64_t m) {
|
||||
return (result(m + 2) - result(n + 1));
|
||||
}
|
||||
} // namespace fibonacci_sum
|
||||
} // namespace math
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$
|
||||
* @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$
|
||||
* denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1.
|
||||
* The value of the sum is calculated by formula:
|
||||
* \f[
|
||||
* \sum\mathrm{LCM}(i, n) = \frac{1}{2} \left[\left(\sum (d * \mathrm{ETF}(d)) + 1\right) * n\right]
|
||||
* \f]
|
||||
* where \mathrm{ETF}(i) represents Euler totient function of i.
|
||||
* @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) +
|
||||
* \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$
|
||||
* @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) +
|
||||
* \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ where
|
||||
* \f$\mathrm{LCM}(i,n)\f$ denotes the Least Common Multiple of the integers i
|
||||
* and n. For n greater than or equal to 1. The value of the sum is calculated
|
||||
* by formula: \f[ \sum\mathrm{LCM}(i, n) = \frac{1}{2} \left[\left(\sum (d *
|
||||
* \mathrm{ETF}(d)) + 1\right) * n\right] \f] where \mathrm{ETF}(i) represents
|
||||
* Euler totient function of i.
|
||||
* @author [Chesta Mittal](https://github.com/chestamittal)
|
||||
*/
|
||||
|
||||
#include <iostream> /// for std::cin and std::cout
|
||||
#include <cassert> /// for assert
|
||||
#include <vector> /// for std::vector
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for std::cin and std::cout
|
||||
#include <vector> /// for std::vector
|
||||
|
||||
/**
|
||||
* @namespace math
|
||||
* @brief Mathematical algorithms
|
||||
*/
|
||||
namespace math {
|
||||
/**
|
||||
* Function to compute sum of euler totients in sumOfEulerTotient vector
|
||||
* @param num input number
|
||||
* @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num
|
||||
*/
|
||||
uint64_t lcmSum(const uint16_t& num) {
|
||||
|
||||
uint64_t i=0, j=0;
|
||||
std::vector <uint64_t> eulerTotient(num+1);
|
||||
std::vector <uint64_t> sumOfEulerTotient(num+1);
|
||||
|
||||
// storing initial values in eulerTotient vector
|
||||
for(i=1; i<=num; i++) {
|
||||
eulerTotient[i] = i;
|
||||
}
|
||||
/**
|
||||
* Function to compute sum of euler totients in sumOfEulerTotient vector
|
||||
* @param num input number
|
||||
* @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num
|
||||
*/
|
||||
uint64_t lcmSum(const uint16_t& num) {
|
||||
uint64_t i = 0, j = 0;
|
||||
std::vector<uint64_t> eulerTotient(num + 1);
|
||||
std::vector<uint64_t> sumOfEulerTotient(num + 1);
|
||||
|
||||
// applying totient sieve
|
||||
for(i=2; i<=num; i++) {
|
||||
if(eulerTotient[i] == i) {
|
||||
for(j=i; j<=num; j+=i) {
|
||||
eulerTotient[j] = eulerTotient[j]/i;
|
||||
eulerTotient[j] = eulerTotient[j]*(i-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// computing sum of euler totients
|
||||
for(i=1; i<=num; i++) {
|
||||
for(j=i; j <=num; j+=i) {
|
||||
sumOfEulerTotient[j] += eulerTotient[i]*i;
|
||||
}
|
||||
}
|
||||
|
||||
return ((sumOfEulerTotient[num] + 1 ) * num) / 2;
|
||||
// storing initial values in eulerTotient vector
|
||||
for (i = 1; i <= num; i++) {
|
||||
eulerTotient[i] = i;
|
||||
}
|
||||
|
||||
// applying totient sieve
|
||||
for (i = 2; i <= num; i++) {
|
||||
if (eulerTotient[i] == i) {
|
||||
for (j = i; j <= num; j += i) {
|
||||
eulerTotient[j] = eulerTotient[j] / i;
|
||||
eulerTotient[j] = eulerTotient[j] * (i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// computing sum of euler totients
|
||||
for (i = 1; i <= num; i++) {
|
||||
for (j = i; j <= num; j += i) {
|
||||
sumOfEulerTotient[j] += eulerTotient[i] * i;
|
||||
}
|
||||
}
|
||||
|
||||
return ((sumOfEulerTotient[num] + 1) * num) / 2;
|
||||
}
|
||||
} // namespace math
|
||||
|
||||
/**
|
||||
* Function for testing lcmSum function.
|
||||
* test cases and assert statement.
|
||||
* @returns `void`
|
||||
*/
|
||||
*/
|
||||
static void test() {
|
||||
uint64_t n = 2;
|
||||
uint64_t test_1 = math::lcmSum(n);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief [Combinations](https://en.wikipedia.org/wiki/Combination) n choose r function implementation
|
||||
* @brief [Combinations](https://en.wikipedia.org/wiki/Combination) n choose r
|
||||
* function implementation
|
||||
* @details
|
||||
* A very basic and efficient method of calculating
|
||||
* choosing r from n different choices.
|
||||
@@ -9,8 +10,8 @@
|
||||
* @author [Tajmeet Singh](https://github.com/tjgurwara99)
|
||||
*/
|
||||
|
||||
#include <iostream> /// for io operations
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for io operations
|
||||
|
||||
/**
|
||||
* @namespace math
|
||||
@@ -22,8 +23,9 @@ namespace math {
|
||||
* @details
|
||||
* We are calculating the ans with iterations
|
||||
* instead of calculating three different factorials.
|
||||
* Also, we are using the fact that
|
||||
* \f$ \frac{n!}{r! (n-r)!} = \frac{(n - r + 1) \times \cdots \times n}{1 \times \cdots \times r} \f$
|
||||
* Also, we are using the fact that
|
||||
* \f$ \frac{n!}{r! (n-r)!} = \frac{(n - r + 1) \times \cdots \times n}{1 \times
|
||||
* \cdots \times r} \f$
|
||||
* @tparam T Only for integer types such as long, int_64 etc
|
||||
* @param n \f$ n \f$ in \f$ \binom{n}{r} \f$
|
||||
* @param r \f$ r \f$ in \f$ \binom{n}{r} \f$
|
||||
@@ -31,16 +33,17 @@ namespace math {
|
||||
*/
|
||||
template <class T>
|
||||
T n_choose_r(T n, T r) {
|
||||
if(r > n / 2)
|
||||
r = n - r; // Because of the fact that nCr(n, r) == nCr(n, n - r)
|
||||
if (r > n / 2) {
|
||||
r = n - r; // Because of the fact that nCr(n, r) == nCr(n, n - r)
|
||||
}
|
||||
T ans = 1;
|
||||
for(int i = 1; i <= r; i++) {
|
||||
for (int i = 1; i <= r; i++) {
|
||||
ans *= n - r + i;
|
||||
ans /= i;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
} // namespace math
|
||||
} // namespace math
|
||||
|
||||
/**
|
||||
* @brief Test implementations
|
||||
@@ -48,25 +51,24 @@ T n_choose_r(T n, T r) {
|
||||
*/
|
||||
static void test() {
|
||||
// First test on 5 choose 2
|
||||
uint8_t t = math::n_choose_r(5, 2);
|
||||
assert(((void)"10 is the answer but function says otherwise.\n",
|
||||
t == 10));
|
||||
std::cout << "First test passes." << std::endl;
|
||||
// Second test on 5 choose 3
|
||||
t = math::n_choose_r(5, 3);
|
||||
assert(((void)"10 is the answer but the function says otherwise.\n",
|
||||
t == 10));
|
||||
std::cout << "Second test passes." << std::endl;
|
||||
// Third test on 3 choose 2
|
||||
t = math::n_choose_r(3, 2);
|
||||
assert(((void)"3 is the answer but the function says otherwise.\n",
|
||||
t == 3));
|
||||
std::cout << "Third test passes." << std::endl;
|
||||
// Fourth test on 10 choose 4
|
||||
t = math::n_choose_r(10, 4);
|
||||
assert(((void)"210 is the answer but the function says otherwise.\n",
|
||||
t == 210));
|
||||
std::cout << "Fourth test passes." << std::endl;
|
||||
uint8_t t = math::n_choose_r(5, 2);
|
||||
assert(((void)"10 is the answer but function says otherwise.\n", t == 10));
|
||||
std::cout << "First test passes." << std::endl;
|
||||
// Second test on 5 choose 3
|
||||
t = math::n_choose_r(5, 3);
|
||||
assert(
|
||||
((void)"10 is the answer but the function says otherwise.\n", t == 10));
|
||||
std::cout << "Second test passes." << std::endl;
|
||||
// Third test on 3 choose 2
|
||||
t = math::n_choose_r(3, 2);
|
||||
assert(
|
||||
((void)"3 is the answer but the function says otherwise.\n", t == 3));
|
||||
std::cout << "Third test passes." << std::endl;
|
||||
// Fourth test on 10 choose 4
|
||||
t = math::n_choose_r(10, 4);
|
||||
assert(((void)"210 is the answer but the function says otherwise.\n",
|
||||
t == 210));
|
||||
std::cout << "Fourth test passes." << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,6 +78,6 @@ static void test() {
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
test(); // executing tests
|
||||
test(); // executing tests
|
||||
return 0;
|
||||
}
|
||||
|
||||
150
math/ncr_modulo_p.cpp
Normal file
150
math/ncr_modulo_p.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief This program aims at calculating [nCr modulo
|
||||
* p](https://cp-algorithms.com/combinatorics/binomial-coefficients.html).
|
||||
* @details nCr is defined as n! / (r! * (n-r)!) where n! represents factorial
|
||||
* of n. In many cases, the value of nCr is too large to fit in a 64 bit
|
||||
* integer. Hence, in competitive programming, there are many problems or
|
||||
* subproblems to compute nCr modulo p where p is a given number.
|
||||
* @author [Kaustubh Damania](https://github.com/KaustubhDamania)
|
||||
*/
|
||||
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for io operations
|
||||
#include <vector> /// for std::vector
|
||||
|
||||
/**
|
||||
* @namespace math
|
||||
* @brief Mathematical algorithms
|
||||
*/
|
||||
namespace math {
|
||||
/**
|
||||
* @namespace ncr_modulo_p
|
||||
* @brief Functions for [nCr modulo
|
||||
* p](https://cp-algorithms.com/combinatorics/binomial-coefficients.html)
|
||||
* implementation.
|
||||
*/
|
||||
namespace ncr_modulo_p {
|
||||
/**
|
||||
* @brief Class which contains all methods required for calculating nCr mod p
|
||||
*/
|
||||
class NCRModuloP {
|
||||
private:
|
||||
std::vector<uint64_t> fac{}; /// stores precomputed factorial(i) % p value
|
||||
uint64_t p = 0; /// the p from (nCr % p)
|
||||
|
||||
public:
|
||||
/** Constructor which precomputes the values of n! % mod from n=0 to size
|
||||
* and stores them in vector 'fac'
|
||||
* @params[in] the numbers 'size', 'mod'
|
||||
*/
|
||||
NCRModuloP(const uint64_t& size, const uint64_t& mod) {
|
||||
p = mod;
|
||||
fac = std::vector<uint64_t>(size);
|
||||
fac[0] = 1;
|
||||
for (int i = 1; i <= size; i++) {
|
||||
fac[i] = (fac[i - 1] * i) % p;
|
||||
}
|
||||
}
|
||||
|
||||
/** Finds the value of x, y such that a*x + b*y = gcd(a,b)
|
||||
*
|
||||
* @params[in] the numbers 'a', 'b' and address of 'x' and 'y' from above
|
||||
* equation
|
||||
* @returns the gcd of a and b
|
||||
*/
|
||||
uint64_t gcdExtended(const uint64_t& a, const uint64_t& b, int64_t* x,
|
||||
int64_t* y) {
|
||||
if (a == 0) {
|
||||
*x = 0, *y = 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
int64_t x1 = 0, y1 = 0;
|
||||
uint64_t gcd = gcdExtended(b % a, a, &x1, &y1);
|
||||
|
||||
*x = y1 - (b / a) * x1;
|
||||
*y = x1;
|
||||
return gcd;
|
||||
}
|
||||
|
||||
/** Find modular inverse of a with m i.e. a number x such that (a*x)%m = 1
|
||||
*
|
||||
* @params[in] the numbers 'a' and 'm' from above equation
|
||||
* @returns the modular inverse of a
|
||||
*/
|
||||
int64_t modInverse(const uint64_t& a, const uint64_t& m) {
|
||||
int64_t x = 0, y = 0;
|
||||
uint64_t g = gcdExtended(a, m, &x, &y);
|
||||
if (g != 1) { // modular inverse doesn't exist
|
||||
return -1;
|
||||
} else {
|
||||
int64_t res = ((x + m) % m);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/** Find nCr % p
|
||||
*
|
||||
* @params[in] the numbers 'n', 'r' and 'p'
|
||||
* @returns the value nCr % p
|
||||
*/
|
||||
int64_t ncr(const uint64_t& n, const uint64_t& r, const uint64_t& p) {
|
||||
// Base cases
|
||||
if (r > n) {
|
||||
return 0;
|
||||
}
|
||||
if (r == 1) {
|
||||
return n % p;
|
||||
}
|
||||
if (r == 0 || r == n) {
|
||||
return 1;
|
||||
}
|
||||
// fac is a global array with fac[r] = (r! % p)
|
||||
int64_t denominator = modInverse(fac[r], p);
|
||||
if (denominator < 0) { // modular inverse doesn't exist
|
||||
return -1;
|
||||
}
|
||||
denominator = (denominator * modInverse(fac[n - r], p)) % p;
|
||||
if (denominator < 0) { // modular inverse doesn't exist
|
||||
return -1;
|
||||
}
|
||||
return (fac[n] * denominator) % p;
|
||||
}
|
||||
};
|
||||
} // namespace ncr_modulo_p
|
||||
} // namespace math
|
||||
|
||||
/**
|
||||
* @brief Test implementations
|
||||
* @param ncrObj object which contains the precomputed factorial values and
|
||||
* ncr function
|
||||
* @returns void
|
||||
*/
|
||||
static void tests(math::ncr_modulo_p::NCRModuloP ncrObj) {
|
||||
// (52323 C 26161) % (1e9 + 7) = 224944353
|
||||
assert(ncrObj.ncr(52323, 26161, 1000000007) == 224944353);
|
||||
// 6 C 2 = 30, 30%5 = 0
|
||||
assert(ncrObj.ncr(6, 2, 5) == 0);
|
||||
// 7C3 = 35, 35 % 29 = 8
|
||||
assert(ncrObj.ncr(7, 3, 29) == 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main() {
|
||||
// populate the fac array
|
||||
const uint64_t size = 1e6 + 1;
|
||||
const uint64_t p = 1e9 + 7;
|
||||
math::ncr_modulo_p::NCRModuloP ncrObj =
|
||||
math::ncr_modulo_p::NCRModuloP(size, p);
|
||||
// test 6Ci for i=0 to 7
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
std::cout << 6 << "C" << i << " = " << ncrObj.ncr(6, i, p) << "\n";
|
||||
}
|
||||
tests(ncrObj); // execute the tests
|
||||
std::cout << "Assertions passed\n";
|
||||
return 0;
|
||||
}
|
||||
@@ -1,14 +1,16 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief Algorithm to find sum of binomial coefficients of a given positive integer.
|
||||
* @details Given a positive integer n, the task is to find the sum of binomial coefficient i.e
|
||||
* nC0 + nC1 + nC2 + ... + nCn-1 + nCn
|
||||
* By induction, we can prove that the sum is equal to 2^n
|
||||
* @see more on https://en.wikipedia.org/wiki/Binomial_coefficient#Sums_of_the_binomial_coefficients
|
||||
* @brief Algorithm to find sum of binomial coefficients of a given positive
|
||||
* integer.
|
||||
* @details Given a positive integer n, the task is to find the sum of binomial
|
||||
* coefficient i.e nC0 + nC1 + nC2 + ... + nCn-1 + nCn By induction, we can
|
||||
* prove that the sum is equal to 2^n
|
||||
* @see more on
|
||||
* https://en.wikipedia.org/wiki/Binomial_coefficient#Sums_of_the_binomial_coefficients
|
||||
* @author [muskan0719](https://github.com/muskan0719)
|
||||
*/
|
||||
#include <iostream> /// for std::cin and std::cout
|
||||
#include <cassert> /// for assert
|
||||
#include <cassert> /// for assert
|
||||
#include <iostream> /// for std::cin and std::cout
|
||||
|
||||
/**
|
||||
* @namespace math
|
||||
@@ -16,52 +18,49 @@
|
||||
*/
|
||||
namespace math {
|
||||
|
||||
/**
|
||||
* Function to calculate sum of binomial coefficients
|
||||
* @param n number
|
||||
* @return Sum of binomial coefficients of number
|
||||
*/
|
||||
uint64_t binomialCoeffSum(uint64_t n)
|
||||
{
|
||||
// Calculating 2^n
|
||||
return (1 << n);
|
||||
}
|
||||
/**
|
||||
* Function to calculate sum of binomial coefficients
|
||||
* @param n number
|
||||
* @return Sum of binomial coefficients of number
|
||||
*/
|
||||
uint64_t binomialCoeffSum(uint64_t n) {
|
||||
// Calculating 2^n
|
||||
return (1 << n);
|
||||
}
|
||||
} // namespace math
|
||||
|
||||
/**
|
||||
* Function for testing binomialCoeffSum function.
|
||||
* test cases and assert statement.
|
||||
* @returns `void`
|
||||
*/
|
||||
static void test()
|
||||
{
|
||||
int test_case_1 = math::binomialCoeffSum(2);
|
||||
assert(test_case_1==4);
|
||||
std::cout<<"Test_case_1 Passed!"<<std::endl;
|
||||
|
||||
int test_case_2 = math::binomialCoeffSum(3);
|
||||
assert(test_case_2==8);
|
||||
std::cout<<"Test_case_2 Passed!"<<std::endl;
|
||||
|
||||
int test_case_3 = math::binomialCoeffSum(4);
|
||||
assert(test_case_3==16);
|
||||
std::cout<<"Test_case_3 Passed!"<<std::endl;
|
||||
|
||||
int test_case_4 = math::binomialCoeffSum(5);
|
||||
assert(test_case_4==32);
|
||||
std::cout<<"Test_case_4 Passed!"<<std::endl;
|
||||
|
||||
int test_case_5 = math::binomialCoeffSum(7);
|
||||
assert(test_case_5==128);
|
||||
std::cout<<"Test_case_5 Passed!"<<std::endl;
|
||||
}
|
||||
*/
|
||||
static void test() {
|
||||
int test_case_1 = math::binomialCoeffSum(2);
|
||||
assert(test_case_1 == 4);
|
||||
std::cout << "Test_case_1 Passed!" << std::endl;
|
||||
|
||||
int test_case_2 = math::binomialCoeffSum(3);
|
||||
assert(test_case_2 == 8);
|
||||
std::cout << "Test_case_2 Passed!" << std::endl;
|
||||
|
||||
int test_case_3 = math::binomialCoeffSum(4);
|
||||
assert(test_case_3 == 16);
|
||||
std::cout << "Test_case_3 Passed!" << std::endl;
|
||||
|
||||
int test_case_4 = math::binomialCoeffSum(5);
|
||||
assert(test_case_4 == 32);
|
||||
std::cout << "Test_case_4 Passed!" << std::endl;
|
||||
|
||||
int test_case_5 = math::binomialCoeffSum(7);
|
||||
assert(test_case_5 == 128);
|
||||
std::cout << "Test_case_5 Passed!" << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Main function
|
||||
* @returns 0 on exit
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
test(); // execute the tests
|
||||
return 0;
|
||||
}
|
||||
int main() {
|
||||
test(); // execute the tests
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user