Skip to content

Commit 3e409e8

Browse files
committed
refactor: add utils namespace
1 parent 9ad083d commit 3e409e8

File tree

1 file changed

+41
-39
lines changed

1 file changed

+41
-39
lines changed

math/ncr_modulo_p.cpp

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,45 @@ namespace math {
2525
* implementation.
2626
*/
2727
namespace ncr_modulo_p {
28+
29+
namespace utils {
30+
/** Finds the value of x, y such that a*x + b*y = gcd(a,b)
31+
*
32+
* @params[in] the numbers 'a', 'b' and address of 'x' and 'y' from above
33+
* equation
34+
* @returns the gcd of a and b
35+
*/
36+
uint64_t gcdExtended(const uint64_t& a, const uint64_t& b, int64_t* x,
37+
int64_t* y) {
38+
if (a == 0) {
39+
*x = 0, *y = 1;
40+
return b;
41+
}
42+
43+
int64_t x1 = 0, y1 = 0;
44+
uint64_t gcd = gcdExtended(b % a, a, &x1, &y1);
45+
46+
*x = y1 - (b / a) * x1;
47+
*y = x1;
48+
return gcd;
49+
}
50+
51+
/** Find modular inverse of a with m i.e. a number x such that (a*x)%m = 1
52+
*
53+
* @params[in] the numbers 'a' and 'm' from above equation
54+
* @returns the modular inverse of a
55+
*/
56+
int64_t modInverse(const uint64_t& a, const uint64_t& m) {
57+
int64_t x = 0, y = 0;
58+
uint64_t g = gcdExtended(a, m, &x, &y);
59+
if (g != 1) { // modular inverse doesn't exist
60+
return -1;
61+
} else {
62+
int64_t res = ((x + m) % m);
63+
return res;
64+
}
65+
}
66+
}; // namespace utils
2867
/**
2968
* @brief Class which contains all methods required for calculating nCr mod p
3069
*/
@@ -47,43 +86,6 @@ class NCRModuloP {
4786
}
4887
}
4988

50-
/** Finds the value of x, y such that a*x + b*y = gcd(a,b)
51-
*
52-
* @params[in] the numbers 'a', 'b' and address of 'x' and 'y' from above
53-
* equation
54-
* @returns the gcd of a and b
55-
*/
56-
uint64_t gcdExtended(const uint64_t& a, const uint64_t& b, int64_t* x,
57-
int64_t* y) {
58-
if (a == 0) {
59-
*x = 0, *y = 1;
60-
return b;
61-
}
62-
63-
int64_t x1 = 0, y1 = 0;
64-
uint64_t gcd = gcdExtended(b % a, a, &x1, &y1);
65-
66-
*x = y1 - (b / a) * x1;
67-
*y = x1;
68-
return gcd;
69-
}
70-
71-
/** Find modular inverse of a with m i.e. a number x such that (a*x)%m = 1
72-
*
73-
* @params[in] the numbers 'a' and 'm' from above equation
74-
* @returns the modular inverse of a
75-
*/
76-
int64_t modInverse(const uint64_t& a, const uint64_t& m) {
77-
int64_t x = 0, y = 0;
78-
uint64_t g = gcdExtended(a, m, &x, &y);
79-
if (g != 1) { // modular inverse doesn't exist
80-
return -1;
81-
} else {
82-
int64_t res = ((x + m) % m);
83-
return res;
84-
}
85-
}
86-
8789
/** Find nCr % p
8890
*
8991
* @params[in] the numbers 'n', 'r' and 'p'
@@ -101,11 +103,11 @@ class NCRModuloP {
101103
return 1;
102104
}
103105
// fac is a global array with fac[r] = (r! % p)
104-
int64_t denominator = modInverse(fac[r], p);
106+
int64_t denominator = utils::modInverse(fac[r], p);
105107
if (denominator < 0) { // modular inverse doesn't exist
106108
return -1;
107109
}
108-
denominator = (denominator * modInverse(fac[n - r], p)) % p;
110+
denominator = (denominator * utils::modInverse(fac[n - r], p)) % p;
109111
if (denominator < 0) { // modular inverse doesn't exist
110112
return -1;
111113
}

0 commit comments

Comments
 (0)