clang-format and clang-tidy fixes for e09a0579

This commit is contained in:
github-actions
2020-10-22 20:00:54 +00:00
parent e09a05793b
commit 8e9803da1e

View File

@@ -2,109 +2,108 @@
* @file
* @brief This program aims at calculating nCr modulo p
* @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.
* 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
#include <cassert> /// for assert
#include <iostream> /// for io operations
#include <vector> /// for std::vector
/**
* @namespace math
* @brief Mathematical algorithms
*/
namespace math {
/**
* @brief Class which contains all methods required for calculating nCr mod p
*/
class NCRModuloP {
private:
std::vector<uint64_t> fac;
uint64_t p;
/**
* @namespace math
* @brief Mathematical algorithms
*/
namespace math {
/**
* @brief Class which contains all methods required for calculating nCr mod 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'
*/
class NCRModuloP {
private:
std::vector<uint64_t> fac;
uint64_t 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(uint64_t size, 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;
}
NCRModuloP(uint64_t size, 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(uint64_t a, uint64_t b, int64_t *x, int64_t *y) {
if (a == 0) {
*x = 0, *y = 1;
return b;
}
/** 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(uint64_t a, 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);
int64_t x1 = 0, y1 = 0;
uint64_t gcd = gcdExtended(b % a, a, &x1, &y1);
*x = y1 - (b / a) * x1;
*y = x1;
return gcd;
}
*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(uint64_t a, 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 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(uint64_t a, 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(uint64_t n, uint64_t r, uint64_t p) {
// Base cases
if (r > n) {
return 0;
}
/** Find nCr % p
*
* @params[in] the numbers 'n', 'r' and 'p'
* @returns the value nCr % p
*/
int64_t ncr(uint64_t n, uint64_t r, 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;
if (r == 1) {
return n % p;
}
};
} // namespace math
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 math
/**
* @brief Test implementations
@@ -116,12 +115,11 @@ void tests(math::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);
assert(ncrObj.ncr(6, 2, 5) == 0);
// 7C3 = 35, 35 % 29 = 8
assert(ncrObj.ncr(7,3,29) == 6);
assert(ncrObj.ncr(7, 3, 29) == 6);
}
/**
* @brief Main function
* @returns 0 on exit
@@ -135,6 +133,6 @@ int main() {
for (int i = 0; i <= 7; i++) {
std::cout << 6 << "C" << i << " = " << ncrObj.ncr(6, i, p) << "\n";
}
tests(ncrObj); // execute the tests
tests(ncrObj); // execute the tests
std::cout << "Assertions passed\n";
}