Skip to content
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

Merged
merged 18 commits into from Nov 22, 2020
Merged

Conversation

KaustubhDamania
Copy link
Contributor

@KaustubhDamania KaustubhDamania commented Oct 18, 2020

Description of Change

Add code for calculating nCr modulo p.
Solves #1323

Checklist

  • Added description of change
  • Added file name matches File name guidelines
  • Added tests and example, test must pass
  • Added documentation so that the program is self-explanatory and educational - Doxygen guidelines
  • Relevant documentation/comments is changed or added
  • PR title follows semantic commit guidelines
  • Search previous suggestions before making a new one, as yours may be a duplicate.
  • I acknowledge that all my contributions will be made under the project's license.

@lgtm-com

This comment has been minimized.

@lgtm-com
Copy link

lgtm-com bot commented Oct 18, 2020

This pull request introduces 1 alert when merging ec3899b into 79b98cc - view on LGTM.com

new alerts:

  • 1 for Short global name

@Panquesito7 Panquesito7 added automated tests are failing Do not merge until tests pass enhancement New feature or request Proper Documentation Required requested to write the documentation properly labels Oct 18, 2020
@lgtm-com
Copy link

lgtm-com bot commented Oct 18, 2020

This pull request introduces 1 alert when merging c2f31f8 into 981f781 - view on LGTM.com

new alerts:

  • 1 for Short global name

@lgtm-com
Copy link

lgtm-com bot commented Oct 18, 2020

This pull request introduces 1 alert when merging bd98630 into 981f781 - view on LGTM.com

new alerts:

  • 1 for Short global name

@KaustubhDamania
Copy link
Contributor Author

KaustubhDamania commented Oct 18, 2020

@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.

@Panquesito7 Panquesito7 removed the Proper Documentation Required requested to write the documentation properly label Oct 18, 2020
Co-authored-by: David Leal <halfpacho@gmail.com>
@lgtm-com
Copy link

lgtm-com bot commented Oct 19, 2020

This pull request introduces 1 alert when merging e44b730 into 981f781 - view on LGTM.com

new alerts:

  • 1 for Short global name

