diff --git a/DIRECTORY.md b/DIRECTORY.md index f8440a770..37132246b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -109,8 +109,8 @@ * [Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/factorial.cpp) * [Fast Power](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fast_power.cpp) * [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp) - * [Greatest Common Divisor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor.cpp) - * [Greatest Common Divisor Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/greatest_common_divisor_euclidean.cpp) + * [Gcd Iterative Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_iterative_euclidean.cpp) + * [Gcd Recursive Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_recursive_euclidean.cpp) * [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp) * [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp) * [Power For Huge Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/power_for_huge_numbers.cpp) diff --git a/math/README.md b/math/README.md index 4ac39c878..d7b862f9f 100644 --- a/math/README.md +++ b/math/README.md @@ -1,3 +1,4 @@ +# Prime factorization # {#section} Prime Factorization is a very important and useful technique to factorize any number into its prime factors. It has various applications in the field of number theory. The method of prime factorization involves two function calls. diff --git a/math/binary_exponent.cpp b/math/binary_exponent.cpp index b4551da25..05e6f33f7 100644 --- a/math/binary_exponent.cpp +++ b/math/binary_exponent.cpp @@ -1,46 +1,57 @@ -/// C++ Program to find Binary Exponent Iteratively and Recursively. - -#include -/* - * Calculate a^b in O(log(b)) by converting b to a binary number. - * Binary exponentiation is also known as exponentiation by squaring. - * NOTE : This is a far better approach compared to naive method which provide O(b) operations. +/** + * @file + * @brief C++ Program to find Binary Exponent Iteratively and Recursively. + * + * Calculate \f$a^b\f$ in \f$O(\log(b))\f$ by converting \f$b\f$ to a + * binary number. Binary exponentiation is also known as exponentiation by + * squaring. + * @note This is a far better approach compared to naive method which + * provide \f$O(b)\f$ operations. + * * Example: - * 10 in base 2 is 1010. - * 2^10 = 2^(1010) = 2^8 * 2^2 - * 2^1 = 2 - * 2^2 = (2^1)^2 = 2^2 = 4 - * 2^4 = (2^2)^2 = 4^2 = 16 - * 2^8 = (2^4)^2 = 16^2 = 256 - * Hence to calculate 2^10 we only need to multiply 2^8 and 2^2 skipping 2^1 and 2^4. -*/ + *
10 in base 2 is 1010. + * \f{eqnarray*}{ + * 2^{10_d} &=& 2^{1010_b} = 2^8 * 2^2\\ + * 2^1 &=& 2\\ + * 2^2 &=& (2^1)^2 = 2^2 = 4\\ + * 2^4 &=& (2^2)^2 = 4^2 = 16\\ + * 2^8 &=& (2^4)^2 = 16^2 = 256\\ + * \f} + * Hence to calculate 2^10 we only need to multiply \f$2^8\f$ and \f$2^2\f$ + * skipping \f$2^1\f$ and \f$2^4\f$. + */ -/// Recursive function to calculate exponent in O(log(n)) using binary exponent. +#include + +/// Recursive function to calculate exponent in \f$O(\log(n))\f$ using binary +/// exponent. int binExpo(int a, int b) { if (b == 0) { return 1; } - int res = binExpo(a, b/2); - if (b%2) { - return res*res*a; + int res = binExpo(a, b / 2); + if (b % 2) { + return res * res * a; } else { - return res*res; + return res * res; } } -/// Iterative function to calculate exponent in O(log(n)) using binary exponent. +/// Iterative function to calculate exponent in \f$O(\log(n))\f$ using binary +/// exponent. int binExpo_alt(int a, int b) { int res = 1; while (b > 0) { - if (b%2) { - res = res*a; + if (b % 2) { + res = res * a; } - a = a*a; + a = a * a; b /= 2; } return res; } +/// Main function int main() { int a, b; /// Give two numbers a, b diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 7b0d1d970..37bd2052a 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -1,28 +1,39 @@ -#include +/** + * @file + * @brief Compute double factorial: \f$n!!\f$ + * + * Double factorial of a non-negative integer n, is defined as the product of + * all the integers from 1 to n that have the same parity (odd or even) as n. + *
It is also called as semifactorial of a number and is denoted by + * \f$n!!\f$ + */ + #include +#include -/* Double factorial of a non-negative integer n, is defined as the product of -all the integers from 1 to n that have the same parity (odd or even) as n. -It is also called as semifactorial of a number and is denoted by !! */ - +/** Compute double factorial using iterative method + */ uint64_t double_factorial_iterative(uint64_t n) { - uint64_t res = 1; - for ( uint64_t i = n; i >= 0; i -= 2 ) { - if (i == 0 || i == 1) return res; - res *= i; - } + uint64_t res = 1; + for (uint64_t i = n;; i -= 2) { + if (i == 0 || i == 1) return res; + res *= i; + } + return res; } -/* Recursion can be costly for large numbers */ - +/** Compute double factorial using resursive method. + *
Recursion can be costly for large numbers. + */ uint64_t double_factorial_recursive(uint64_t n) { - if (n <= 1) return 1; - return n * double_factorial_recursive(n - 2); + if (n <= 1) return 1; + return n * double_factorial_recursive(n - 2); } +/// main function int main() { - uint64_t n{}; - std::cin >> n; - assert(n >= 0); - std::cout << double_factorial_iterative(n); + uint64_t n; + std::cin >> n; + assert(n >= 0); + std::cout << double_factorial_iterative(n); } diff --git a/math/eulers_totient_function.cpp b/math/eulers_totient_function.cpp index 31ced5a51..e7f6fbf7f 100644 --- a/math/eulers_totient_function.cpp +++ b/math/eulers_totient_function.cpp @@ -1,28 +1,37 @@ -/// C++ Program to find Euler Totient Function -#include - -/* +/** + * @file + * @brief C++ Program to find + * [Euler's Totient](https://en.wikipedia.org/wiki/Euler%27s_totient_function) + * function + * * Euler Totient Function is also known as phi function. - * phi(n) = phi(p1^a1).phi(p2^a2)... - * where p1, p2,... are prime factors of n. - * 3 Euler's properties: - * 1. phi(prime_no) = prime_no-1 - * 2. phi(prime_no^k) = (prime_no^k - prime_no^(k-1)) - * 3. phi(a,b) = phi(a). phi(b) where a and b are relative primes. + * \f[\phi(n) = + * \phi\left({p_1}^{a_1}\right)\cdot\phi\left({p_2}^{a_2}\right)\ldots\f] where + * \f$p_1\f$, \f$p_2\f$, \f$\ldots\f$ are prime factors of n. + *
3 Euler's properties: + * 1. \f$\phi(n) = n-1\f$ + * 2. \f$\phi(n^k) = n^k - n^{k-1}\f$ + * 3. \f$\phi(a,b) = \phi(a)\cdot\phi(b)\f$ where a and b are relative primes. + * * Applying this 3 properties on the first equation. - * phi(n) = n. (1-1/p1). (1-1/p2). ... - * where p1,p2... are prime factors. - * Hence Implementation in O(sqrt(n)). - * phi(100) = 40 - * phi(1) = 1 - * phi(17501) = 15120 - * phi(1420) = 560 + * \f[\phi(n) = + * n\cdot\left(1-\frac{1}{p_1}\right)\cdot\left(1-\frac{1}{p_2}\right)\cdots\f] + * where \f$p_1\f$,\f$p_2\f$... are prime factors. + * Hence Implementation in \f$O\left(\sqrt{n}\right)\f$. + *
Some known values are: + * * \f$\phi(100) = 40\f$ + * * \f$\phi(1) = 1\f$ + * * \f$\phi(17501) = 15120\f$ + * * \f$\phi(1420) = 560\f$ */ +#include +#include -// Function to caculate Euler's totient phi -int phiFunction(int n) { - int result = n; - for (int i = 2; i * i <= n; i++) { +/** Function to caculate Euler's totient phi + */ +uint64_t phiFunction(uint64_t n) { + uint64_t result = n; + for (uint64_t i = 2; i * i <= n; i++) { if (n % i == 0) { while (n % i == 0) { n /= i; @@ -34,8 +43,15 @@ int phiFunction(int n) { return result; } -int main() { - int n; +/// Main function +int main(int argc, char *argv[]) { + uint64_t n; + if (argc < 2) { + std::cout << "Enter the number: "; + } else { + n = strtoull(argv[1], nullptr, 10); + } std::cin >> n; std::cout << phiFunction(n); + return 0; } diff --git a/math/extended_euclid_algorithm.cpp b/math/extended_euclid_algorithm.cpp index 3db14802f..3fdae25b5 100644 --- a/math/extended_euclid_algorithm.cpp +++ b/math/extended_euclid_algorithm.cpp @@ -1,28 +1,94 @@ +/** + * @file + * @brief GCD using [extended Euclid's algorithm] + * (https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm) + * + * Finding coefficients of a and b ie x and y in Bézout's identity + * \f[\text{gcd}(a, b) = a \times x + b \times y \f] + * This is also used in finding Modular + * multiplicative inverse of a number. (A * B)%M == 1 Here B is the MMI of A for + * given M, so extendedEuclid (A, M) gives B. + */ +#include // for swap function #include -// Finding coefficients of a and b ie x and y in gcd(a, b) = a * x + b * y -// d is gcd(a, b) -// This is also used in finding Modular multiplicative inverse of a number. -// (A * B)%M == 1 Here B is the MMI of A for given M, -// so extendedEuclid (A, M) gives B. -int d, x, y; -void extendedEuclid(int A, int B) { +/** + * function to update the coefficients per iteration + * \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f] + * + * @param[in,out] r signed or unsigned + * @param[in,out] r0 signed or unsigned + * @param[in] quotient unsigned + */ +template +inline void update_step(T *r, T *r0, const T2 quotient) { + T temp = *r; + *r = *r0 - (quotient * temp); + *r0 = temp; +} + +/** + * Implementation using iterative algorithm from + * [Wikipedia](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode) + * + * @param[in] A unsigned + * @param[in] B unsigned + * @param[out] GCD unsigned + * @param[out] x signed + * @param[out] y signed + */ +template +void extendedEuclid_1(T1 A, T1 B, T1 *GCD, T2 *x, T2 *y) { + if (B > A) std::swap(A, B); // Ensure that A >= B + + T2 s = 0, s0 = 1; + T2 t = 1, t0 = 0; + T1 r = B, r0 = A; + + while (r != 0) { + T1 quotient = r0 / r; + update_step(&r, &r0, quotient); + update_step(&s, &s0, quotient); + update_step(&t, &t0, quotient); + } + *GCD = r0; + *x = s0; + *y = t0; +} + +/** + * Implementation using recursive algorithm + * + * @param[in] A unsigned + * @param[in] B unsigned + * @param[out] GCD unsigned + * @param[in,out] x signed + * @param[in,out] y signed + */ +template +void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) { + if (B > A) std::swap(A, B); // Ensure that A >= B + if (B == 0) { - d = A; - x = 1; - y = 0; + *GCD = A; + *x = 1; + *y = 0; } else { - extendedEuclid(B, A%B); - int temp = x; - x = y; - y = temp - (A/B)*y; + extendedEuclid(B, A % B, GCD, x, y); + T2 temp = *x; + *x = *y; + *y = temp - (A / B) * (*y); } } +/// Main function int main() { - int a, b; + uint32_t a, b, gcd; + int32_t x, y; std::cin >> a >> b; - extendedEuclid(a, b); - std::cout << x << " " << y << std::endl; + extendedEuclid(a, b, &gcd, &x, &y); + std::cout << gcd << " " << x << " " << y << std::endl; + extendedEuclid_1(a, b, &gcd, &x, &y); + std::cout << gcd << " " << x << " " << y << std::endl; return 0; } diff --git a/math/fast_power.cpp b/math/fast_power.cpp index 0ffbcd40d..d4de07460 100644 --- a/math/fast_power.cpp +++ b/math/fast_power.cpp @@ -1,15 +1,16 @@ /** * @file - Program that computes \f$a^b\f$ in \f$O(logN)\f$ time. - It is based on formula that: - 1. if \f$b\f$ is even: \f$a^b = a^\frac{b}{2} \cdot a^\frac{b}{2} = - {a^\frac{b}{2}}^2\f$ - 2. if \f$b\f$ is odd: \f$a^b = a^\frac{b-1}{2} \cdot - a^\frac{b-1}{2} \cdot a = {a^\frac{b-1}{2}}^2 \cdot a\f$ - - We can compute \f$a^b\f$ - recursively using above algorithm. -*/ + * @brief Faster computation for \f$a^b\f$ + * + * Program that computes \f$a^b\f$ in \f$O(logN)\f$ time. + * It is based on formula that: + * 1. if \f$b\f$ is even: + * \f$a^b = a^\frac{b}{2} \cdot a^\frac{b}{2} = {a^\frac{b}{2}}^2\f$ + * 2. if \f$b\f$ is odd: \f$a^b = a^\frac{b-1}{2} + * \cdot a^\frac{b-1}{2} \cdot a = {a^\frac{b-1}{2}}^2 \cdot a\f$ + * + * We can compute \f$a^b\f$ recursively using above algorithm. + */ #include #include @@ -21,16 +22,17 @@ /** * algorithm implementation for \f$a^b\f$ */ -double fast_power_recursive(int64_t a, int64_t b) { +template +double fast_power_recursive(T a, T b) { // negative power. a^b = 1 / (a^-b) if (b < 0) return 1.0 / fast_power_recursive(a, -b); if (b == 0) return 1; - int64_t bottom = fast_power_recursive(a, b >> 1); + T bottom = fast_power_recursive(a, b >> 1); // Since it is integer division b/2 = (b-1)/2 where b is odd. // Therefore, case2 is easily solved by integer division. - int64_t result; + double result; if ((b & 1) == 0) // case1 result = bottom * bottom; else // case2 @@ -40,9 +42,10 @@ double fast_power_recursive(int64_t a, int64_t b) { /** Same algorithm with little different formula. - It still calculates in O(logN) + It still calculates in \f$O(\log N)\f$ */ -double fast_power_linear(int64_t a, int64_t b) { +template +double fast_power_linear(T a, T b) { // negative power. a^b = 1 / (a^-b) if (b < 0) return 1.0 / fast_power_linear(a, -b); @@ -55,6 +58,9 @@ double fast_power_linear(int64_t a, int64_t b) { return result; } +/** + * Main function + */ int main() { std::srand(std::time(nullptr)); std::ios_base::sync_with_stdio(false); diff --git a/math/fibonacci.cpp b/math/fibonacci.cpp index e82875da3..1a5f4afb4 100644 --- a/math/fibonacci.cpp +++ b/math/fibonacci.cpp @@ -1,12 +1,17 @@ +/** + * @file + * @brief Generate fibonacci sequence + * + * Calculate the the value on Fibonacci's sequence given an + * integer as input. + * \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f] + */ #include #include -/* Calculate the the value on Fibonacci's sequence given an -integer as input -Fibonacci = 0, 1, 1, 2, 3, 5, - 8, 13, 21, 34, 55, - 89, 144, ... */ - +/** + * Recursively compute sequences + */ int fibonacci(unsigned int n) { /* If the input is 0 or 1 just return the same This will set the first 2 values of the sequence */ @@ -16,6 +21,7 @@ int fibonacci(unsigned int n) { return fibonacci(n - 1) + fibonacci(n - 2); } +/// Main function int main() { int n; std::cin >> n; diff --git a/math/greatest_common_divisor_euclidean.cpp b/math/gcd_iterative_euclidean.cpp similarity index 80% rename from math/greatest_common_divisor_euclidean.cpp rename to math/gcd_iterative_euclidean.cpp index c4812e45b..61fb640a3 100644 --- a/math/greatest_common_divisor_euclidean.cpp +++ b/math/gcd_iterative_euclidean.cpp @@ -1,10 +1,17 @@ -#include +/** + * @file + * @brief Compute the greatest common denominator of two integers using + * *iterative form* of + * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) + * + * @see gcd_recursive_euclidean.cpp + */ #include #include -// will find the greatest common denominator of two ints integers -// Euclidean algorithm can be found here -// https://en.wikipedia.org/wiki/Euclidean_algorithm +/** + * algorithm + */ int gcd(int num1, int num2) { if (num1 <= 0 | num2 <= 0) { throw std::domain_error("Euclidean algorithm domain is for ints > 0"); @@ -34,6 +41,9 @@ int gcd(int num1, int num2) { return previous_remainder; } +/** + * Main function + */ int main() { std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl; try { diff --git a/math/gcd_recursive_euclidean.cpp b/math/gcd_recursive_euclidean.cpp new file mode 100644 index 000000000..3a1ca6e66 --- /dev/null +++ b/math/gcd_recursive_euclidean.cpp @@ -0,0 +1,48 @@ +/** + * @file + * @brief Compute the greatest common denominator of two integers using + * *recursive form* of + * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) + * + * @see gcd_iterative_euclidean.cpp + */ +#include + +/** + * algorithm + */ +int gcd(int num1, int num2) { + if (num1 <= 0 | num2 <= 0) { + throw std::domain_error("Euclidean algorithm domain is for ints > 0"); + } + + if (num1 == num2) { + return num1; + } + + // Everything divides 0 + if (num1 == 0) return num2; + if (num2 == 0) return num1; + + // base case + if (num1 == num2) return num1; + + // a is greater + if (num1 > num2) return gcd(num1 - num2, num2); + return gcd(num1, num2 - num1); +} + +/** + * Main function + */ +int main() { + std::cout << "gcd of 120,7 is " << (gcd(120, 7)) << std::endl; + try { + std::cout << "gcd of -120,10 is " << gcd(-120, 10) << std::endl; + } catch (const std::domain_error &e) { + std::cout << "Error handling was successful" << std::endl; + } + std::cout << "gcd of 312,221 is " << (gcd(312, 221)) << std::endl; + std::cout << "gcd of 289,204 is " << (gcd(289, 204)) << std::endl; + return 0; +} diff --git a/math/greatest_common_divisor.cpp b/math/greatest_common_divisor.cpp deleted file mode 100644 index 5601c4be9..000000000 --- a/math/greatest_common_divisor.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// C++ program to find GCD of two numbers -#include - -// Recursive function to return gcd of a and b -int gcd(int a, int b) { - // Everything divides 0 - if (a == 0) - return b; - if (b == 0) - return a; - - // base case - if (a == b) - return a; - - // a is greater - if (a > b) - return gcd(a-b, b); - return gcd(a, b-a); -} - -// Driver program to test above function -int main() { - int a = 98, b = 56; - std::cout << "GCD of " << a << " and " << b << " is " << gcd(a, b); - return 0; -} diff --git a/math/modular_inverse_fermat_little_theorem.cpp b/math/modular_inverse_fermat_little_theorem.cpp index 965c21298..7550e14bf 100644 --- a/math/modular_inverse_fermat_little_theorem.cpp +++ b/math/modular_inverse_fermat_little_theorem.cpp @@ -1,44 +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 a prime number. - * - * (a * x) ≡ 1 mod m. - * x ≡ (a^(-1)) mod m. +/** + * @file + * @brief C++ Program to find the modular inverse using [Fermat's Little + * Theorem](https://en.wikipedia.org/wiki/Fermat%27s_little_theorem) * + * Fermat's Little Theorem state that \f[ϕ(m) = m-1\f] + * where \f$m\f$ is a prime number. + * \f{eqnarray*}{ + * a \cdot x &≡& 1 \;\text{mod}\; m\\ + * x &≡& a^{-1} \;\text{mod}\; m + * \f} * Using Euler's theorem we can modify the equation. + *\f[ + * a^{ϕ(m)} ≡ 1 \;\text{mod}\; m + * \f] + * (Where '^' denotes the exponent operator) * - * (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. + * 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 + * \f$a^{ϕ(m)} ≡ 1 \;\text{mod}\; m\f$ (Using Euler's Theorem) + * \f$ϕ(m) = m-1\f$ using Fermat's Little Theorem. + * \f$a^{m-1} ≡ 1 \;\text{mod}\; m\f$ + * Now multiplying both side by \f$a^{-1}\f$. + * \f{eqnarray*}{ + * a^{m-1} \cdot a^{-1} &≡& a^{-1} \;\text{mod}\; m\\ + * a^{m-2} &≡& a^{-1} \;\text{mod}\; m + * \f} * - * We will find the exponent using binary exponentiation. Such that the algorithm works in O(log(m)) time. + * We will find the exponent using binary exponentiation. Such that the + * algorithm works in \f$O(\log m)\f$ 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) + * Examples: - + * * a = 3 and m = 7 + * * \f$a^{-1} \;\text{mod}\; m\f$ is equivalent to + * \f$a^{m-2} \;\text{mod}\; m\f$ + * * \f$3^5 \;\text{mod}\; 7 = 243 \;\text{mod}\; 7 = 5\f$ + *
Hence, \f$3^{-1} \;\text{mod}\; 7 = 5\f$ + * or \f$3 \times 5 \;\text{mod}\; 7 = 1 \;\text{mod}\; 7\f$ + * (as \f$a\times a^{-1} = 1\f$) */ -#include -#include +#include +#include -// Recursive function to calculate exponent in O(log(n)) using binary exponent. +/** Recursive function to calculate exponent in \f$O(\log n)\f$ using binary + * exponent. + */ int64_t binExpo(int64_t a, int64_t b, int64_t m) { a %= m; int64_t res = 1; while (b > 0) { - if (b%2) { + if (b % 2) { res = res * a % m; } a = a * a % m; @@ -48,13 +63,14 @@ int64_t binExpo(int64_t a, int64_t b, int64_t m) { return res; } -// Prime check in O(sqrt(m)) time. +/** Prime check in \f$O(\sqrt{m})\f$ time. + */ bool isPrime(int64_t m) { if (m <= 1) { return false; } else { - for (int i=2; i*i <= m; i++) { - if (m%i == 0) { + for (int64_t i = 2; i * i <= m; i++) { + if (m % i == 0) { return false; } } @@ -62,6 +78,9 @@ bool isPrime(int64_t m) { return true; } +/** + * Main function + */ int main() { int64_t a, m; // Take input of a and m. @@ -71,7 +90,7 @@ int main() { 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; + std::cout << binExpo(a, m - 2, m) << std::endl; } else { std::cout << "m must be a prime number."; std::cout << std::endl; diff --git a/math/number_of_positive_divisors.cpp b/math/number_of_positive_divisors.cpp index 48ab63c36..f157f7b41 100644 --- a/math/number_of_positive_divisors.cpp +++ b/math/number_of_positive_divisors.cpp @@ -1,34 +1,39 @@ -/// C++ Program to calculate number of divisors. - -#include -#include - /** + * @file + * @brief C++ Program to calculate number of divisors + * * This algorithm use the prime factorization approach. * Any number can be written in multiplication of its prime factors. - * Let N = P1^E1 * P2^E2 ... Pk^Ek - * Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1). - * Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents respectively. + *
Let N = P1^E1 * P2^E2 ... Pk^Ek + *
Therefore. number-of-divisors(N) = (E1+1) * (E2+1) ... (Ek+1). + *
Where P1, P2 ... Pk are prime factors and E1, E2 ... Ek are exponents +respectively. * * Example:- - * N = 36 - * 36 = (3^2 * 2^2) - * number_of_positive_divisors(36) = (2+1) * (2+1) = 9. - * list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36. + *
N = 36 + *
36 = (3^2 * 2^2) + *
number_of_positive_divisors(36) = (2+1) * (2+1) = 9. + *
list of positive divisors of 36 = 1, 2, 3, 4, 6, 9, 12, 18, 36. * * Similarly if N is -36 at that time number of positive divisors remain same. * * Example:- - * N = -36 - * -36 = -1 * (3^2 * 2^2) - * number_of_positive_divisors(-36) = (2+1) * (2+1) = 9. - * list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36. + *
N = -36 + *
-36 = -1 * (3^2 * 2^2) + *
number_of_positive_divisors(-36) = (2+1) * (2+1) = 9. + *
list of positive divisors of -36 = 1, 2, 3, 4, 6, 9, 12, 18, 36. * **/ +#include +#include + +/** + * Algorithm + */ int number_of_positive_divisors(int n) { std::vector prime_exponent_count; - for (int i=2; i*i <= n; i++) { + for (int i = 2; i * i <= n; i++) { int prime_count = 0; while (n % i == 0) { prime_count += 1; @@ -44,13 +49,16 @@ int number_of_positive_divisors(int n) { int divisors_count = 1; - for (int i=0; i < prime_exponent_count.size(); i++) { - divisors_count = divisors_count * (prime_exponent_count[i]+1); + for (int i = 0; i < prime_exponent_count.size(); i++) { + divisors_count = divisors_count * (prime_exponent_count[i] + 1); } return divisors_count; } +/** + * Main function + */ int main() { int n; std::cin >> n; diff --git a/math/power_for_huge_numbers.cpp b/math/power_for_huge_numbers.cpp index bf9374228..5cb1ae514 100644 --- a/math/power_for_huge_numbers.cpp +++ b/math/power_for_huge_numbers.cpp @@ -1,91 +1,90 @@ +/** + * @file + * @brief Compute powers of large numbers + */ #include -using namespace std; -// Maximum number of digits in output -// x^n where 1 <= x, n <= 10000 and overflow may happen +/** Maximum number of digits in output + * \f$x^n\f$ where \f$1 <= x,\; n <= 10000\f$ and overflow may happen + */ #define MAX 100000 -// This function multiplies x -// with the number represented by res[]. -// res_size is size of res[] or -// number of digits in the number -// represented by res[]. This function -// uses simple school mathematics -// for multiplication. -// This function may value of res_size -// and returns the new value of res_size -int multiply(int x, int res[], int res_size) -{ +/** This function multiplies x + * with the number represented by res[]. + * res_size is size of res[] or + * number of digits in the number + * represented by res[]. This function + * uses simple school mathematics + * for multiplication. + * This function may value of res_size + * and returns the new value of res_size + * @param x multiplicand + * @param res large number representation using array + * @param res_size number of digits in `res` + */ +int multiply(int x, int res[], int res_size) { + // Initialize carry + int carry = 0; - // Initialize carry - int carry = 0; + // One by one multiply n with + // individual digits of res[] + for (int i = 0; i < res_size; i++) { + int prod = res[i] * x + carry; - // One by one multiply n with - // individual digits of res[] - for (int i = 0; i < res_size; i++) - { - int prod = res[i] * x + carry; + // Store last digit of + // 'prod' in res[] + res[i] = prod % 10; - // Store last digit of - // 'prod' in res[] - res[i] = prod % 10; + // Put rest in carry + carry = prod / 10; + } - // Put rest in carry - carry = prod / 10; - } - - // Put carry in res and - // increase result size - while (carry) - { - res[res_size] = carry % 10; - carry = carry / 10; - res_size++; - } - return res_size; + // Put carry in res and + // increase result size + while (carry) { + res[res_size] = carry % 10; + carry = carry / 10; + res_size++; + } + return res_size; } -// This function finds -// power of a number x -void power(int x, int n) -{ +/** This function finds power of a number x and print \f$x^n\f$ + * @param x base + * @param n exponent + */ +void power(int x, int n) { + // printing value "1" for power = 0 + if (n == 0) { + std::cout << "1"; + return; + } - //printing value "1" for power = 0 - if (n == 0) - { - cout << "1"; - return; - } + int res[MAX]; + int res_size = 0; + int temp = x; - int res[MAX]; - int res_size = 0; - int temp = x; + // Initialize result + while (temp != 0) { + res[res_size++] = temp % 10; + temp = temp / 10; + } - // Initialize result - while (temp != 0) - { - res[res_size++] = temp % 10; - temp = temp / 10; - } + // Multiply x n times + // (x^n = x*x*x....n times) + for (int i = 2; i <= n; i++) res_size = multiply(x, res, res_size); - // Multiply x n times - // (x^n = x*x*x....n times) - for (int i = 2; i <= n; i++) - res_size = multiply(x, res, res_size); - - cout << x << "^" << n << " = "; - for (int i = res_size - 1; i >= 0; i--) - cout << res[i]; + std::cout << x << "^" << n << " = "; + for (int i = res_size - 1; i >= 0; i--) std::cout << res[i]; } -// Driver program -int main() -{ - int exponent, base; - printf("Enter base "); - scanf("%id \n", &base); - printf("Enter exponent "); - scanf("%id", &exponent); - power(base, exponent); - return 0; +/** Main function */ +int main() { + int exponent, base; + printf("Enter base "); + scanf("%id \n", &base); + printf("Enter exponent "); + scanf("%id", &exponent); + power(base, exponent); + return 0; } diff --git a/math/prime_factorization.cpp b/math/prime_factorization.cpp index c018de666..d0e05cb4c 100644 --- a/math/prime_factorization.cpp +++ b/math/prime_factorization.cpp @@ -1,15 +1,25 @@ +/** + * @file + * @brief Prime factorization of positive integers + */ #include #include #include #include -// Declaring variables for maintaing prime numbers and to check whether a number -// is prime or not +/** Declaring variables for maintaing prime numbers and to check whether a + * number is prime or not + */ bool isprime[1000006]; + +/** list of prime numbers */ std::vector prime_numbers; + +/** list of prime factor-pairs */ std::vector> factors; -// Calculating prime number upto a given range +/** Calculating prime number upto a given range + */ void SieveOfEratosthenes(int N) { // initializes the array isprime memset(isprime, true, sizeof isprime); @@ -25,7 +35,7 @@ void SieveOfEratosthenes(int N) { } } -// Prime factorization of a number +/** Prime factorization of a number */ void prime_factorization(int num) { int number = num; @@ -46,9 +56,7 @@ void prime_factorization(int num) { } } -/* - I added a simple UI. -*/ +/** Main program */ int main() { int num; std::cout << "\t\tComputes the prime factorization\n\n"; diff --git a/math/prime_numbers.cpp b/math/prime_numbers.cpp index 7264ff528..4dd54f136 100644 --- a/math/prime_numbers.cpp +++ b/math/prime_numbers.cpp @@ -1,26 +1,33 @@ +/** + * @file + * @brief Get list of prime numbers + * @see primes_up_to_billion.cpp sieve_of_eratosthenes.cpp + */ #include #include +/** Generate an increasingly large number of primes + * and store in a list + */ std::vector primes(int max) { max++; std::vector res; std::vector numbers(max, false); for (int i = 2; i < max; i++) { if (!numbers[i]) { - for (int j = i; j < max; j += i) - numbers[j] = true; + for (int j = i; j < max; j += i) numbers[j] = true; res.push_back(i); } } return res; } +/** main function */ int main() { std::cout << "Calculate primes up to:\n>> "; int n; std::cin >> n; std::vector ans = primes(n); - for (int i = 0; i < ans.size(); i++) - std::cout << ans[i] << ' '; + for (int i = 0; i < ans.size(); i++) std::cout << ans[i] << ' '; std::cout << std::endl; } diff --git a/math/primes_up_to_billion.cpp b/math/primes_up_to_billion.cpp index d8f5a9f9d..4fb79a15e 100644 --- a/math/primes_up_to_billion.cpp +++ b/math/primes_up_to_billion.cpp @@ -1,8 +1,15 @@ +/** + * @file + * @brief Compute prime numbers upto 1 billion + * @see prime_numbers.cpp sieve_of_eratosthenes.cpp + */ #include #include +/** array to store the primes */ char prime[100000000]; +/** Perform Sieve algorithm */ void Sieve(int64_t n) { memset(prime, '1', sizeof(prime)); // intitize '1' to every index prime[0] = '0'; // 0 is not prime @@ -15,6 +22,7 @@ void Sieve(int64_t n) { } } +/** Main function */ int main() { Sieve(100000000); int64_t n; @@ -23,4 +31,6 @@ int main() { std::cout << "YES\n"; else std::cout << "NO\n"; + + return 0; } diff --git a/math/sieve_of_eratosthenes.cpp b/math/sieve_of_eratosthenes.cpp index e600e480d..d8fa70531 100644 --- a/math/sieve_of_eratosthenes.cpp +++ b/math/sieve_of_eratosthenes.cpp @@ -1,69 +1,65 @@ -/* - * Sieve of Eratosthenes is an algorithm to find the primes +/** + * @file + * @brief Get list of prime numbers using Sieve of Eratosthenes + * Sieve of Eratosthenes is an algorithm to find the primes * that is between 2 to N (as defined in main). * - * Time Complexity : O(N * log N) - * Space Complexity : O(N) + * Time Complexity : \f$O(N \cdot\log N)\f$ + *
Space Complexity : \f$O(N)\f$ + * + * @see primes_up_to_billion.cpp prime_numbers.cpp */ #include -using namespace std; +/** Maximum number of primes */ #define MAX 10000000 -int isprime[MAX]; +/** array to store the primes */ +bool isprime[MAX]; -/* - * This is the function that finds the primes and eliminates +/** + * This is the function that finds the primes and eliminates * the multiples. */ -void sieve(int N) -{ - isprime[0] = 0; - isprime[1] = 0; - for (int i = 2; i <= N; i++) - { - if (isprime[i]) - { - for (int j = i * 2; j <= N; j += i) - { - isprime[j] = 0; +void sieve(uint32_t N) { + isprime[0] = false; + isprime[1] = false; + for (uint32_t i = 2; i <= N; i++) { + if (isprime[i]) { + for (uint32_t j = (i << 1); j <= N; j += i) { + isprime[j] = false; } } } } -/* +/** * This function prints out the primes to STDOUT */ -void print(int N) -{ - for (int i = 1; i <= N; i++) - { - if (isprime[i] == 1) - { - cout << i << ' '; +void print(uint32_t N) { + for (uint32_t i = 1; i <= N; i++) { + if (isprime[i]) { + std::cout << i << ' '; } } - cout << '\n'; + std::cout << std::endl; } -/* - * NOTE: This function is important for the - * initialization of the array. +/** + * Initialize the array */ -void init() -{ - for (int i = 1; i < MAX; i++) - { - isprime[i] = 1; +void init() { + for (uint32_t i = 1; i < MAX; i++) { + isprime[i] = true; } } -int main() -{ - int N = 100; +/** main function */ +int main() { + uint32_t N = 100; init(); sieve(N); print(N); + return 0; } diff --git a/math/sqrt_double.cpp b/math/sqrt_double.cpp index 5a0fd1c88..1521b500a 100644 --- a/math/sqrt_double.cpp +++ b/math/sqrt_double.cpp @@ -1,27 +1,35 @@ -#include +/** + * @file + * @brief Calculate the square root of any positive number in \f$O(\log N)\f$ + * time, with precision fixed using [bisection + * method](https://en.wikipedia.org/wiki/Bisection_method) of root-finding. + * + * @see Can be implemented using faster and better algorithms like + * newton_raphson_method.cpp and false_position.cpp + */ #include +#include -/* Calculate the square root of any -number in O(logn) time, -with precision fixed */ - -double Sqrt(double x) { - if ( x > 0 && x < 1 ) { - return 1/Sqrt(1/x); +/** Bisection method implemented for the function \f$x^2-a=0\f$ + * whose roots are \f$\pm\sqrt{a}\f$ and only the positive root is returned. + */ +double Sqrt(double a) { + if (a > 0 && a < 1) { + return 1 / Sqrt(1 / a); } - double l = 0, r = x; - /* Epsilon is the precision. - A great precision is + double l = 0, r = a; + /* Epsilon is the precision. + A great precision is between 1e-7 and 1e-12. double epsilon = 1e-12; */ double epsilon = 1e-12; - while ( l <= r ) { + while (l <= r) { double mid = (l + r) / 2; - if ( mid * mid > x ) { + if (mid * mid > a) { r = mid; } else { - if ( x - mid * mid < epsilon ) { + if (a - mid * mid < epsilon) { return mid; } l = mid; @@ -29,11 +37,13 @@ double Sqrt(double x) { } return -1; } + +/** main function */ int main() { - double n{}; - std::cin >> n; - assert(n >= 0); - // Change this line for a better precision - std::cout.precision(12); - std::cout << std::fixed << Sqrt(n); + double n{}; + std::cin >> n; + assert(n >= 0); + // Change this line for a better precision + std::cout.precision(12); + std::cout << std::fixed << Sqrt(n); }