New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add ncr mod p code #1325
feat: Add ncr mod p code #1325
Conversation
This comment has been minimized.
This comment has been minimized.
This pull request introduces 1 alert when merging ec3899b into 79b98cc - view on LGTM.com new alerts:
|
ec3899b
to
c2f31f8
Compare
This pull request introduces 1 alert when merging c2f31f8 into 981f781 - view on LGTM.com new alerts:
|
c2f31f8
to
bd98630
Compare
This pull request introduces 1 alert when merging bd98630 into 981f781 - view on LGTM.com new alerts:
|
@Panquesito7 I see you have added "Proper Documentation Required". May I know what documentation do I need to add? Apart from that I have fixed the automation test errors. |
Co-authored-by: David Leal <halfpacho@gmail.com>
This pull request introduces 1 alert when merging e44b730 into 981f781 - view on LGTM.com new alerts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please enable GitHub Actions in your repository of this fork in this link: https://github.com/KaustubhDamania/C-Plus-Plus/actions
math/ncr_modulo_p.cpp
Outdated
#include <iostream> | ||
#include <vector> | ||
|
||
/** Finds the value of x, y such that a*x + b*y = gcd(a,b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** Finds the value of x, y such that a*x + b*y = gcd(a,b) | |
/** | |
* @namespace math | |
* @brief Mathematical algorithms | |
*/ | |
namespace math { | |
/** Finds the value of x, y such that a*x + b*y = gcd(a,b) |
math/ncr_modulo_p.cpp
Outdated
} | ||
} | ||
|
||
std::vector<int64_t> fac; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using global variables, they may cause overflows and other issues.
Pass them as local function parameters, or as class private members.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if I keep that variable inside namespace?
And later access them as math::fac?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easiest thing you can do is to pass them as local function parameters.
Or even better, add them as (public) class members, and call the variable directly to the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I refactored the code so that the factorial vector and the remaining functions are inside a class
math/ncr_modulo_p.cpp
Outdated
} | ||
|
||
// (52323 C 26161) % (1e9 + 7) = 224944353 | ||
assert(ncr(52323, 26161, p) == 224944353); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the assert checks in a separate test function. 🙂
@Panquesito7 I have made the required changes, can you review this please? |
math/ncr_modulo_p.cpp
Outdated
#include <cassert> | ||
#include <iostream> | ||
#include <vector> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include <cassert> | |
#include <iostream> | |
#include <vector> | |
#include <cassert> /// for assert | |
#include <iostream> /// for io operations | |
#include <vector> /// for std::vector |
math/ncr_modulo_p.cpp
Outdated
#include <iostream> | ||
#include <vector> | ||
|
||
/** Class which contains all methods required for calculating nCr mod p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** Class which contains all methods required for calculating nCr mod p | |
/** | |
* @namespace math | |
* @brief Mathematical algorithms | |
*/ | |
namespace math { | |
/** | |
* @brief Class which contains all methods required for calculating nCr mod p |
math/ncr_modulo_p.cpp
Outdated
#include <vector> | ||
|
||
/** Class which contains all methods required for calculating nCr mod p | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* |
} | ||
return (fac[n] * denominator) % p; | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
}; | |
}; | |
} // namespace math |
math/ncr_modulo_p.cpp
Outdated
for (int i = 0; i <= 7; i++) { | ||
std::cout << 6 << "C" << i << " = " << ncrObj.ncr(6, i, p) << "\n"; | ||
} | ||
tests(ncrObj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests(ncrObj); | |
tests(ncrObj); // execute the tests |
math/ncr_modulo_p.cpp
Outdated
} | ||
}; | ||
|
||
void tests(NCRModuloP ncrObj) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a brief description of the ncrObj
parameter here (in the code).
void tests(NCRModuloP ncrObj) { | |
/** | |
* @brief Test implementations | |
* @param ncrObj description | |
* @returns void | |
*/ | |
void tests(NCRModuloP ncrObj) { |
math/ncr_modulo_p.cpp
Outdated
*/ | ||
class NCRModuloP { | ||
private: | ||
std::vector<int64_t> fac; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use uint64_t
instead (same in other parts of the code).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Panquesito7 I have replaced int64_t
with uint64_t
in all parts except the ncr
and modInverse
function because those functions can return a negative value in case the modular inverse doesn't exist. Also, the variables x,y in gcdExtended
should be int64_t
because they can be negative as well.
math/ncr_modulo_p.cpp
Outdated
/** | ||
* @file | ||
* @brief This program aims at calculating nCr modulo p | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* | |
* | |
* @author [Kaustubh Damania](https://github.com/KaustubhDamania) |
math/ncr_modulo_p.cpp
Outdated
@@ -0,0 +1,122 @@ | |||
/** | |||
* @file | |||
* @brief This program aims at calculating nCr modulo p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a detailed description using @details
.
d5a278f
to
e09a057
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, good work! 😄 👍
@ayaankhan98 can you review this? or @Panquesito7 can you merge this? 😅 |
math/ncr_modulo_p.cpp
Outdated
std::vector<uint64_t> fac; | ||
uint64_t p; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::vector<uint64_t> fac; | |
uint64_t p; | |
std::vector<uint64_t> fac{}; | |
uint64_t p = 0; |
math/ncr_modulo_p.cpp
Outdated
* and stores them in vector 'fac' | ||
* @params[in] the numbers 'size', 'mod' | ||
*/ | ||
NCRModuloP(uint64_t size, uint64_t mod) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NCRModuloP(uint64_t size, uint64_t mod) { | |
NCRModuloP(const uint64_t& size, const uint64_t& mod) { |
math/ncr_modulo_p.cpp
Outdated
* equation | ||
* @returns the gcd of a and b | ||
*/ | ||
uint64_t gcdExtended(uint64_t a, uint64_t b, int64_t *x, int64_t *y) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint64_t gcdExtended(uint64_t a, uint64_t b, int64_t *x, int64_t *y) { | |
uint64_t gcdExtended(const uint64_t& a, const uint64_t& b, int64_t *x, int64_t *y) { |
math/ncr_modulo_p.cpp
Outdated
* @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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int64_t modInverse(uint64_t a, uint64_t m) { | |
int64_t modInverse(const uint64_t& a, const uint64_t& m) { |
math/ncr_modulo_p.cpp
Outdated
* @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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int64_t ncr(uint64_t n, uint64_t r, uint64_t p) { | |
int64_t ncr(const uint64_t& n, const uint64_t& r, const uint64_t& p) { |
std::cout << 6 << "C" << i << " = " << ncrObj.ncr(6, i, p) << "\n"; | ||
} | ||
tests(ncrObj); // execute the tests | ||
std::cout << "Assertions passed\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::cout << "Assertions passed\n"; | |
std::cout << "Assertions passed\n"; | |
return 0; |
math/ncr_modulo_p.cpp
Outdated
@@ -0,0 +1,138 @@ | |||
/** | |||
* @file | |||
* @brief This program aims at calculating nCr modulo p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provide a Wikipedia link in Markdown format (if available/possible).
If there's no Wikipedia link, add another web source for algorithm explanation. 🙂
* @namespace math | ||
* @brief Mathematical algorithms | ||
*/ | ||
namespace math { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
namespace math { | |
namespace math { | |
/** | |
* @namespace ncr_modulo_p | |
* @brief Functions for nCr modulo p implementation. | |
*/ | |
namespace ncr_modulo_p { |
return (fac[n] * denominator) % p; | ||
} | ||
}; | ||
} // namespace math |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} // namespace math | |
} // namespace ncr_modulo_p | |
} // namespace math |
math/ncr_modulo_p.cpp
Outdated
// populate the fac array | ||
const uint64_t size = 1e6 + 1; | ||
const uint64_t p = 1e9 + 7; | ||
math::NCRModuloP ncrObj = math::NCRModuloP(size, p); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
math::NCRModuloP ncrObj = math::NCRModuloP(size, p); | |
math::ncr_modulo_p::NCRModuloP ncrObj = math::ncr_modulo_p::NCRModuloP(size, p); |
math/ncr_modulo_p.cpp
Outdated
std::vector<uint64_t> fac{}; | ||
uint64_t p = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a brief description of what the variable does.
std::vector<uint64_t> fac{}; | |
uint64_t p = 0; | |
std::vector<uint64_t> fac{}; ///< brief description | |
uint64_t p = 0; ///< brief description |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Panquesito7 Done! 👍
@Panquesito7 can you review this? 😅 I have made the necessary changes, hope it gets merged soon! |
Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
5b69ba5
to
70bc17b
Compare
70bc17b
to
8b747e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! Thanks for your contribution! 🎉 👍
@ayaankhan98 @kvedala please review this PR. Thanks. 🙂 |
@ayaankhan98 @kvedala can you review this please? 😅 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KaustubhDamania please resolve the merge conflict
@ayaankhan98 done! 👍 can you review this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@ayaankhan98 @Panquesito7 Thanks for reviewing & merging my PR, could you add the |
Done. 🙂 |
Description of Change
Add code for calculating nCr modulo p.
Solves #1323
Checklist