@KaustubhDamania KaustubhDamania changed the title feat: Add ncr mod p code (#1323) feat: Add ncr mod p code Oct 19, 2020
@Panquesito7 Panquesito7 removed the automated tests are failing Do not merge until tests pass label Oct 20, 2020
Copy link
Member

@Panquesito7 Panquesito7 left a 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

#include <iostream>
#include <vector>

/** Finds the value of x, y such that a*x + b*y = gcd(a,b)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** 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)

}
}

std::vector<int64_t> fac;
Copy link
Member

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.

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Contributor Author

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

}

// (52323 C 26161) % (1e9 + 7) = 224944353
assert(ncr(52323, 26161, p) == 224944353);
Copy link
Member

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 Panquesito7 added the requested changes changes required label Oct 20, 2020
@KaustubhDamania
Copy link
Contributor Author

@Panquesito7 I have made the required changes, can you review this please?

Comment on lines 7 to 9
#include <cassert>
#include <iostream>
#include <vector>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <cassert>
#include <iostream>
#include <vector>
#include <cassert> /// for assert
#include <iostream> /// for io operations
#include <vector> /// for std::vector

#include <iostream>
#include <vector>

/** Class which contains all methods required for calculating nCr mod p
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** 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

#include <vector>

/** Class which contains all methods required for calculating nCr mod p
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*

}
return (fac[n] * denominator) % p;
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
};
};
} // namespace math

for (int i = 0; i <= 7; i++) {
std::cout << 6 << "C" << i << " = " << ncrObj.ncr(6, i, p) << "\n";
}
tests(ncrObj);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tests(ncrObj);
tests(ncrObj); // execute the tests

}
};

void tests(NCRModuloP ncrObj) {
Copy link
Member

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).

Suggested change
void tests(NCRModuloP ncrObj) {
/**
* @brief Test implementations
* @param ncrObj description
* @returns void
*/
void tests(NCRModuloP ncrObj) {

*/
class NCRModuloP {
private:
std::vector<int64_t> fac;
Copy link
Member

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).

Copy link
Contributor Author

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.

/**
* @file
* @brief This program aims at calculating nCr modulo p
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
*
*
* @author [Kaustubh Damania](https://github.com/KaustubhDamania)

@@ -0,0 +1,122 @@
/**
* @file
* @brief This program aims at calculating nCr modulo p
Copy link
Member

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.

Copy link
Member

@Panquesito7 Panquesito7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good work! 😄 👍

@Panquesito7 Panquesito7 removed the requested changes changes required label Oct 22, 2020
@KaustubhDamania
Copy link
Contributor Author

@ayaankhan98 can you review this? or @Panquesito7 can you merge this? 😅

Comment on lines 25 to 26
std::vector<uint64_t> fac;
uint64_t p;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::vector<uint64_t> fac;
uint64_t p;
std::vector<uint64_t> fac{};
uint64_t p = 0;

* and stores them in vector 'fac'
* @params[in] the numbers 'size', 'mod'
*/
NCRModuloP(uint64_t size, uint64_t mod) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NCRModuloP(uint64_t size, uint64_t mod) {
NCRModuloP(const uint64_t& size, const uint64_t& mod) {

* equation
* @returns the gcd of a and b
*/
uint64_t gcdExtended(uint64_t a, uint64_t b, int64_t *x, int64_t *y) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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) {

* @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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int64_t modInverse(uint64_t a, uint64_t m) {
int64_t modInverse(const uint64_t& a, const uint64_t& m) {

* @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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::cout << "Assertions passed\n";
std::cout << "Assertions passed\n";
return 0;

@@ -0,0 +1,138 @@
/**
* @file
* @brief This program aims at calculating nCr modulo p
Copy link
Member

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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} // namespace math
} // namespace ncr_modulo_p
} // namespace math

// populate the fac array
const uint64_t size = 1e6 + 1;
const uint64_t p = 1e9 + 7;
math::NCRModuloP ncrObj = math::NCRModuloP(size, p);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
math::NCRModuloP ncrObj = math::NCRModuloP(size, p);
math::ncr_modulo_p::NCRModuloP ncrObj = math::ncr_modulo_p::NCRModuloP(size, p);

Comment on lines 31 to 32
std::vector<uint64_t> fac{};
uint64_t p = 0;
Copy link
Member

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.

Suggested change
std::vector<uint64_t> fac{};
uint64_t p = 0;
std::vector<uint64_t> fac{}; ///< brief description
uint64_t p = 0; ///< brief description

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Panquesito7 Done! 👍

@KaustubhDamania
Copy link
Contributor Author

@Panquesito7 can you review this? 😅 I have made the necessary changes, hope it gets merged soon!

math/ncr_modulo_p.cpp Outdated Show resolved Hide resolved
Co-authored-by: David Leal <halfpacho@gmail.com>
math/ncr_modulo_p.cpp Outdated Show resolved Hide resolved
math/ncr_modulo_p.cpp Outdated Show resolved Hide resolved
KaustubhDamania and others added 2 commits November 16, 2020 01:38
Co-authored-by: David Leal <halfpacho@gmail.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
Copy link
Member

@Panquesito7 Panquesito7 left a 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! 🎉 👍

@Panquesito7
Copy link
Member

@ayaankhan98 @kvedala please review this PR. Thanks. 🙂

@KaustubhDamania
Copy link
Contributor Author

@ayaankhan98 @kvedala can you review this please? 😅

Copy link
Member

@ayaankhan98 ayaankhan98 left a 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

@KaustubhDamania
Copy link
Contributor Author

@KaustubhDamania please resolve the merge conflict

@ayaankhan98 done! 👍 can you review this?

Copy link
Member

@ayaankhan98 ayaankhan98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@ayaankhan98 ayaankhan98 merged commit 67e26cf into TheAlgorithms:master Nov 22, 2020
@KaustubhDamania
Copy link
Contributor Author

KaustubhDamania commented Nov 23, 2020

@ayaankhan98 @Panquesito7 Thanks for reviewing & merging my PR, could you add the hacktoberfest-accepted label to it?

@Panquesito7 Panquesito7 added the hacktoberfest-accepted Accepted to be counted towards Hacktoberfest label Nov 23, 2020
@Panquesito7
Copy link
Member

could you add the hacktoberfest-accepted label

Done. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Approved; waiting for merge enhancement New feature or request hacktoberfest-accepted Accepted to be counted towards Hacktoberfest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants