From 808464c4f609105c210b1991de97a5107c087e1a Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 00:13:06 +0530 Subject: [PATCH 01/10] Added mod_inverse_by_fermat_theorem.cpp in math directory. --- math/mod_inverse_by_fermat_theorem.cpp | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 math/mod_inverse_by_fermat_theorem.cpp diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp new file mode 100644 index 000000000..3c306e467 --- /dev/null +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -0,0 +1,59 @@ +// C++ Program to find the modular inverse using Fermat's Little Theorem. +// Fermat's Little Theorem state that => ϕ(m) = m-1, where m is prime number. +/* + * (a * x) ≡ 1 mod m. + * x ≡ (a^(-1)) mod m. + * + * Using Euler's theorem we can modify the equation. + * + * (a^ϕ(m)) ≡ 1 mod m (Where '^' denotes the exponent operator) + * Here 'ϕ' is Euler's Totient Function. For modular inverse existence 'a' and 'm' must be relatively primes numbers. + * To apply Fermat's Little Theorem is necessary that 'm' must be a prime number. + * Generally in many competitive programming competitions 'm' is either 1000000007 (1e9+7) or 998244353. + * + * We considered m as large prime (1e9+7). + * (a^ϕ(m)) ≡ 1 mod m (Using Euler's Theorem) + * ϕ(m) = m-1 using Fermat's Little Theorem. + * (a^(m-1)) ≡ 1 mod m + * Now multiplying both side by (a^(-1)). + * (a^(m-1)) * (a^(-1)) ≡ (a^(-1)) mod m + * (a^(m-2)) ≡ (a^(-1)) mod m + * + * We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time. + * + */ + + #include + #include + + // m is large prime number. + const long long int m = 1000000007; + +// Recursive function to calculate exponent in O(log(n)) using binary exponent. +long long int binExpo(long long int a, long long int b) { + a %= m; + long long int res = 1; + while (b > 0) { + if (b%2) { + res = res * a % m; + } + a = a * a % m; + // Dividing b by 2 is similar to right shift. + b >>= 1; + } + return res; +} + +int main() { + // Take input of a. (A number for which we want to find modular inverse with m) + long long int a; + std::cout << "Give input a for computing ((a^(-1))%(m)) : "; + std::cin >> a; + + std::cout << "The modular inverse of a with mod m is (a^(m-2)) equivalent (a^(-1)) mod m : "; + std::cout << binExpo(a, m-2) << std::endl; +} + + + + From c17b6a9ee0223d0ffee6d2dd29797aeee68c504e Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 00:21:24 +0530 Subject: [PATCH 02/10] Resolve type errors in math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 3c306e467..5276956f7 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -23,16 +23,16 @@ * */ - #include - #include +#include +#include - // m is large prime number. - const long long int m = 1000000007; +// m is large prime number. +const int64_t m = 1000000007; // Recursive function to calculate exponent in O(log(n)) using binary exponent. -long long int binExpo(long long int a, long long int b) { +int64_t binExpo(int64_t a, int64_t b) { a %= m; - long long int res = 1; + int64_t res = 1; while (b > 0) { if (b%2) { res = res * a % m; @@ -46,7 +46,7 @@ long long int binExpo(long long int a, long long int b) { int main() { // Take input of a. (A number for which we want to find modular inverse with m) - long long int a; + int64_t a; std::cout << "Give input a for computing ((a^(-1))%(m)) : "; std::cin >> a; From 5f11e212f8093399ee393640545fd4f124d662dd Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 00:24:16 +0530 Subject: [PATCH 03/10] Resolve line_length errors in math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 5276956f7..73dd6e656 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -45,12 +45,17 @@ int64_t binExpo(int64_t a, int64_t b) { } int main() { - // Take input of a. (A number for which we want to find modular inverse with m) + int64_t a; + /* + Take input of a. + (A number for which we want to find modular inverse with m) + */ + std::cout << "Give input a for computing ((a^(-1))%(m)) : "; std::cin >> a; - std::cout << "The modular inverse of a with mod m is (a^(m-2)) equivalent (a^(-1)) mod m : "; + std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << binExpo(a, m-2) << std::endl; } From 9872a08f277f4432a9e2665cacafd26822d24c2c Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 00:26:15 +0530 Subject: [PATCH 04/10] Remove extra blank lines in math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 73dd6e656..911613353 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -45,16 +45,13 @@ int64_t binExpo(int64_t a, int64_t b) { } int main() { - int64_t a; /* Take input of a. (A number for which we want to find modular inverse with m) */ - std::cout << "Give input a for computing ((a^(-1))%(m)) : "; std::cin >> a; - std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << binExpo(a, m-2) << std::endl; } From 409625656d517f3935f92570b7832a5bd534f483 Mon Sep 17 00:00:00 2001 From: John Law Date: Fri, 8 May 2020 22:45:38 +0200 Subject: [PATCH 05/10] Fix descriptive comment --- math/mod_inverse_by_fermat_theorem.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 911613353..033027933 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -1,6 +1,7 @@ -// C++ Program to find the modular inverse using Fermat's Little Theorem. -// Fermat's Little Theorem state that => ϕ(m) = m-1, where m is prime number. -/* +/* + * C++ Program to find the modular inverse using Fermat's Little Theorem. + * Fermat's Little Theorem state that => ϕ(m) = m-1, where m is prime number. + * * (a * x) ≡ 1 mod m. * x ≡ (a^(-1)) mod m. * @@ -55,7 +56,3 @@ int main() { std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << binExpo(a, m-2) << std::endl; } - - - - From 78eecf75eb29124ce3d5d3bf392574df330495b2 Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 17:27:29 +0530 Subject: [PATCH 06/10] Modified the math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 51 ++++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 033027933..30702b8cd 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -1,6 +1,6 @@ -/* +/* * C++ Program to find the modular inverse using Fermat's Little Theorem. - * Fermat's Little Theorem state that => ϕ(m) = m-1, where m is prime number. + * Fermat's Little Theorem state that => ϕ(m) = m-1, where m is a prime number. * * (a * x) ≡ 1 mod m. * x ≡ (a^(-1)) mod m. @@ -22,16 +22,19 @@ * * We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time. * + * Example: - + * a = 3 and m = 7 + * (a^(-1) mod m) is equivalent to (a^(m-2) mod m) + * (3^(5) mod 7) = (243 mod 7) = 5 + * Hence, ( 3^(-1) mod 7 ) = 5 + * or ( 3 * 5 ) mod 7 = 1 mod 7 (as a*(a^(-1)) = 1) */ #include #include -// m is large prime number. -const int64_t m = 1000000007; - // Recursive function to calculate exponent in O(log(n)) using binary exponent. -int64_t binExpo(int64_t a, int64_t b) { +int64_t binExpo(int64_t a, int64_t b, int64_t m) { a %= m; int64_t res = 1; while (b > 0) { @@ -45,14 +48,30 @@ int64_t binExpo(int64_t a, int64_t b) { return res; } -int main() { - int64_t a; - /* - Take input of a. - (A number for which we want to find modular inverse with m) - */ - std::cout << "Give input a for computing ((a^(-1))%(m)) : "; - std::cin >> a; - std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; - std::cout << binExpo(a, m-2) << std::endl; +// Prime check in O(sqrt(m)) time. +bool isPrime(int64_t m) { + if (m <= 1) { + return false; + } else { + for(int i=2; i*i <= m; i++) { + if (m%i == 0) { + return false; + } + } + } + return true; +} + +int main() { + int64_t a, m; + // Take input of a and m. + std::cout << "Computing ((a^(-1))%(m)) using Fermat's Little Theorem" << std::endl; + std::cout << "Give input 'a' and 'm' space separated (m must be a prime number) : "; + std::cin >> a >> m; + if (isPrime(m)) { + std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; + std::cout << binExpo(a, m-2, m) << std::endl; + } else { + std::cout << "m must be a prime number to apply Fermat's Little Theorem." << std::endl; + } } From 563e29acaef009b433f772dafb02443a9b1a1883 Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 17:31:48 +0530 Subject: [PATCH 07/10] Resolve errors in math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index 30702b8cd..e4b0fa095 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -53,7 +53,7 @@ bool isPrime(int64_t m) { if (m <= 1) { return false; } else { - for(int i=2; i*i <= m; i++) { + for (int i=2; i*i <= m; i++) { if (m%i == 0) { return false; } @@ -65,13 +65,15 @@ bool isPrime(int64_t m) { int main() { int64_t a, m; // Take input of a and m. - std::cout << "Computing ((a^(-1))%(m)) using Fermat's Little Theorem" << std::endl; - std::cout << "Give input 'a' and 'm' space separated (m must be a prime number) : "; + std::cout << "Computing ((a^(-1))%(m)) using Fermat's Little Theorem"; + std:: cout << std::endl << std::endl; + std::cout << "Give input 'a' and 'm' space separated : "; std::cin >> a >> m; if (isPrime(m)) { std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << binExpo(a, m-2, m) << std::endl; } else { - std::cout << "m must be a prime number to apply Fermat's Little Theorem." << std::endl; + std::cout << "m must be a prime number to apply Fermat's Little Theorem."; + std::cout << std::endl; } } From c9fc01af7a0c37973a3977916dda45fdd14e8fd0 Mon Sep 17 00:00:00 2001 From: Mann Mehta <44433995+mann2108@users.noreply.github.com> Date: Sat, 9 May 2020 17:33:08 +0530 Subject: [PATCH 08/10] Resolve line length errors in math/mod_inverse_by_fermat_theorem.cpp --- math/mod_inverse_by_fermat_theorem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/mod_inverse_by_fermat_theorem.cpp index e4b0fa095..fde19dc52 100644 --- a/math/mod_inverse_by_fermat_theorem.cpp +++ b/math/mod_inverse_by_fermat_theorem.cpp @@ -73,7 +73,7 @@ int main() { std::cout << "The modular inverse of a with mod m is (a^(m-2)) : "; std::cout << binExpo(a, m-2, m) << std::endl; } else { - std::cout << "m must be a prime number to apply Fermat's Little Theorem."; + std::cout << "m must be a prime number."; std::cout << std::endl; } } From 8f41e1704d60a8ca29085a7fd93dd5ddb3657974 Mon Sep 17 00:00:00 2001 From: John Law Date: Mon, 11 May 2020 00:54:45 +0200 Subject: [PATCH 09/10] Rename mod_inverse_by_fermat_theorem.cpp to modular_inverse_fermat_little_theorem.cpp --- ...rmat_theorem.cpp => modular_inverse_fermat_little_theorem.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename math/{mod_inverse_by_fermat_theorem.cpp => modular_inverse_fermat_little_theorem.cpp} (100%) diff --git a/math/mod_inverse_by_fermat_theorem.cpp b/math/modular_inverse_fermat_little_theorem.cpp similarity index 100% rename from math/mod_inverse_by_fermat_theorem.cpp rename to math/modular_inverse_fermat_little_theorem.cpp From 264a26e15a70d94ba630b4638278d8480386e4f5 Mon Sep 17 00:00:00 2001 From: John Law Date: Mon, 11 May 2020 00:55:16 +0200 Subject: [PATCH 10/10] Fix spacing --- math/modular_inverse_fermat_little_theorem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/modular_inverse_fermat_little_theorem.cpp b/math/modular_inverse_fermat_little_theorem.cpp index fde19dc52..965c21298 100644 --- a/math/modular_inverse_fermat_little_theorem.cpp +++ b/math/modular_inverse_fermat_little_theorem.cpp @@ -66,7 +66,7 @@ int main() { int64_t a, m; // Take input of a and m. std::cout << "Computing ((a^(-1))%(m)) using Fermat's Little Theorem"; - std:: cout << std::endl << std::endl; + std::cout << std::endl << std::endl; std::cout << "Give input 'a' and 'm' space separated : "; std::cin >> a >> m; if (isPrime(m)) {