From 334eb3df591cabf3d860bd0467b7bdd70ce157f9 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 09:13:21 -0400 Subject: [PATCH 01/20] documetnation for binary_exponent.cpp --- math/binary_exponent.cpp | 59 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 24 deletions(-) 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 From 4134c16f429be72eece8b1d176ed0790738d31b1 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 09:21:54 -0400 Subject: [PATCH 02/20] documentation for double_factorial --- math/double_factorial.cpp | 41 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 7b0d1d970..2b28a5d5a 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -1,28 +1,33 @@ -#include +/** + * @file + * 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 `!!` + */ + #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 >= 0; i -= 2) { + if (i == 0 || i == 1) return res; + res *= i; + } } -/* 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); } From 44f68e9a2e50275fce0d6a3e23ed5f15585c1ff5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 12:54:42 -0400 Subject: [PATCH 03/20] bug fix - no function return and invalid for loop termination check --- math/double_factorial.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 2b28a5d5a..73a3d344a 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -11,10 +11,11 @@ /// 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) { + for (uint64_t i = n;; i -= 2) { if (i == 0 || i == 1) return res; res *= i; } + return res; } /// Compute double factorial using resursive method. From 50070774dd7cbf80e76bbf32f5f45c2cb3d8f24b Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 12:55:03 -0400 Subject: [PATCH 04/20] fix documentation for double_factorial --- math/double_factorial.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 73a3d344a..26b90f356 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -2,7 +2,8 @@ * @file * 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 `!!` + *
It is also called as semifactorial of a number and is denoted by + * \f$n!!\f$ */ #include @@ -27,7 +28,7 @@ uint64_t double_factorial_recursive(uint64_t n) { /// main function int main() { - uint64_t n{}; + uint64_t n; std::cin >> n; assert(n >= 0); std::cout << double_factorial_iterative(n); From d723604e0162c5f828d9f3137f1ff9c7f26e97ed Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 14:07:05 -0400 Subject: [PATCH 05/20] documentation update for double_factorial --- math/double_factorial.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 26b90f356..37bd2052a 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -1,5 +1,7 @@ /** * @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 @@ -9,7 +11,8 @@ #include #include -/// Compute double factorial using iterative method +/** Compute double factorial using iterative method + */ uint64_t double_factorial_iterative(uint64_t n) { uint64_t res = 1; for (uint64_t i = n;; i -= 2) { @@ -19,8 +22,9 @@ uint64_t double_factorial_iterative(uint64_t n) { return res; } -/// Compute double factorial using resursive method. -//
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); From 4944d4c8b1dc00231209d24f26374dfc96d2c429 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 14:07:18 -0400 Subject: [PATCH 06/20] documentation for eulers_totient_function.cpp --- math/eulers_totient_function.cpp | 62 ++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 23 deletions(-) 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; } From 691cbdb1f514f5bbd295b97c5d8123f63a9e62fe Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:06:36 -0400 Subject: [PATCH 07/20] fix code for generic types --- math/extended_euclid_algorithm.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/math/extended_euclid_algorithm.cpp b/math/extended_euclid_algorithm.cpp index 3db14802f..829db4336 100644 --- a/math/extended_euclid_algorithm.cpp +++ b/math/extended_euclid_algorithm.cpp @@ -4,25 +4,27 @@ // 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. +template +void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) { + if (B > A) std::swap(A, B); // Ensure that A >= B -int d, x, y; -void extendedEuclid(int A, int 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); } } 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; return 0; } From 757970dbaec023fd9cdcbab40fb64f66cae21bb5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:06:46 -0400 Subject: [PATCH 08/20] documentation for extended euclid --- math/extended_euclid_algorithm.cpp | 74 ++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/math/extended_euclid_algorithm.cpp b/math/extended_euclid_algorithm.cpp index 829db4336..84dec55c5 100644 --- a/math/extended_euclid_algorithm.cpp +++ b/math/extended_euclid_algorithm.cpp @@ -1,9 +1,70 @@ +/** + * @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. + +/** + * function to update the coefficients per iteration + * \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f] + * + * @param[in,out] r signed + * @param[in,out] r0 signed + * @param[in] quotient unsigned input + */ +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 @@ -20,11 +81,14 @@ void extendedEuclid(T A, T B, T *GCD, T2 *x, T2 *y) { } } +/// Main function int main() { uint32_t a, b, gcd; int32_t x, y; std::cin >> a >> b; 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; } From d26206549248998e1dc1de57a271d3c931c44019 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:14:30 -0400 Subject: [PATCH 09/20] use template based functions --- math/fast_power.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/math/fast_power.cpp b/math/fast_power.cpp index 0ffbcd40d..f69a90e4c 100644 --- a/math/fast_power.cpp +++ b/math/fast_power.cpp @@ -21,16 +21,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 @@ -42,7 +43,8 @@ double fast_power_recursive(int64_t a, int64_t b) { Same algorithm with little different formula. It still calculates in O(logN) */ -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); From a436cd7a1b3050af91f8aa4fdb6e5ec24b1d181d Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:14:39 -0400 Subject: [PATCH 10/20] improve documentation for fast_power --- math/fast_power.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/math/fast_power.cpp b/math/fast_power.cpp index f69a90e4c..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 @@ -41,7 +42,7 @@ double fast_power_recursive(T a, T b) { /** Same algorithm with little different formula. - It still calculates in O(logN) + It still calculates in \f$O(\log N)\f$ */ template double fast_power_linear(T a, T b) { @@ -57,6 +58,9 @@ double fast_power_linear(T a, T b) { return result; } +/** + * Main function + */ int main() { std::srand(std::time(nullptr)); std::ios_base::sync_with_stdio(false); From e31ee6e83332e9c6e508e8bd88f216ce6042d40f Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:42:12 -0400 Subject: [PATCH 11/20] better document GCD programs --- ...lidean.cpp => gcd_iterative_euclidean.cpp} | 18 +++++-- math/gcd_recursive_euclidean.cpp | 48 +++++++++++++++++++ math/greatest_common_divisor.cpp | 27 ----------- 3 files changed, 62 insertions(+), 31 deletions(-) rename math/{greatest_common_divisor_euclidean.cpp => gcd_iterative_euclidean.cpp} (80%) create mode 100644 math/gcd_recursive_euclidean.cpp delete mode 100644 math/greatest_common_divisor.cpp 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; -} From 49fe1b11ef124c240b5552b57d1b2ddbefcea5a5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 15:42:23 -0400 Subject: [PATCH 12/20] document fibonacci program --- math/fibonacci.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) 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; From 4d272210fc8bd9c26f68abb4124edd5c3d509419 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 27 May 2020 19:42:57 +0000 Subject: [PATCH 13/20] updating DIRECTORY.md --- DIRECTORY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index ba455f2c1..2b73144b8 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) From 6173a6a7017553805c7e3cb05af42cae6147af58 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:09:50 -0400 Subject: [PATCH 14/20] documentation for Little Fermat's Thm --- .../modular_inverse_fermat_little_theorem.cpp | 81 ++++++++++++------- 1 file changed, 50 insertions(+), 31 deletions(-) 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; From f432c0f5840d1151e4b4491abc55303e8dc8d4d9 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:22:10 -0400 Subject: [PATCH 15/20] documetnation for positive divisors --- math/number_of_positive_divisors.cpp | 46 ++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) 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; From 9154d5a25dde12744898c5d5cd19ab9c1b3f0268 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:22:22 -0400 Subject: [PATCH 16/20] docs for large number power --- math/power_for_huge_numbers.cpp | 147 ++++++++++++++++---------------- 1 file changed, 73 insertions(+), 74 deletions(-) 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; } From 093b993cc717aabdabc3886dca65bc7ba8b47348 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:44:58 -0400 Subject: [PATCH 17/20] fix cpplint --- math/extended_euclid_algorithm.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/math/extended_euclid_algorithm.cpp b/math/extended_euclid_algorithm.cpp index 84dec55c5..3fdae25b5 100644 --- a/math/extended_euclid_algorithm.cpp +++ b/math/extended_euclid_algorithm.cpp @@ -16,15 +16,15 @@ * function to update the coefficients per iteration * \f[r_0,\,r = r,\, r_0 - \text{quotient}\times r\f] * - * @param[in,out] r signed - * @param[in,out] r0 signed - * @param[in] quotient unsigned input + * @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; +inline void update_step(T *r, T *r0, const T2 quotient) { + T temp = *r; + *r = *r0 - (quotient * temp); + *r0 = temp; } /** @@ -47,9 +47,9 @@ void extendedEuclid_1(T1 A, T1 B, T1 *GCD, T2 *x, T2 *y) { while (r != 0) { T1 quotient = r0 / r; - update_step(r, r0, quotient); - update_step(s, s0, quotient); - update_step(t, t0, quotient); + update_step(&r, &r0, quotient); + update_step(&s, &s0, quotient); + update_step(&t, &t0, quotient); } *GCD = r0; *x = s0; From ea3f8bbf29381b0a999891d6590c934cd2cdbacc Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:45:33 -0400 Subject: [PATCH 18/20] documentation and bug fixes --- math/prime_factorization.cpp | 22 ++++++---- math/prime_numbers.cpp | 15 +++++-- math/primes_up_to_billion.cpp | 10 +++++ math/sieve_of_eratosthenes.cpp | 74 ++++++++++++++++------------------ 4 files changed, 71 insertions(+), 50 deletions(-) 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; } From 6cd589a75287298317b04ed2e221bd63f0a7c593 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:47:32 -0400 Subject: [PATCH 19/20] math readme title --- math/README.md | 1 + 1 file changed, 1 insertion(+) 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. From 27cea79fa3538ab18c36d3aa64c28624041b1357 Mon Sep 17 00:00:00 2001 From: Krishna Vedala Date: Wed, 27 May 2020 16:58:30 -0400 Subject: [PATCH 20/20] document square-root that uses bisection method --- math/sqrt_double.cpp | 50 ++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 20 deletions(-) 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); }