From de4578c1a47d9c03eb96aa863ed109bec80933f5 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Mon, 15 Jun 2020 22:11:20 +0530 Subject: [PATCH 001/261] feat: add sum of digits --- math/sum_of_digits.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 math/sum_of_digits.cpp diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp new file mode 100644 index 000000000..d3e7d3291 --- /dev/null +++ b/math/sum_of_digits.cpp @@ -0,0 +1,28 @@ +/** + * A simple C++ Program to find the Sum of Digits of input integer. + */ +#include + +/** + * Function to find the sum of the digits of an integer. + * @param num The integer. + * @return Sum of the digits of the integer. + */ +int sum_of_digits(int num) { + int sum = 0; + while (num > 0) { + sum = sum + (num % 10); + num = num / 10; + } + return sum; +} + +int main() { + int num; + std::cin >> num; + if (num < 0) { + num = -1 * num; + } + std::cout << sum_of_digits(num); + return 0; +} \ No newline at end of file From d86a9b56df77b0b6544c2d40fb1482c41a779dc3 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Mon, 15 Jun 2020 23:17:50 +0530 Subject: [PATCH 002/261] fix: sum of digits bug --- math/sum_of_digits.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index d3e7d3291..b259e48da 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -1,7 +1,11 @@ /** - * A simple C++ Program to find the Sum of Digits of input integer. + * Copyright 2020 @author iamnambiar + * + * @file + * A C++ Program to find the Sum of Digits of input integer. */ #include +#include /** * Function to find the sum of the digits of an integer. @@ -9,6 +13,9 @@ * @return Sum of the digits of the integer. */ int sum_of_digits(int num) { + if (num < 0) { + num = -1 * num; + } int sum = 0; while (num > 0) { sum = sum + (num % 10); @@ -17,12 +24,18 @@ int sum_of_digits(int num) { return sum; } -int main() { - int num; - std::cin >> num; - if (num < 0) { - num = -1 * num; +/** + * Test function. + */ +void test() { + int test_case_1 = sum_of_digits(119765); + int test_case_2 = sum_of_digits(-12256); + assert(test_case_1 == 29); + assert(test_case_2 == 16); } - std::cout << sum_of_digits(num); + +int main() { + test(); + std::cout << "Success."; return 0; -} \ No newline at end of file +} From 2191ef4881f6b3a94b9f26189b320fb27ef06692 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Mon, 15 Jun 2020 23:26:58 +0530 Subject: [PATCH 003/261] fix: whitespace issue in sum_of_digits --- math/sum_of_digits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index b259e48da..cf8c28360 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -27,7 +27,7 @@ int sum_of_digits(int num) { /** * Test function. */ -void test() { +void test() { int test_case_1 = sum_of_digits(119765); int test_case_2 = sum_of_digits(-12256); assert(test_case_1 == 29); From 12f0ec3c45fc2789be69a8a579b0eee92e356412 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Tue, 16 Jun 2020 08:03:14 +0530 Subject: [PATCH 004/261] test: add two test functions --- math/sum_of_digits.cpp | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index cf8c28360..460bff691 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -11,8 +11,17 @@ * Function to find the sum of the digits of an integer. * @param num The integer. * @return Sum of the digits of the integer. + * + * \detail + * First the algorithm check whether the num is negative or positive, + * if it is negative, then we neglect the negative sign. + * Next, the algorithm extract the last digit of num by dividing by 10 + * and extracting the remainder and this is added to the sum. + * The number is then divided by 10 to remove the last digit. + * This loop continues until num becomes 0. */ int sum_of_digits(int num) { + // If num is negative then negative sign is neglected. if (num < 0) { num = -1 * num; } @@ -25,17 +34,38 @@ int sum_of_digits(int num) { } /** - * Test function. + * Function for testing the sum_of_digits() function with a + * first test case of 119765 and assert statement. */ -void test() { +void test1() { int test_case_1 = sum_of_digits(119765); - int test_case_2 = sum_of_digits(-12256); assert(test_case_1 == 29); - assert(test_case_2 == 16); } +/** + * Function for testing the sum_of_digits() function with a + * second test case of -12256 and assert statement. + */ +void test2() { + int test_case_2 = sum_of_digits(-12256); + assert(test_case_2 == 16); + } +/** + * Function for testing the sum_of_digits() with + * all the test cases. + */ +void test() { + //First test. + test1(); + //Second test. + test2(); + } + +/** + * Main Function +*/ int main() { test(); - std::cout << "Success."; + std::cout << "Success." << std::endl; return 0; } From 05aa382a168b817145e6a956096fe88dac147e95 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Tue, 16 Jun 2020 08:05:06 +0530 Subject: [PATCH 005/261] docs: comment space fix --- math/sum_of_digits.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index 460bff691..42f0b5e82 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -55,9 +55,9 @@ void test2() { * all the test cases. */ void test() { - //First test. + // First test. test1(); - //Second test. + // Second test. test2(); } From d9e3053fade7b68a9fd61b72b5a2b0db72cd98a3 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Thu, 18 Jun 2020 11:04:27 +0530 Subject: [PATCH 006/261] fix: formatting code style. --- math/sum_of_digits.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index 42f0b5e82..bcb6d7956 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -40,7 +40,7 @@ int sum_of_digits(int num) { void test1() { int test_case_1 = sum_of_digits(119765); assert(test_case_1 == 29); - } +} /** * Function for testing the sum_of_digits() function with a @@ -49,7 +49,8 @@ void test1() { void test2() { int test_case_2 = sum_of_digits(-12256); assert(test_case_2 == 16); - } +} + /** * Function for testing the sum_of_digits() with * all the test cases. @@ -59,7 +60,7 @@ void test() { test1(); // Second test. test2(); - } +} /** * Main Function From 405c4ee2549d8425e413c1b86e6efb3e0515da26 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:10:57 -0400 Subject: [PATCH 007/261] update image and details section of documentation --- machine_learning/adaline_learning.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/machine_learning/adaline_learning.cpp b/machine_learning/adaline_learning.cpp index 1e25d3ba1..a8426ac4e 100644 --- a/machine_learning/adaline_learning.cpp +++ b/machine_learning/adaline_learning.cpp @@ -7,10 +7,12 @@ * * \author [Krishna Vedala](https://github.com/kvedala) * - * - * [source](https://commons.wikimedia.org/wiki/File:Adaline_flow_chart.gif) + * alt="Structure of an ADALINE network. Source: Wikipedia" + * style="width:200px; float:right;"> + * * ADALINE is one of the first and simplest single layer artificial neural * network. The algorithm essentially implements a linear function * \f[ f\left(x_0,x_1,x_2,\ldots\right) = From ba2f1ed12d85d03f5d47ec4f75be99648ad1f9e3 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:12:35 -0400 Subject: [PATCH 008/261] update documentation --- machine_learning/kohonen_som_topology.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/machine_learning/kohonen_som_topology.cpp b/machine_learning/kohonen_som_topology.cpp index 25c58e260..016fe6d1e 100644 --- a/machine_learning/kohonen_som_topology.cpp +++ b/machine_learning/kohonen_som_topology.cpp @@ -3,9 +3,11 @@ * @{ * \file * \author [Krishna Vedala](https://github.com/kvedala) + * * \brief [Kohonen self organizing * map](https://en.wikipedia.org/wiki/Self-organizing_map) (topological map) * + * \details * This example implements a powerful unsupervised learning algorithm called as * a self organizing map. The algorithm creates a connected network of weights * that closely follows the given data points. This thus creates a topological @@ -21,7 +23,7 @@ * than with GCC on windows * \see kohonen_som_trace.cpp */ -#define _USE_MATH_DEFINES // required for MS Visual C++ +#define _USE_MATH_DEFINES //< required for MS Visual C++ #include #include #include From 2ad1b72f6c4ea0b63e01e3fa83924095789b43dd Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:17:16 -0400 Subject: [PATCH 009/261] make epsilon equal system epsilon --- numerical_methods/newton_raphson_method.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/newton_raphson_method.cpp b/numerical_methods/newton_raphson_method.cpp index d086123ca..45560e323 100644 --- a/numerical_methods/newton_raphson_method.cpp +++ b/numerical_methods/newton_raphson_method.cpp @@ -18,7 +18,7 @@ #include #define EPSILON \ - 1e-6 // std::numeric_limits::epsilon() ///< system accuracy limit + std::numeric_limits::epsilon() ///< system accuracy limit #define MAX_ITERATIONS 50000 ///< Maximum number of iterations to check /** define \f$f(x)\f$ to find root for From 5111c2cf599ab3fbd89b97cd190f34814a03f60f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:19:20 -0400 Subject: [PATCH 010/261] set author after program details --- numerical_methods/ordinary_least_squares_regressor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index 43979d0ea..bbd75a742 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -3,10 +3,11 @@ * \brief Linear regression example using [Ordinary least * squares](https://en.wikipedia.org/wiki/Ordinary_least_squares) * - * \author [Krishna Vedala](https://github.com/kvedala) * Program that gets the number of data samples and number of features per * sample along with output per sample. It applies OLS regression to compute * the regression output for additional test data samples. + * + * \author [Krishna Vedala](https://github.com/kvedala) */ #include // for print formatting #include From 00fab77412da2ad4304faa8227e7ccce8ee8139d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 19 Jun 2020 18:26:15 -0400 Subject: [PATCH 011/261] set epsilon to 1e-10 and update documentation --- numerical_methods/newton_raphson_method.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/numerical_methods/newton_raphson_method.cpp b/numerical_methods/newton_raphson_method.cpp index 45560e323..7597f1b8a 100644 --- a/numerical_methods/newton_raphson_method.cpp +++ b/numerical_methods/newton_raphson_method.cpp @@ -17,17 +17,24 @@ #include #include -#define EPSILON \ - std::numeric_limits::epsilon() ///< system accuracy limit -#define MAX_ITERATIONS 50000 ///< Maximum number of iterations to check +#define EPSILON 1e-10 ///< system accuracy limit +#define MAX_ITERATIONS INT16_MAX ///< Maximum number of iterations to check -/** define \f$f(x)\f$ to find root for +/** define \f$f(x)\f$ to find root for. + * Currently defined as: + * \f[ + * f(x) = x^3 - 4x - 9 + * \f] */ static double eq(double i) { return (std::pow(i, 3) - (4 * i) - 9); // original equation } /** define the derivative function \f$f'(x)\f$ + * For the current problem, it is: + * \f[ + * f'(x) = 3x^2 - 4 + * \f] */ static double eq_der(double i) { return ((3 * std::pow(i, 2)) - 4); // derivative of equation From f7a8b7a85f3b227e8ebb7f865e211be9b3a0a61c Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Sat, 20 Jun 2020 21:09:43 +0530 Subject: [PATCH 012/261] Update math/sum_of_digits.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/sum_of_digits.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index bcb6d7956..d5a705c48 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -2,7 +2,7 @@ * Copyright 2020 @author iamnambiar * * @file - * A C++ Program to find the Sum of Digits of input integer. + * \brief A C++ Program to find the Sum of Digits of input integer. */ #include #include From 4eee4ee7dabfca9835618f471a0e8671a2237b51 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 20 Jun 2020 22:16:37 -0400 Subject: [PATCH 013/261] enable AlignConsecutiveMacros --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6d75a1390..245be1a04 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "C_Cpp.clang_format_style": "{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3 }", + "C_Cpp.clang_format_style": "{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }", "editor.formatOnSave": true, "editor.formatOnType": true, "editor.formatOnPaste": true From b5e25f44cfcc251f3e47c24bdebb455f2fd601bd Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 00:09:09 -0400 Subject: [PATCH 014/261] added minima algorithm using golden section search --- numerical_methods/golden_search_extrema.cpp | 128 ++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 numerical_methods/golden_search_extrema.cpp diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp new file mode 100644 index 000000000..2d4611561 --- /dev/null +++ b/numerical_methods/golden_search_extrema.cpp @@ -0,0 +1,128 @@ +/** + * \file + * \brief Find extrema of a univariate real function in a given interval using + * [golden section search + * algorithm](https://en.wikipedia.org/wiki/Golden-section_search). + * + * \author [Krishna Vedala](https://github.com/kvedala) + */ +#define _USE_MATH_DEFINES //< required for MS Visual C++ +#include +#include +#include +#include +#include +#include + +#define EPSILON 1e-7 ///< solution accuracy limit +#define M_GOLDEN_RATIO \ + static_cast(1.618033988749894848204586834) ///< golden ratio value + +/** + * @brief Get the minima of a function in the given interval. To get the maxima, + * simply negate the function. + * + * @param f function to get minima for + * @param lim_a lower limit of search window + * @param lim_b upper limit of search window + * @return local minima found in the interval + */ +double get_minima(const std::function &f, double lim_a, + double lim_b) { + double c, d; + double prev_mean, mean = std::numeric_limits::infinity(); + + do { + prev_mean = mean; + + c = lim_b - (lim_b - lim_a) / M_GOLDEN_RATIO; + d = lim_a + (lim_b - lim_a) / M_GOLDEN_RATIO; + + if (f(c) < f(d)) { + lim_b = d; + } else { + lim_a = c; + } + + mean = (lim_a + lim_b) * 0.5f; + } while (std::abs(mean - prev_mean) > EPSILON); + + return mean; +} + +/** + * @brief Test function to find minima for the function + * \f$f(x)= (x-2)^2\f$ + * in the interval \f$[1,5]\f$ + * \n Expected result = 2 + */ +void test1() { + // define the function to minimize as a lambda function + std::function f1 = [](double x) { + return (x - 2) * (x - 2); + }; + + std::cout << "Test 1.... "; + + double minima = get_minima(f1, 1, 5); + + std::cout << minima << "..."; + + assert(std::abs(minima - 2) < EPSILON); + std::cout << "passed\n"; +} + +/** + * @brief Test function to find *maxima* for the function + * \f$f(x)= x^{\frac{1}{x}}\f$ + * in the interval \f$[-2,10]\f$ + * \n Expected result: \f$e\approx 2.71828182845904509\f$ + */ +void test2() { + // define the function to maximize as a lambda function + // since we are maximixing, we negated the function return value + std::function func = [](double x) { + return -std::pow(x, 1.f / x); + }; + + std::cout << "Test 2.... "; + + double minima = get_minima(func, -2, 10); + + std::cout << minima << " (" << M_E << ")..."; + + assert(std::abs(minima - M_E) < EPSILON); + std::cout << "passed\n"; +} + +/** + * @brief Test function to find *maxima* for the function + * \f$f(x)= \cos x\f$ + * in the interval \f$[0,12]\f$ + * \n Expected result: \f$\pi\approx 3.14159265358979312\f$ + */ +void test3() { + // define the function to maximize as a lambda function + // since we are maximixing, we negated the function return value + std::function func = [](double x) { return std::cos(x); }; + + std::cout << "Test 3.... "; + + double minima = get_minima(func, 0, 12); + + std::cout << minima << " (" << M_PI << ")..."; + + assert(std::abs(minima - M_PI) < EPSILON); + std::cout << "passed\n"; +} + +/** Main function */ +int main() { + std::cout.precision(18); + + test1(); + test2(); + test3(); + + return 0; +} From 33b8169f41b429b70f97fef40a484ed6e4dbda26 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 21 Jun 2020 04:10:37 +0000 Subject: [PATCH 015/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 071ee8b95..1ba34af53 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -132,6 +132,7 @@ * [Durand Kerner Roots](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/durand_kerner_roots.cpp) * [False Position](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/false_position.cpp) * [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/gaussian_elimination.cpp) + * [Golden Search Extrema](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/golden_search_extrema.cpp) * [Lu Decompose](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/lu_decompose.cpp) * [Newton Raphson Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/newton_raphson_method.cpp) * [Ode Forward Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_forward_euler.cpp) From bf2b70313181cc31ce42a2807078df2770e8357f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 00:18:34 -0400 Subject: [PATCH 016/261] remove redundant header includes --- numerical_methods/golden_search_extrema.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 2d4611561..538c53961 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -9,10 +9,8 @@ #define _USE_MATH_DEFINES //< required for MS Visual C++ #include #include -#include #include #include -#include #define EPSILON 1e-7 ///< solution accuracy limit #define M_GOLDEN_RATIO \ From d8e76eda6f3d4091c0b61579a10bce895d7c16a8 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 00:21:54 -0400 Subject: [PATCH 017/261] added limits header file --- numerical_methods/golden_search_extrema.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 538c53961..5a327c1ef 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #define EPSILON 1e-7 ///< solution accuracy limit #define M_GOLDEN_RATIO \ From de70c5d864e0ccae223b0a7f96ebfe548049e37e Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 21:28:00 +0530 Subject: [PATCH 018/261] [Bug Fix] of sorting/heapsort.cpp (#873) * formatting source-code for 72c365dcd34d9776fac3e2b58b41891b3619b02e * Fixed Bug [munmap_chunck() core dumped] * formatting source-code for b06bbf4dc6c46a3284d7852bb570438384eef4ef * fixed line spacing * fixed line spacing * fixed documentation * closed the paranthesis of line 3 * formatting source-code for 8233eda8894f46785f288e72c639d201852f6096 * Bug Fix heap sort [Fresh Implementation] * formatting source-code for e464ddac3688834ce46c59bada5ad3fddbfa2254 * Bug Fix heap sort [Fresh Implementation] * formatting source-code for 803981c831b36bf940d3fa2a901340cb0029717b * switched to normal functions from lambda * formatting source-code for ced5dcd6c4db53ece27d22ecd1dd1c1fcce6afb0 * Added template and test cases * formatting source-code for 7c8617fa46d41481c68ae2ae9d4f6a89ca42a4ff * fixed docs * fixed line spacing in tests * fix docs Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- sorting/heap_sort.cpp | 137 ++++++++++++++++++++++++++++++++---------- 1 file changed, 104 insertions(+), 33 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 9948bb821..ef9f87094 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -1,52 +1,123 @@ +/** + * \file + * \brief [Heap Sort Algorithm + * (heap sort)](https://en.wikipedia.org/wiki/Heapsort) implementation + * + * \author [Ayaan Khan](http://github.com/ayaankhan98) + * + * \details + * Heap-sort is a comparison-based sorting algorithm. + * Heap-sort can be thought of as an improved selection sort: + * like selection sort, heap sort divides its input into a sorted + * and an unsorted region, and it iteratively shrinks the unsorted + * region by extracting the largest element from it and inserting + * it into the sorted region. Unlike selection sort, + * heap sort does not waste time with a linear-time scan of the + * unsorted region; rather, heap sort maintains the unsorted region + * in a heap data structure to more quickly find the largest element + * in each step. + * + * Time Complexity - \f$O(n \log(n))\f$ + * + */ #include +#include #include -void heapify(int *a, int i, int n) { - int largest = i; - const int l = 2 * i + 1; - const int r = 2 * i + 2; +/** + * + * Utility Lambda function to print the array after + * sorting. + * + * @param arr array to be printed + * @param sz size of array + * + */ +template +void printArray(T *arr, int sz) { + for (int i = 0; i < sz; i++) std::cout << arr[i] << " "; + std::cout << "\n"; +} - if (l < n && a[l] > a[largest]) +/** + * + * \addtogroup sorting Sorting Algorithm + * @{ + * + * The heapify procedure can be thought of as building a heap from + * the bottom up by successively sifting downward to establish the + * heap property. + * + * @param arr array to be sorted + * @param n size of array + * @param i node position in Binary Tress or element position in + * Array to be compared with it's childern + * + */ +template +void heapify(T *arr, int n, int i) { + int largest = i; + int l = 2 * i + 1; + int r = 2 * i + 2; + + if (l < n && arr[l] > arr[largest]) largest = l; - if (r < n && a[r] > a[largest]) + if (r < n && arr[r] > arr[largest]) largest = r; if (largest != i) { - std::swap(a[i], a[largest]); - heapify(a, n, largest); + std::swap(arr[i], arr[largest]); + heapify(arr, n, largest); } } -void heapsort(int *a, int n) { - for (int i = n - 1; i >= 0; --i) { - std::swap(a[0], a[i]); - heapify(a, 0, i); +/** + * Utilizes heapify procedure to sort + * the array + * + * @param arr array to be sorted + * @param n size of array + * + */ +template +void heapSort(T *arr, int n) { + for (int i = n - 1; i >= 0; i--) heapify(arr, n, i); + + for (int i = n - 1; i >= 0; i--) { + std::swap(arr[0], arr[i]); + heapify(arr, i, 0); } } -void build_maxheap(int *a, int n) { - for (int i = n / 2 - 1; i >= 0; --i) { - heapify(a, i, n); - } +/** + * + * @} + * Test cases to test the program + * + */ +void test() { + std::cout << "Test 1\n"; + int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; + int sz = sizeof(arr) / sizeof(arr[0]); // sz - size of array + printArray(arr, sz); // displaying the array before sorting + heapSort(arr, sz); // calling heapsort to sort the array + printArray(arr, sz); // display array after sorting + assert(std::is_sorted(arr, arr + sz)); + std::cout << "Test 1 Passed\n========================\n"; + + std::cout << "Test 2\n"; + double arr2[] = {4.5, -3.6, 7.6, 0, 12.9}; + sz = sizeof(arr2) / sizeof(arr2[0]); + printArray(arr2, sz); + heapSort(arr2, sz); + printArray(arr2, sz); + assert(std::is_sorted(arr2, arr2 + sz)); + std::cout << "Test 2 passed\n"; } +/** Main function */ int main() { - int n; - std::cout << "Enter number of elements of array\n"; - std::cin >> n; - int a[20]; - for (int i = 0; i < n; ++i) { - std::cout << "Enter Element " << i << std::endl; - std::cin >> a[i]; - } - - build_maxheap(a, n); - heapsort(a, n); - std::cout << "Sorted Output\n"; - for (int i = 0; i < n; ++i) { - std::cout << a[i] << std::endl; - } - - std::getchar(); + test(); + return 0; } From a48d05fb6223cedde57fa487fb79ee51651d5985 Mon Sep 17 00:00:00 2001 From: Taj Date: Sun, 21 Jun 2020 18:40:57 +0100 Subject: [PATCH 019/261] feat: Added a probabilistic Miller-Rabin Primality Test (#845) * feat: Added a probabilitic Miller-Rabin Primality test * docs: Documentation Changes * fix: Issue with the assert call * docs: grammatical error * docs: corrected the copyright comment * docs: Fixed some documentation issues. * docs: fix latex issues * docs and fix: Fixed documentation issues and vector by const reference and iterator over const reference. * docs: fixed latex documentation issue. * docs: spelling errors * docs: spelling error fixed --- math/miller_rabin.cpp | 183 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 math/miller_rabin.cpp diff --git a/math/miller_rabin.cpp b/math/miller_rabin.cpp new file mode 100644 index 000000000..654f99820 --- /dev/null +++ b/math/miller_rabin.cpp @@ -0,0 +1,183 @@ +/** + * Copyright 2020 @author tjgurwara99 + * @file + * + * A basic implementation of Miller-Rabin primality test. + */ + +#include +#include +#include +#include + +/** + * Function to give a binary representation of a number in reverse order + * @param num integer number that we want to convert + * @return result vector of the number input in reverse binary + */ +template std::vector reverse_binary(T num) { + std::vector result; + T temp = num; + while (temp > 0) { + result.push_back(temp % 2); + temp = temp / 2; + } + return result; +} + +/** + * Function for modular exponentiation. + * This function is an efficient modular exponentiation function. + * It can be used with any big integer library such as Boost multiprecision + * to give result any modular exponentiation problem relatively quickly. + * @param base number being raised to a power as integer + * @param rev_binary_exponent reverse binary of the power the base is being + * raised to + * @param mod modulo + * @return r the modular exponentiation of \f$a^{n} \equiv r \mod{m}\f$ where + * \f$n\f$ is the base 10 representation of rev_binary_exponent and \f$m = mod \f$ + * parameter. + */ +template +T modular_exponentiation(T base, const std::vector &rev_binary_exponent, + T mod) { + if (mod == 1) + return 0; + T b = 1; + if (rev_binary_exponent.size() == 0) + return b; + T A = base; + if (rev_binary_exponent[0] == 1) + b = base; + + for (typename std::vector::const_iterator it = + rev_binary_exponent.cbegin() + 1; + it != rev_binary_exponent.cend(); ++it) { + A = A * A % mod; + if (*it == 1) + b = A * b % mod; + } + return b; +} + +/** Function for testing the conditions that are satisfied when a number is + * prime. + * @param d number such that \f$d \cdot 2^r = n - 1\f$ where \f$n = num\f$ + * parameter and \f$r \geq 1\f$ + * @param num number being tested for primality. + * @return 'false' if n is composite + * @return 'true' if n is (probably) prime. + */ +template bool miller_test(T d, T num) { + // random number seed + std::random_device rd_seed; + // random number generator + std::mt19937 gen(rd_seed()); + // Uniformly distributed range [2, num - 2] for random numbers + std::uniform_int_distribution<> distribution(2, num - 2); + // Random number generated in the range [2, num -2]. + T random = distribution(gen); + // vector for reverse binary of the power + std::vector power = reverse_binary(d); + // x = random ^ d % num + T x = modular_exponentiation(random, power, num); + // miller conditions + if (x == 1 || x == num - 1) { + return true; + } + + while (d != num - 1) { + x = (x * x) % num; + d *= 2; + if (x == 1) { + return false; + } + if (x == num - 1) { + return true; + } + } + return false; +} + +/** + * Function that test (probabilistically) whether a given number is a prime + * based on the Miller-Rabin Primality Test. + * @param num number to be tested for primality. + * @param repeats number of repetitions for the test to increase probability of + * correct result. + * @return 'false' if num is composite + * @return 'true' if num is (probably) prime + * + * \detail + * First we check whether the num input is less than 4, if so we can determine + * whether this is a prime or composite by checking for 2 and 3. + * Next we check whether this num is odd (as all primes greater than 2 are odd). + * Next we write our num in the following format \f$num = 2^r \cdot d + 1\f$. After + * finding r and d for our input num, we use for loop repeat number of times + * inside which we check the miller conditions using the function miller_test. + * If miller_test returns false then the number is composite + * After the loop finishes completely without issuing a false return call, + * we can conclude that this number is probably prime. + */ +template bool miller_rabin_primality_test(T num, T repeats) { + if (num <= 4) { + // If num == 2 or num == 3 then prime + if (num == 2 || num == 3) { + return true; + } else { + return false; + } + } + // If num is even then not prime + if (num % 2 == 0) { + return false; + } + // Finding d and r in num = 2^r * d + 1 + T d = num - 1, r = 0; + while (d % 2 == 0) { + d = d / 2; + r++; + } + + for (T i = 0; i < repeats; ++i) { + if (!miller_test(d, num)) { + return false; + } + } + return true; +} + +/** + * Functions for testing the miller_rabin_primality_test() function with some + * assert statements. + */ +void tests() { + // First test on 2 + assert(((void)"2 is prime but function says otherwise.\n", + miller_rabin_primality_test(2, 1) == true)); + std::cout << "First test passes." << std::endl; + // Second test on 5 + assert(((void)"5 should be prime but the function says otherwise.\n", + miller_rabin_primality_test(5, 3) == true)); + std::cout << "Second test passes." << std::endl; + // Third test on 23 + assert(((void)"23 should be prime but the function says otherwise.\n", + miller_rabin_primality_test(23, 3) == true)); + std::cout << "Third test passes." << std::endl; + // Fourth test on 16 + assert(((void)"16 is not a prime but the function says otherwise.\n", + miller_rabin_primality_test(16, 3) == false)); + std::cout << "Fourth test passes." << std::endl; + // Fifth test on 27 + assert(((void)"27 is not a prime but the function says otherwise.\n", + miller_rabin_primality_test(27, 3) == false)); + std::cout << "Fifth test passes." << std::endl; +} + +/** + * Main function + */ +int main() { + tests(); + return 0; +} From bbe1ff12860dc0beb5cc0c4d732c77b61962cdbf Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 21 Jun 2020 17:42:09 +0000 Subject: [PATCH 020/261] formatting source-code for a48d05fb6223cedde57fa487fb79ee51651d5985 --- math/miller_rabin.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/math/miller_rabin.cpp b/math/miller_rabin.cpp index 654f99820..ec24ddb3e 100644 --- a/math/miller_rabin.cpp +++ b/math/miller_rabin.cpp @@ -15,7 +15,8 @@ * @param num integer number that we want to convert * @return result vector of the number input in reverse binary */ -template std::vector reverse_binary(T num) { +template +std::vector reverse_binary(T num) { std::vector result; T temp = num; while (temp > 0) { @@ -35,8 +36,8 @@ template std::vector reverse_binary(T num) { * raised to * @param mod modulo * @return r the modular exponentiation of \f$a^{n} \equiv r \mod{m}\f$ where - * \f$n\f$ is the base 10 representation of rev_binary_exponent and \f$m = mod \f$ - * parameter. + * \f$n\f$ is the base 10 representation of rev_binary_exponent and \f$m = mod + * \f$ parameter. */ template T modular_exponentiation(T base, const std::vector &rev_binary_exponent, @@ -68,7 +69,8 @@ T modular_exponentiation(T base, const std::vector &rev_binary_exponent, * @return 'false' if n is composite * @return 'true' if n is (probably) prime. */ -template bool miller_test(T d, T num) { +template +bool miller_test(T d, T num) { // random number seed std::random_device rd_seed; // random number generator @@ -112,14 +114,15 @@ template bool miller_test(T d, T num) { * First we check whether the num input is less than 4, if so we can determine * whether this is a prime or composite by checking for 2 and 3. * Next we check whether this num is odd (as all primes greater than 2 are odd). - * Next we write our num in the following format \f$num = 2^r \cdot d + 1\f$. After - * finding r and d for our input num, we use for loop repeat number of times - * inside which we check the miller conditions using the function miller_test. - * If miller_test returns false then the number is composite - * After the loop finishes completely without issuing a false return call, - * we can conclude that this number is probably prime. + * Next we write our num in the following format \f$num = 2^r \cdot d + 1\f$. + * After finding r and d for our input num, we use for loop repeat number of + * times inside which we check the miller conditions using the function + * miller_test. If miller_test returns false then the number is composite After + * the loop finishes completely without issuing a false return call, we can + * conclude that this number is probably prime. */ -template bool miller_rabin_primality_test(T num, T repeats) { +template +bool miller_rabin_primality_test(T num, T repeats) { if (num <= 4) { // If num == 2 or num == 3 then prime if (num == 2 || num == 3) { From 0f5e880376239db1a12be4ed0900e99794a828fc Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 21 Jun 2020 17:42:10 +0000 Subject: [PATCH 021/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 071ee8b95..9cb6abcfa 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -116,6 +116,7 @@ * [Large Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_factorial.cpp) * [Large Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/large_number.h) * [Least Common Multiple](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/least_common_multiple.cpp) + * [Miller Rabin](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/miller_rabin.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 d9fc87896213c3fb562fb6fadb68821310f5ced7 Mon Sep 17 00:00:00 2001 From: matgrz1993 Date: Sun, 21 Jun 2020 21:41:08 +0200 Subject: [PATCH 022/261] fix: Remove FenwickTree (#856) * Remove FenwickTree FenwickTree is the same Data Structure as Binary Indexed Tree located in file "range_queries/bit.cpp" so it could be removed. * Fix cpplint errors * docs: Update documentation * docs: Update FenwickTree documentation * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 3 +- range_queries/bit.cpp | 60 ------------------------- range_queries/fenwick_tree.cpp | 82 ++++++++++++++++++++++++++++++++++ range_queries/fenwicktree.cpp | 54 ---------------------- 4 files changed, 83 insertions(+), 116 deletions(-) delete mode 100644 range_queries/bit.cpp create mode 100644 range_queries/fenwick_tree.cpp delete mode 100644 range_queries/fenwicktree.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 9cb6abcfa..4989050df 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -181,8 +181,7 @@ * [Poisson Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/probability/poisson_dist.cpp) ## Range Queries - * [Bit](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/bit.cpp) - * [Fenwicktree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/fenwicktree.cpp) + * [Fenwick Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/fenwick_tree.cpp) * [Mo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/mo.cpp) * [Segtree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/range_queries/segtree.cpp) diff --git a/range_queries/bit.cpp b/range_queries/bit.cpp deleted file mode 100644 index a1878705b..000000000 --- a/range_queries/bit.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Binary Indexed Tree. -#include - -using namespace std; - -class Bit { - int n; - vector bit; - inline int offset(int x) { return (x & (-x)); } - - public: - Bit(vector& arr) { - n = arr.size(); - bit.assign(n + 1, 0); - for (int i = 0; i < n; ++i) { - update(i, arr[i]); - } - } - Bit(int x) { - n = x; - bit.assign(n + 1, 0); - } - - void update(int id, int val) { - // Add val at id - id++; - while (id <= n) { - bit[id] += val; - id += offset(id); - } - } - - int sum(int id) { - // Get prefix sum upto id. - id++; - int res = 0; - while (id > 0) { - res += bit[id]; - id -= offset(id); - } - return res; - } - - int sum_range(int l, int r) { return sum(r) - sum(l - 1); } -}; - -int main() { - int n = 5; - vector arr = {1, 2, 3, 4, 5}; - Bit x(arr); - - assert(x.sum_range(0, 0) == 1); - assert(x.sum_range(0, 1) == 3); - assert(x.sum_range(0, 2) == 6); - x.update(0, 6); - assert(x.sum_range(0, 0) == 6); - assert(x.sum_range(0, 1) == 8); - assert(x.sum_range(0, 2) == 11); - return 0; -} diff --git a/range_queries/fenwick_tree.cpp b/range_queries/fenwick_tree.cpp new file mode 100644 index 000000000..a2498dc6a --- /dev/null +++ b/range_queries/fenwick_tree.cpp @@ -0,0 +1,82 @@ +/** + * @file + * @brief Fenwick tree + * + * A Fenwick tree or binary indexed tree is a data structure + * that can efficiently update elements and calculate + * prefix sums in a table of numbers. + */ +#include +#include +#include + +/** + * n --> No. of elements present in input array. + * bit[0..n] --> Array that represents Binary Indexed Tree. + */ +class FenwickTree { + int n; + std::vector bit; + + /** Returns the highest power of two which is not more than x */ + inline int offset(int x) { return (x & (-x)); } + + public: + /** Constructor + * \param[in] arr --> Input array for which prefix sum is evaluated. + */ + explicit FenwickTree(const std::vector& arr) { + n = arr.size(); + bit.assign(n + 1, 0); + for (int i = 0; i < n; ++i) { + update(i, arr[i]); + } + } + + /** Constructor + * \param[in] x --> Size of array that represents Binary Indexed Tree. + */ + explicit FenwickTree(int x) { + n = x; + bit.assign(n + 1, 0); + } + + /** Add val at id */ + void update(int id, int val) { + id++; + while (id <= n) { + bit[id] += val; + id += offset(id); + } + } + + /** Get prefix sum upto id */ + int sum(int id) { + id++; + int res = 0; + while (id > 0) { + res += bit[id]; + id -= offset(id); + } + return res; + } + + /** Returns the prefix sum in range from l to r */ + int sum_range(int l, int r) { return sum(r) - sum(l - 1); } +}; + +/** Main function */ +int main() { + int n = 5; + std::vector arr = {1, 2, 3, 4, 5}; + FenwickTree fenwick_tree(arr); + + assert(fenwick_tree.sum_range(0, 0) == 1); + assert(fenwick_tree.sum_range(0, 1) == 3); + assert(fenwick_tree.sum_range(0, 2) == 6); + fenwick_tree.update(0, 6); + assert(fenwick_tree.sum_range(0, 0) == 6); + assert(fenwick_tree.sum_range(0, 1) == 8); + assert(fenwick_tree.sum_range(0, 2) == 11); + return 0; +} diff --git a/range_queries/fenwicktree.cpp b/range_queries/fenwicktree.cpp deleted file mode 100644 index fb7cbaac4..000000000 --- a/range_queries/fenwicktree.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -using namespace std; - -/** - * ` lowbit(x) ` aims to find the last 1 in binary of a positive number - * twos complement works good on this - * also using ` x - (x & (x - 1)) ` - */ -#define lowbit(x) (x & (-x)) - -const int maxn = 1e5 + 7; -int tree[maxn] = {0}, - range; // segement of [1...range], notice it must be less than `maxn` - -void update(int x, int c) { - while (x <= range) { - tree[x] += c; - x += lowbit(x); - } -} -int query(int x) { - int ans = 0; - while (x) { - ans += tree[x]; - x -= lowbit(x); - } - return ans; -} -int query_segement(int l, int r) { return query(r) - query(l - 1); } - -int main() { - cin >> range; - for (int i = 1; i <= range; i++) { - int num; - cin >> num; - update(i, num); - } - int q; - cin >> q; - while (q--) { - int op; - cin >> op; - if (op == 0) { - int l, r; - cin >> l >> r; - cout << query_segement(l, r) << endl; - } else { - int x, c; - cin >> x >> c; - update(x, c); - } - } - return 0; -} From 00dda54f4f1f52ad497747a2316309cc2d0cbf05 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 17:12:18 -0400 Subject: [PATCH 023/261] ensure search window is increasing and greater than tolerance --- numerical_methods/golden_search_extrema.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 5a327c1ef..5d84c5572 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -31,6 +31,14 @@ double get_minima(const std::function &f, double lim_a, double c, d; double prev_mean, mean = std::numeric_limits::infinity(); + // ensure that lim_a < lim_b + if (lim_a > lim_b) { + std::swap(lim_a, lim_b); + } else if (std::abs(lim_a - lim_b) <= EPSILON) { + std::cerr << "Search range must be greater than " << EPSILON << "\n"; + return lim_a; + } + do { prev_mean = mean; From 9c186095a806e293e3da3c6fdf3562b864789f0a Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 17:31:53 -0400 Subject: [PATCH 024/261] print number of steps taken for convergence --- numerical_methods/golden_search_extrema.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 5d84c5572..44e8e2c12 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -28,6 +28,7 @@ */ double get_minima(const std::function &f, double lim_a, double lim_b) { + uint32_t iters = 0; double c, d; double prev_mean, mean = std::numeric_limits::infinity(); @@ -51,10 +52,12 @@ double get_minima(const std::function &f, double lim_a, lim_a = c; } - mean = (lim_a + lim_b) * 0.5f; + mean = (lim_a + lim_b) / 2.f; + iters++; } while (std::abs(mean - prev_mean) > EPSILON); - return mean; + std::cout << " (iters: " << iters << ") "; + return prev_mean; } /** @@ -115,7 +118,7 @@ void test3() { std::cout << "Test 3.... "; - double minima = get_minima(func, 0, 12); + double minima = get_minima(func, -4, 12); std::cout << minima << " (" << M_PI << ")..."; @@ -127,6 +130,9 @@ void test3() { int main() { std::cout.precision(18); + std::cout << "Computations performed with machine epsilon: " << EPSILON + << "\n"; + test1(); test2(); test3(); From 21e93919f3255103d0442733eec0952b3b9c75d2 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 17:50:04 -0400 Subject: [PATCH 025/261] limit print precision to 9 decimals --- numerical_methods/golden_search_extrema.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 44e8e2c12..41bf9c8d3 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -128,7 +128,7 @@ void test3() { /** Main function */ int main() { - std::cout.precision(18); + std::cout.precision(9); std::cout << "Computations performed with machine epsilon: " << EPSILON << "\n"; From e71ee9ccb0aa58aeb10fff22d5c48e2e65fe44bb Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 18:30:31 -0400 Subject: [PATCH 026/261] better documentation of algorithm --- numerical_methods/golden_search_extrema.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 41bf9c8d3..0969544e5 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -14,12 +14,11 @@ #include #define EPSILON 1e-7 ///< solution accuracy limit -#define M_GOLDEN_RATIO \ - static_cast(1.618033988749894848204586834) ///< golden ratio value /** * @brief Get the minima of a function in the given interval. To get the maxima, - * simply negate the function. + * simply negate the function. The golden ratio used here is:\f[ + * k=\frac{3-\sqrt{5}}{2} \approx 0.381966\ldots\f] * * @param f function to get minima for * @param lim_a lower limit of search window @@ -32,6 +31,9 @@ double get_minima(const std::function &f, double lim_a, double c, d; double prev_mean, mean = std::numeric_limits::infinity(); + // golden ratio value + const double M_GOLDEN_RATIO = (1.f + std::sqrt(5.f)) / 2.f; + // ensure that lim_a < lim_b if (lim_a > lim_b) { std::swap(lim_a, lim_b); @@ -43,18 +45,24 @@ double get_minima(const std::function &f, double lim_a, do { prev_mean = mean; - c = lim_b - (lim_b - lim_a) / M_GOLDEN_RATIO; - d = lim_a + (lim_b - lim_a) / M_GOLDEN_RATIO; + // compute the section ratio width + double ratio = (lim_b - lim_a) / M_GOLDEN_RATIO; + c = lim_b - ratio; // right-side section start + d = lim_a + ratio; // left-side section end if (f(c) < f(d)) { + // select left section lim_b = d; } else { + // selct right section lim_a = c; } mean = (lim_a + lim_b) / 2.f; iters++; - } while (std::abs(mean - prev_mean) > EPSILON); + + // continue till the interval width is greater than sqrt(system epsilon) + } while (std::abs(lim_a - lim_b) > EPSILON); std::cout << " (iters: " << iters << ") "; return prev_mean; From 744da70bbf744c77579edd9540ce9d757106dbe4 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 22:28:50 -0400 Subject: [PATCH 027/261] added see-also reference to brents method --- numerical_methods/golden_search_extrema.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/numerical_methods/golden_search_extrema.cpp b/numerical_methods/golden_search_extrema.cpp index 0969544e5..1ca47949f 100644 --- a/numerical_methods/golden_search_extrema.cpp +++ b/numerical_methods/golden_search_extrema.cpp @@ -4,6 +4,7 @@ * [golden section search * algorithm](https://en.wikipedia.org/wiki/Golden-section_search). * + * \see brent_method_extrema.cpp * \author [Krishna Vedala](https://github.com/kvedala) */ #define _USE_MATH_DEFINES //< required for MS Visual C++ From db0fc17efbb13a9c66dfa46f5c9f737047696cbc Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 22:30:23 -0400 Subject: [PATCH 028/261] feat: added brent's mthod to find extrema of a unimodal real function with real variables Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- numerical_methods/brent_method_extrema.cpp | 215 +++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 numerical_methods/brent_method_extrema.cpp diff --git a/numerical_methods/brent_method_extrema.cpp b/numerical_methods/brent_method_extrema.cpp new file mode 100644 index 000000000..941c3b694 --- /dev/null +++ b/numerical_methods/brent_method_extrema.cpp @@ -0,0 +1,215 @@ +/** + * \file + * \brief Find real extrema of a univariate real function in a given interval + * using [Brent's method](https://en.wikipedia.org/wiki/Brent%27s_method). + * + * Refer the algorithm discoverer's publication + * [online](https://maths-people.anu.edu.au/~brent/pd/rpb011i.pdf) and also + * associated book: + * > R. P. Brent, Algorithms for Minimization without + * > Derivatives, Prentice-Hall, Englewood Cliffs, New Jersey, 1973 + * + * \see golden_search_extrema.cpp + * + * \author [Krishna Vedala](https://github.com/kvedala) + */ +#define _USE_MATH_DEFINES //< required for MS Visual C++ +#include +#include +#include +#include +#include + +#define EPSILON \ + std::sqrt( \ + std::numeric_limits::epsilon()) ///< system accuracy limit + +/** + * @brief Get the real root of a function in the given interval. + * + * @param f function to get root for + * @param lim_a lower limit of search window + * @param lim_b upper limit of search window + * @return root found in the interval + */ +double get_minima(const std::function &f, double lim_a, + double lim_b) { + uint32_t iters = 0; + + if (lim_a > lim_b) { + std::swap(lim_a, lim_b); + } else if (std::abs(lim_a - lim_b) <= EPSILON) { + std::cerr << "Search range must be greater than " << EPSILON << "\n"; + return lim_a; + } + + // golden ratio value + const double M_GOLDEN_RATIO = (3.f - std::sqrt(5.f)) / 2.f; + + double v = lim_a + M_GOLDEN_RATIO * (lim_b - lim_a); + double u, w = v, x = v; + double fu, fv = f(v); + double fw = fv, fx = fv; + + double mid_point = (lim_a + lim_b) / 2.f; + double p = 0, q = 0, r = 0; + + double d, e = 0; + double tolerance, tolerance2; + + do { + mid_point = (lim_a + lim_b) / 2.f; + tolerance = EPSILON * std::abs(x); + tolerance2 = 2 * tolerance; + + if (std::abs(e) > tolerance2) { + // fit parabola + r = (x - w) * (fx - fv); + q = (x - v) * (fx - fw); + p = (x - v) * q - (x - w) * r; + q = 2.f * (q - r); + if (q > 0) + p = -p; + else + q = -q; + r = e; + e = d; + } + + if (std::abs(p) < std::abs(0.5 * q * r) && p < q * (lim_b - x)) { + // parabolic interpolation step + d = p / q; + u = x + d; + if (u - lim_a < tolerance2 || lim_b - u < tolerance2) + d = x < mid_point ? tolerance : -tolerance; + } else { + // golden section interpolation step + e = (x < mid_point ? lim_b : lim_a) - x; + d = M_GOLDEN_RATIO * e; + } + + // evaluate not too close to x + if (std::abs(d) >= tolerance) + u = d; + else if (d > 0) + u = tolerance; + else + u = -tolerance; + u += x; + fu = f(u); + + // update variables + if (fu <= fx) { + if (u < x) + lim_b = x; + else + lim_a = x; + v = w; + fv = fw; + w = x; + fw = fx; + x = u; + fx = fu; + } else { + if (u < x) + lim_a = u; + else + lim_b = u; + if (fu <= fw || x == w) { + v = w; + fv = fw; + w = u; + fw = fu; + } else if (fu <= fv || v == x || v == w) { + v = u; + fv = fu; + } + } + + iters++; + } while (std::abs(x - mid_point) > (tolerance - (lim_b - lim_a) / 2.f)); + + std::cout << " (iters: " << iters << ") "; + + return x; +} + +/** + * @brief Test function to find root for the function + * \f$f(x)= (x-2)^2\f$ + * in the interval \f$[1,5]\f$ + * \n Expected result = 2 + */ +void test1() { + // define the function to minimize as a lambda function + std::function f1 = [](double x) { + return (x - 2) * (x - 2); + }; + + std::cout << "Test 1.... "; + + double minima = get_minima(f1, -1, 5); + + std::cout << minima << "..."; + + assert(std::abs(minima - 2) < EPSILON * 2); + std::cout << "passed\n"; +} + +/** + * @brief Test function to find root for the function + * \f$f(x)= x^{\frac{1}{x}}\f$ + * in the interval \f$[-2,10]\f$ + * \n Expected result: \f$e\approx 2.71828182845904509\f$ + */ +void test2() { + // define the function to maximize as a lambda function + // since we are maximixing, we negated the function return value + std::function func = [](double x) { + return -std::pow(x, 1.f / x); + }; + + std::cout << "Test 2.... "; + + double minima = get_minima(func, -2, 5); + + std::cout << minima << " (" << M_E << ")..."; + + assert(std::abs(minima - M_E) < EPSILON * 2); + std::cout << "passed\n"; +} + +/** + * @brief Test function to find *maxima* for the function + * \f$f(x)= \cos x\f$ + * in the interval \f$[0,12]\f$ + * \n Expected result: \f$\pi\approx 3.14159265358979312\f$ + */ +void test3() { + // define the function to maximize as a lambda function + // since we are maximixing, we negated the function return value + std::function func = [](double x) { return std::cos(x); }; + + std::cout << "Test 3.... "; + + double minima = get_minima(func, -4, 12); + + std::cout << minima << " (" << M_PI << ")..."; + + assert(std::abs(minima - M_PI) < EPSILON * 2); + std::cout << "passed\n"; +} + +/** Main function */ +int main() { + std::cout.precision(18); + + std::cout << "Computations performed with machine epsilon: " << EPSILON + << "\n"; + + test1(); + test2(); + test3(); + + return 0; +} From 1c4026bca1e3fb0e4e1083c06f71653a0c59933c Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 22 Jun 2020 02:31:55 +0000 Subject: [PATCH 029/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 071ee8b95..55a97657c 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -129,6 +129,7 @@ ## Numerical Methods * [Bisection Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/bisection_method.cpp) + * [Brent Method Extrema](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/brent_method_extrema.cpp) * [Durand Kerner Roots](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/durand_kerner_roots.cpp) * [False Position](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/false_position.cpp) * [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/gaussian_elimination.cpp) From 957fe5c6ce1479342001fc141f5bbec0f60bfaff Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 23:05:36 -0400 Subject: [PATCH 030/261] fixed doc for #define --- numerical_methods/brent_method_extrema.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/brent_method_extrema.cpp b/numerical_methods/brent_method_extrema.cpp index 941c3b694..10b53b882 100644 --- a/numerical_methods/brent_method_extrema.cpp +++ b/numerical_methods/brent_method_extrema.cpp @@ -13,7 +13,7 @@ * * \author [Krishna Vedala](https://github.com/kvedala) */ -#define _USE_MATH_DEFINES //< required for MS Visual C++ +#define _USE_MATH_DEFINES ///< required for MS Visual C++ #include #include #include From ef957bae98dde4bed07186c72ab75083db53763f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 21 Jun 2020 23:08:53 -0400 Subject: [PATCH 031/261] removed scaling during assert checks --- numerical_methods/brent_method_extrema.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/numerical_methods/brent_method_extrema.cpp b/numerical_methods/brent_method_extrema.cpp index 10b53b882..654a69451 100644 --- a/numerical_methods/brent_method_extrema.cpp +++ b/numerical_methods/brent_method_extrema.cpp @@ -152,7 +152,7 @@ void test1() { std::cout << minima << "..."; - assert(std::abs(minima - 2) < EPSILON * 2); + assert(std::abs(minima - 2) < EPSILON); std::cout << "passed\n"; } @@ -175,7 +175,7 @@ void test2() { std::cout << minima << " (" << M_E << ")..."; - assert(std::abs(minima - M_E) < EPSILON * 2); + assert(std::abs(minima - M_E) < EPSILON); std::cout << "passed\n"; } @@ -196,7 +196,7 @@ void test3() { std::cout << minima << " (" << M_PI << ")..."; - assert(std::abs(minima - M_PI) < EPSILON * 2); + assert(std::abs(minima - M_PI) < EPSILON); std::cout << "passed\n"; } From c563fc66947f424edea5ca55149bccbfee444701 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 22 Jun 2020 12:05:13 +0000 Subject: [PATCH 032/261] formatting source-code for 9bc80876e81aeb73c9490417f19cc1d91e60e0d1 --- math/sum_of_digits.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/sum_of_digits.cpp b/math/sum_of_digits.cpp index d5a705c48..cc2595e01 100644 --- a/math/sum_of_digits.cpp +++ b/math/sum_of_digits.cpp @@ -1,24 +1,24 @@ /** * Copyright 2020 @author iamnambiar - * + * * @file * \brief A C++ Program to find the Sum of Digits of input integer. */ -#include #include +#include /** * Function to find the sum of the digits of an integer. * @param num The integer. * @return Sum of the digits of the integer. - * + * * \detail * First the algorithm check whether the num is negative or positive, * if it is negative, then we neglect the negative sign. - * Next, the algorithm extract the last digit of num by dividing by 10 + * Next, the algorithm extract the last digit of num by dividing by 10 * and extracting the remainder and this is added to the sum. * The number is then divided by 10 to remove the last digit. - * This loop continues until num becomes 0. + * This loop continues until num becomes 0. */ int sum_of_digits(int num) { // If num is negative then negative sign is neglected. @@ -52,7 +52,7 @@ void test2() { } /** - * Function for testing the sum_of_digits() with + * Function for testing the sum_of_digits() with * all the test cases. */ void test() { @@ -64,7 +64,7 @@ void test() { /** * Main Function -*/ + */ int main() { test(); std::cout << "Success." << std::endl; From 58d5f3ea114d6a9336e67d9eef0ea3649000083c Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 22 Jun 2020 12:05:14 +0000 Subject: [PATCH 033/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 4989050df..a24342e3b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -127,6 +127,7 @@ * [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sieve_of_eratosthenes.cpp) * [Sqrt Double](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sqrt_double.cpp) * [String Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/string_fibonacci.cpp) + * [Sum Of Digits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sum_of_digits.cpp) ## Numerical Methods * [Bisection Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/bisection_method.cpp) From bebb76e5570a4c496f29fb424f7044df07193074 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 22 Jun 2020 16:19:17 -0400 Subject: [PATCH 034/261] make 'a' signed --- math/large_number.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/large_number.h b/math/large_number.h index bffb764d0..51f8cc528 100644 --- a/math/large_number.h +++ b/math/large_number.h @@ -53,7 +53,7 @@ class large_number { /**< initializer from a string */ explicit large_number(char const *number_str) { for (size_t i = strlen(number_str); i > 0; i--) { - unsigned char a = number_str[i - 1] - '0'; + char a = number_str[i - 1] - '0'; if (a >= 0 && a <= 9) _digits.push_back(a); } From 8862859c18a1017be49d8f960f77abd18c75f9b0 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 22 Jun 2020 16:19:59 -0400 Subject: [PATCH 035/261] remove const identifier --- math/large_number.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/large_number.h b/math/large_number.h index 51f8cc528..521199862 100644 --- a/math/large_number.h +++ b/math/large_number.h @@ -127,7 +127,7 @@ class large_number { /** * Get number of digits in the number **/ - const size_t num_digits() const { return _digits.size(); } + size_t num_digits() const { return _digits.size(); } /** * operator over load to access the From fb82e9050d7708fa0c3b30e5d96c95c21ff520f5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 22 Jun 2020 16:20:27 -0400 Subject: [PATCH 036/261] remove const identifier for function --- math/large_number.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/large_number.h b/math/large_number.h index 521199862..57154f57b 100644 --- a/math/large_number.h +++ b/math/large_number.h @@ -245,7 +245,7 @@ class large_number { /** * returns i^th digit as an ASCII character **/ - const char digit_char(size_t i) const { + char digit_char(size_t i) const { return _digits[num_digits() - i - 1] + '0'; } From 8736dce71a47f44c5fc62d32287245c4f0e1d790 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 22 Jun 2020 16:21:57 -0400 Subject: [PATCH 037/261] make multiplication 64-bit --- math/large_number.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/large_number.h b/math/large_number.h index 57154f57b..421d8c303 100644 --- a/math/large_number.h +++ b/math/large_number.h @@ -264,7 +264,7 @@ class large_number { size_t i; uint64_t carry = 0, temp; for (i = 0; i < this->num_digits(); i++) { - temp = (*this)[i] * n; + temp = static_cast((*this)[i]) * n; temp += carry; if (temp < 10) { carry = 0; From fce7e22d8f142c1ad9b73317c64c489ae0eba802 Mon Sep 17 00:00:00 2001 From: liushubin lwx470335 Date: Tue, 23 Jun 2020 09:06:00 +0800 Subject: [PATCH 038/261] =?UTF-8?q?binary=20search=20tree=20insert?= =?UTF-8?q?=EF=BC=88=EF=BC=89=20function=20modify=E3=80=82=20insert=20the?= =?UTF-8?q?=20greater=20value=20to=20right=EF=BC=8Csmaller=20value=20to=20?= =?UTF-8?q?left=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data_structures/binary_search_tree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/binary_search_tree.cpp b/data_structures/binary_search_tree.cpp index 947bb53d8..3cc7d09fb 100644 --- a/data_structures/binary_search_tree.cpp +++ b/data_structures/binary_search_tree.cpp @@ -43,7 +43,7 @@ void Insert(node *n, int x) { temp->val = x; temp->left = NULL; temp->right = NULL; - n->left = temp; + n->right = temp; } else { Insert(n->right, x); } From 1158e626cb8fe76d6b3de9fdd7bd39672e62460a Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:29:48 +0100 Subject: [PATCH 039/261] feat: Added a class implemetation of complex numbers along with implementation of all (most) binary operations involved with complex numbers. --- math/complex_numbers.cpp | 183 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 math/complex_numbers.cpp diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp new file mode 100644 index 000000000..8d778d735 --- /dev/null +++ b/math/complex_numbers.cpp @@ -0,0 +1,183 @@ +/** + * Copyright 2020 @author tjgurwara99 + * @file + * + * A basic implementation of Complex Number field as a class with operators overloaded to accommodate (mathematical) field operations. + */ + +#include +#include +#include + +/** + * Class Complex to represent complex numbers as a field. + */ +class Complex { + // The real value of the complex number + double re; + // The imaginary value of the complex number + double im; + + public: + /** + * Complex Constructor which initialises the complex number which takes two arguments. + * @param x The real value of the complex number. + * @param y The imaginary value of the complex number. + */ + Complex(double x, double y) { + this->re = x; + this->im = y; + } + + /** + * Complex Constructor which initialises the complex number with no arguments. + */ + Complex() { + Complex(0.0,0.0); + } + + /** + * Member function (getter) to access the class' re value. + */ + double real() const { + return this->re; + } + + /** + * Member function (getter) to access the class' im value. + */ + double imag() const { + return this->im; + } + + /** + * Member function to which gives the absolute value (modulus) of our complex number + * @return \f$ \sqrt{z \dot \bar{z} \f$ where \f$ z \f$ is our complex number. + */ + double abs() const { + return std::sqrt(this->re*this->re + this->im*this->im); + } + + /** + * Operator overload to be able to add two complex numbers. + * @param other The other number that is added to the current number. + * @return result current number plus other number + */ + Complex operator+(const Complex& other) { + Complex result(this->re + other.re, this->im + other.im); + return result; + } + + /** + * Operator overload to be able to subtract two complex numbers. + * @param other The other number being subtracted from the current number. + * @return result current number subtract other number + */ + Complex operator-(const Complex& other) { + Complex result(this->re - other.re, this->im - other.im); + return result; + } + + /** + * Operator overload to be able to multiple two complex numbers. + * @param other The other number to multiply the current number to. + * @return result current number times other number. + */ + Complex operator*(const Complex& other) { + Complex result(this->re * other.re - this->im * other.im, + this->re * other.im + this->im * other.re); + return result; + } + + /** + * Operator overload of the BITWISE NOT which gives us the conjugate of our complex number. + * NOTE: This is overloading the BITWISE operator but its not a BITWISE operation in this definition. + * @return result The conjugate of our complex number. + */ + Complex operator~() const { + Complex result(this->re, -(this->im)); + return result; + } + + /** + * Operator overload to be able to divide two complex numbers. This function would throw an exception if the other number is zero. + * @param other The other number we divide our number by. + * @return result Current number divided by other number. + */ + Complex operator/(const Complex& other) { + Complex result = *this * ~other; + double denominator = other.abs() * other.abs(); + if (denominator != 0) { + result = Complex(result.real() / denominator, result.imag() / denominator); + return result; + } + else { + throw std::invalid_argument("Undefined Value"); + } + } +}; + +/** + * Logical Equal overload for our Complex class. + * @param a Left hand side of our expression + * @param b Right hand side of our expression + * @return 'True' If real and imaginary parts of a and b are same + * @return 'False' Otherwise. + */ +bool operator==(const Complex& a, const Complex& b) { + double del_real = a.real() - b.real(); + double del_imag = a.imag() - b.imag(); + return ((del_real <= 1e-15 && del_real >= - 1e-15 ) && (del_imag <= 1e-15 && del_imag >= - 1e-15)); +} + +/** + * Overloaded insersion operator to accommodate the printing of our complex number in their standard form. + * @param os The console stream + * @param num The complex number. + */ +std::ostream& operator<<(std::ostream& os, const Complex& num) { + os << num.real(); + if (num.imag() < 0) { + os << " - " << -num.imag(); + } + else { + os << " + " << num.imag(); + } + os << "i"; + return os; +} + +/** + * Tests Function + */ +void tests() { + Complex num1(1,1), num2(1,1); + // Test for addition + assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't add up \n", + (num1 + num2) == Complex(2,2))); + std::cout << "First test passes." << std::endl; + // Test for subtraction + assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says otherwise. \n", + (num1 - num2) == Complex(0,0))); + std::cout << "Second test passes." << std::endl; + // Test for multiplication + assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says otherwise. \n", + (num1 * num2) == Complex(0,2))); + std::cout << "Third test passes." << std::endl; + // Test for division + assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says otherwise.\n", + (num1 / num2) == Complex(1,0))); + std::cout << "Fourth test passes." << std::endl; + // Test for conjugates + assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the program says otherwise.\n", + ~num1 == Complex(1,-1))); + std::cout << "Fifth test passes." << std::endl; + +} +/** + * Main function + */ +int main() { + tests(); + return 0; +} From f4fa366da501e41cac6bd274df4a02fc345d0c3b Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:32:08 +0100 Subject: [PATCH 040/261] docs: Fixed some clangformat issues with the documentation --- math/complex_numbers.cpp | 98 +++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 8d778d735..9a381b125 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -2,11 +2,12 @@ * Copyright 2020 @author tjgurwara99 * @file * - * A basic implementation of Complex Number field as a class with operators overloaded to accommodate (mathematical) field operations. + * A basic implementation of Complex Number field as a class with operators + * overloaded to accommodate (mathematical) field operations. */ -#include #include +#include #include /** @@ -18,9 +19,10 @@ class Complex { // The imaginary value of the complex number double im; - public: + public: /** - * Complex Constructor which initialises the complex number which takes two arguments. + * Complex Constructor which initialises the complex number which takes two + * arguments. * @param x The real value of the complex number. * @param y The imaginary value of the complex number. */ @@ -28,34 +30,31 @@ class Complex { this->re = x; this->im = y; } - + /** - * Complex Constructor which initialises the complex number with no arguments. + * Complex Constructor which initialises the complex number with no + * arguments. */ - Complex() { - Complex(0.0,0.0); - } + Complex() { Complex(0.0, 0.0); } /** * Member function (getter) to access the class' re value. */ - double real() const { - return this->re; - } + double real() const { return this->re; } /** * Member function (getter) to access the class' im value. */ - double imag() const { - return this->im; - } + double imag() const { return this->im; } /** - * Member function to which gives the absolute value (modulus) of our complex number - * @return \f$ \sqrt{z \dot \bar{z} \f$ where \f$ z \f$ is our complex number. + * Member function to which gives the absolute value (modulus) of our + * complex number + * @return \f$ \sqrt{z \dot \bar{z}} \f$ where \f$ z \f$ is our complex + * number. */ double abs() const { - return std::sqrt(this->re*this->re + this->im*this->im); + return std::sqrt(this->re * this->re + this->im * this->im); } /** @@ -63,7 +62,7 @@ class Complex { * @param other The other number that is added to the current number. * @return result current number plus other number */ - Complex operator+(const Complex& other) { + Complex operator+(const Complex &other) { Complex result(this->re + other.re, this->im + other.im); return result; } @@ -73,7 +72,7 @@ class Complex { * @param other The other number being subtracted from the current number. * @return result current number subtract other number */ - Complex operator-(const Complex& other) { + Complex operator-(const Complex &other) { Complex result(this->re - other.re, this->im - other.im); return result; } @@ -83,15 +82,16 @@ class Complex { * @param other The other number to multiply the current number to. * @return result current number times other number. */ - Complex operator*(const Complex& other) { + Complex operator*(const Complex &other) { Complex result(this->re * other.re - this->im * other.im, this->re * other.im + this->im * other.re); return result; } /** - * Operator overload of the BITWISE NOT which gives us the conjugate of our complex number. - * NOTE: This is overloading the BITWISE operator but its not a BITWISE operation in this definition. + * Operator overload of the BITWISE NOT which gives us the conjugate of our + * complex number. NOTE: This is overloading the BITWISE operator but its + * not a BITWISE operation in this definition. * @return result The conjugate of our complex number. */ Complex operator~() const { @@ -100,18 +100,19 @@ class Complex { } /** - * Operator overload to be able to divide two complex numbers. This function would throw an exception if the other number is zero. + * Operator overload to be able to divide two complex numbers. This function + * would throw an exception if the other number is zero. * @param other The other number we divide our number by. * @return result Current number divided by other number. */ - Complex operator/(const Complex& other) { + Complex operator/(const Complex &other) { Complex result = *this * ~other; double denominator = other.abs() * other.abs(); if (denominator != 0) { - result = Complex(result.real() / denominator, result.imag() / denominator); + result = Complex(result.real() / denominator, + result.imag() / denominator); return result; - } - else { + } else { throw std::invalid_argument("Undefined Value"); } } @@ -124,23 +125,24 @@ class Complex { * @return 'True' If real and imaginary parts of a and b are same * @return 'False' Otherwise. */ -bool operator==(const Complex& a, const Complex& b) { +bool operator==(const Complex &a, const Complex &b) { double del_real = a.real() - b.real(); double del_imag = a.imag() - b.imag(); - return ((del_real <= 1e-15 && del_real >= - 1e-15 ) && (del_imag <= 1e-15 && del_imag >= - 1e-15)); + return ((del_real <= 1e-15 && del_real >= -1e-15) && + (del_imag <= 1e-15 && del_imag >= -1e-15)); } /** - * Overloaded insersion operator to accommodate the printing of our complex number in their standard form. + * Overloaded insersion operator to accommodate the printing of our complex + * number in their standard form. * @param os The console stream * @param num The complex number. */ -std::ostream& operator<<(std::ostream& os, const Complex& num) { +std::ostream &operator<<(std::ostream &os, const Complex &num) { os << num.real(); if (num.imag() < 0) { os << " - " << -num.imag(); - } - else { + } else { os << " + " << num.imag(); } os << "i"; @@ -151,28 +153,32 @@ std::ostream& operator<<(std::ostream& os, const Complex& num) { * Tests Function */ void tests() { - Complex num1(1,1), num2(1,1); + Complex num1(1, 1), num2(1, 1); // Test for addition - assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't add up \n", - (num1 + num2) == Complex(2,2))); + assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " + "add up \n", + (num1 + num2) == Complex(2, 2))); std::cout << "First test passes." << std::endl; // Test for subtraction - assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says otherwise. \n", - (num1 - num2) == Complex(0,0))); + assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " + "otherwise. \n", + (num1 - num2) == Complex(0, 0))); std::cout << "Second test passes." << std::endl; // Test for multiplication - assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says otherwise. \n", - (num1 * num2) == Complex(0,2))); + assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " + "otherwise. \n", + (num1 * num2) == Complex(0, 2))); std::cout << "Third test passes." << std::endl; // Test for division - assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says otherwise.\n", - (num1 / num2) == Complex(1,0))); + assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " + "otherwise.\n", + (num1 / num2) == Complex(1, 0))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates - assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the program says otherwise.\n", - ~num1 == Complex(1,-1))); + assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " + "program says otherwise.\n", + ~num1 == Complex(1, -1))); std::cout << "Fifth test passes." << std::endl; - } /** * Main function From 8969047d3ff8fe6f08966f0a465b239a4fdc16a0 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:41:46 +0100 Subject: [PATCH 041/261] fix: Added missing header --- math/complex_numbers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9a381b125..4505b5677 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -9,6 +9,7 @@ #include #include #include +#include /** * Class Complex to represent complex numbers as a field. From 626ab310955b5417675b0487a8d4f79f1786d355 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:53:09 +0100 Subject: [PATCH 042/261] fix: incorrect constructor delegation --- math/complex_numbers.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 4505b5677..10e50b22a 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -36,7 +36,10 @@ class Complex { * Complex Constructor which initialises the complex number with no * arguments. */ - Complex() { Complex(0.0, 0.0); } + Complex() { + this->re = 0.0; + this.im = 0.0; + } /** * Member function (getter) to access the class' re value. From c419e1f7882298fb98567898f82482fd2cd4c29a Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:54:10 +0100 Subject: [PATCH 043/261] fix: arrow operator instead of dot --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 10e50b22a..189d0b831 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -38,7 +38,7 @@ class Complex { */ Complex() { this->re = 0.0; - this.im = 0.0; + this->im = 0.0; } /** From 1708de2296204efd863e485068a96078ce76f5af Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 16:23:49 +0100 Subject: [PATCH 044/261] fix: fixed all pull request suggestions --- math/complex_numbers.cpp | 88 +++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 189d0b831..4ae5c493b 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -6,10 +6,11 @@ * overloaded to accommodate (mathematical) field operations. */ +#include #include +#include #include #include -#include /** * Class Complex to represent complex numbers as a field. @@ -27,19 +28,13 @@ class Complex { * @param x The real value of the complex number. * @param y The imaginary value of the complex number. */ - Complex(double x, double y) { - this->re = x; - this->im = y; - } + explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } /** - * Complex Constructor which initialises the complex number with no - * arguments. + * Copy Constructor + * @param other The other number to equate our number to. */ - Complex() { - this->re = 0.0; - this->im = 0.0; - } + Complex(const Complex &other) : re(other.real()), im(other.imag()) { ; } /** * Member function (getter) to access the class' re value. @@ -61,6 +56,26 @@ class Complex { return std::sqrt(this->re * this->re + this->im * this->im); } + /** + * Member function which gives the argument of our complex number. + * @return Argument of our Complex number. + */ + double arg() const { + if (this->re > 0) { + return std::atan(this->im / this->re); + } else if (this->re < 0 && this->im >= 0) { + return std::atan(this->im / this->re) + M_PI; + } else if (this->re < 0 && this->im < 0) { + return std::atan(this->im / this->re) - M_PI; + } else if (this->re == 0 && this->im > 0) { + return M_PI / 2; + } else if (this->re == 0 && this->im < 0) { + return -M_PI / 2; + } else { + throw std::invalid_argument("Undefined Value"); + } + } + /** * Operator overload to be able to add two complex numbers. * @param other The other number that is added to the current number. @@ -111,7 +126,8 @@ class Complex { */ Complex operator/(const Complex &other) { Complex result = *this * ~other; - double denominator = other.abs() * other.abs(); + double denominator = + other.real() * other.real() + other.imag() * other.imag(); if (denominator != 0) { result = Complex(result.real() / denominator, result.imag() / denominator); @@ -120,6 +136,16 @@ class Complex { throw std::invalid_argument("Undefined Value"); } } + + /** + * Operator overload to be able to copy RHS instance of Complex to LHS + * instance of Complex + */ + const Complex &operator=(const Complex &other) { + this->re = other.real(); + this->im = other.imag(); + return *this; + } }; /** @@ -130,10 +156,7 @@ class Complex { * @return 'False' Otherwise. */ bool operator==(const Complex &a, const Complex &b) { - double del_real = a.real() - b.real(); - double del_imag = a.imag() - b.imag(); - return ((del_real <= 1e-15 && del_real >= -1e-15) && - (del_imag <= 1e-15 && del_imag >= -1e-15)); + return a.real() == b.real() && a.imag() == b.imag(); } /** @@ -143,13 +166,13 @@ bool operator==(const Complex &a, const Complex &b) { * @param num The complex number. */ std::ostream &operator<<(std::ostream &os, const Complex &num) { - os << num.real(); + os << "(" << num.real(); if (num.imag() < 0) { os << " - " << -num.imag(); } else { os << " + " << num.imag(); } - os << "i"; + os << "i)"; return os; } @@ -158,32 +181,49 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { */ void tests() { Complex num1(1, 1), num2(1, 1); + std::complex cnum1(1, 1), cnum2(1, 1); // Test for addition assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " "add up \n", - (num1 + num2) == Complex(2, 2))); + ((num1 + num2).real() == (cnum1 + cnum2).real() && + (num1 + num2).imag() == (cnum1 + cnum2).imag()))); std::cout << "First test passes." << std::endl; // Test for subtraction assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " "otherwise. \n", - (num1 - num2) == Complex(0, 0))); + ((num1 - num2).real() == (cnum1 - cnum2).real() && + (num1 - num2).imag() == (cnum1 - cnum2).imag()))); std::cout << "Second test passes." << std::endl; // Test for multiplication assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " "otherwise. \n", - (num1 * num2) == Complex(0, 2))); + ((num1 * num2).real() == (cnum1 * cnum2).real() && + (num1 * num2).imag() == (cnum1 * cnum2).imag()))); std::cout << "Third test passes." << std::endl; // Test for division assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " "otherwise.\n", - (num1 / num2) == Complex(1, 0))); + ((num1 / num2).real() == (cnum1 / cnum2).real() && + (num1 / num2).imag() == (cnum1 / cnum2).imag()))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " "program says otherwise.\n", - ~num1 == Complex(1, -1))); - std::cout << "Fifth test passes." << std::endl; + ((~num1).real() == std::conj(cnum1).real() && + (~num1).imag() == std::conj(cnum1).imag()))); + std::cout << "Fifth test passes.\n"; + // Test for Argument of our complex number + assert(((void)"(1 + 1i) has argument PI / 4 but the program differs from " + "the std::complex result.\n", + (num1.arg() == std::arg(cnum1)))); + std::cout << "Sixth test passes.\n"; + // Test for absolute value of our complex number + assert(((void)"(1 + 1i) has absolute value sqrt(2) but the program differs " + "from the std::complex result. \n", + (num1.abs() == std::abs(cnum1)))); + std::cout << "Seventh test passes.\n"; } + /** * Main function */ From 52f918a4ffb11aec4fbc4b22d026e2e0a39b867d Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 16:33:54 +0100 Subject: [PATCH 045/261] fix: Fixed issue with Windows CI test - M_PI doesn't work on Windows CI --- math/complex_numbers.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 4ae5c493b..9d6ede15d 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -12,6 +12,11 @@ #include #include +/** + * Global constant for pi to work with Windows environment + */ +const double pi = 3.14159265358979323846; + /** * Class Complex to represent complex numbers as a field. */ @@ -64,13 +69,13 @@ class Complex { if (this->re > 0) { return std::atan(this->im / this->re); } else if (this->re < 0 && this->im >= 0) { - return std::atan(this->im / this->re) + M_PI; + return std::atan(this->im / this->re) + pi; } else if (this->re < 0 && this->im < 0) { - return std::atan(this->im / this->re) - M_PI; + return std::atan(this->im / this->re) - pi; } else if (this->re == 0 && this->im > 0) { - return M_PI / 2; + return pi / 2; } else if (this->re == 0 && this->im < 0) { - return -M_PI / 2; + return -pi / 2; } else { throw std::invalid_argument("Undefined Value"); } From 2fe7e4add0d4939d6553552d0714ec99d93f1683 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Tue, 23 Jun 2020 11:43:28 -0400 Subject: [PATCH 046/261] fix function return + add docs --- data_structures/list_array.cpp | 75 +++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/data_structures/list_array.cpp b/data_structures/list_array.cpp index c796ffef9..4c6855a51 100644 --- a/data_structures/list_array.cpp +++ b/data_structures/list_array.cpp @@ -1,5 +1,9 @@ +/** + * @file list_array.cpp + * @todo Add documentation + * @warning The sorting algorithm is erroneous + */ #include -using namespace std; struct list { int data[50]; @@ -17,6 +21,9 @@ struct list { return (BinarySearch(array, first, mid - 1, x)); else if (x > array[mid]) return (BinarySearch(array, mid + 1, last, x)); + + std::cerr << __func__ << ":" << __LINE__ << ": Undefined condition\n"; + return -1; } int LinarSearch(int *array, int x) { @@ -41,9 +48,9 @@ struct list { } if (pos != -1) { - cout << "\nElement found at position : " << pos; + std::cout << "\nElement found at position : " << pos; } else { - cout << "\nElement not found"; + std::cout << "\nElement not found"; } return pos; } @@ -69,7 +76,7 @@ struct list { void insert(int x) { if (!isSorted) { if (top == 49) { - cout << "\nOverflow"; + std::cout << "\nOverflow"; } else { data[top] = x; top++; @@ -99,7 +106,7 @@ struct list { void Remove(int x) { int pos = Search(x); - cout << "\n" << data[pos] << " deleted"; + std::cout << "\n" << data[pos] << " deleted"; for (int i = pos; i < top; i++) { data[i] = data[i + 1]; } @@ -108,7 +115,7 @@ struct list { void Show() { for (int i = 0; i < top; i++) { - cout << data[i] << "\t"; + std::cout << data[i] << "\t"; } } }; @@ -118,35 +125,35 @@ int main() { int choice; int x; do { - cout << "\n1.Insert"; - cout << "\n2.Delete"; - cout << "\n3.Search"; - cout << "\n4.Sort"; - cout << "\n5.Print"; - cout << "\n\nEnter Your Choice : "; - cin >> choice; + std::cout << "\n1.Insert"; + std::cout << "\n2.Delete"; + std::cout << "\n3.Search"; + std::cout << "\n4.Sort"; + std::cout << "\n5.Print"; + std::cout << "\n\nEnter Your Choice : "; + std::cin >> choice; switch (choice) { - case 1: - cout << "\nEnter the element to be inserted : "; - cin >> x; - L.insert(x); - break; - case 2: - cout << "\nEnter the element to be removed : "; - cin >> x; - L.Remove(x); - break; - case 3: - cout << "\nEnter the element to be searched : "; - cin >> x; - L.Search(x); - break; - case 4: - L.Sort(); - break; - case 5: - L.Show(); - break; + case 1: + std::cout << "\nEnter the element to be inserted : "; + std::cin >> x; + L.insert(x); + break; + case 2: + std::cout << "\nEnter the element to be removed : "; + std::cin >> x; + L.Remove(x); + break; + case 3: + std::cout << "\nEnter the element to be searched : "; + std::cin >> x; + L.Search(x); + break; + case 4: + L.Sort(); + break; + case 5: + L.Show(); + break; } } while (choice != 0); return 0; From 497ede21e0d29aa2a8b856289dfa24dec3751dc2 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Tue, 23 Jun 2020 11:45:16 -0400 Subject: [PATCH 047/261] fix function return --- data_structures/trie_tree.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data_structures/trie_tree.cpp b/data_structures/trie_tree.cpp index 66b67fbc0..a613ebd8f 100644 --- a/data_structures/trie_tree.cpp +++ b/data_structures/trie_tree.cpp @@ -74,6 +74,10 @@ bool deleteString(trie* root, std::string str, int index) { return true; } } + + /* should not return here */ + std::cout << __func__ << ":" << __LINE__ << "Should not reach this line\n"; + return false; } int main() { From 56cb22cd444aa1c24dffbbdd2356945dc873d362 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 15:46:52 +0000 Subject: [PATCH 048/261] formatting source-code for 497ede21e0d29aa2a8b856289dfa24dec3751dc2 --- data_structures/list_array.cpp | 42 +++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/data_structures/list_array.cpp b/data_structures/list_array.cpp index 4c6855a51..c49e17e06 100644 --- a/data_structures/list_array.cpp +++ b/data_structures/list_array.cpp @@ -133,27 +133,27 @@ int main() { std::cout << "\n\nEnter Your Choice : "; std::cin >> choice; switch (choice) { - case 1: - std::cout << "\nEnter the element to be inserted : "; - std::cin >> x; - L.insert(x); - break; - case 2: - std::cout << "\nEnter the element to be removed : "; - std::cin >> x; - L.Remove(x); - break; - case 3: - std::cout << "\nEnter the element to be searched : "; - std::cin >> x; - L.Search(x); - break; - case 4: - L.Sort(); - break; - case 5: - L.Show(); - break; + case 1: + std::cout << "\nEnter the element to be inserted : "; + std::cin >> x; + L.insert(x); + break; + case 2: + std::cout << "\nEnter the element to be removed : "; + std::cin >> x; + L.Remove(x); + break; + case 3: + std::cout << "\nEnter the element to be searched : "; + std::cin >> x; + L.Search(x); + break; + case 4: + L.Sort(); + break; + case 5: + L.Show(); + break; } } while (choice != 0); return 0; From 8575e21e73d5286b1c05cbe8b70f77997f0b0a2f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Tue, 23 Jun 2020 11:50:12 -0400 Subject: [PATCH 049/261] fix lint errors --- data_structures/list_array.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/data_structures/list_array.cpp b/data_structures/list_array.cpp index c49e17e06..24b04867b 100644 --- a/data_structures/list_array.cpp +++ b/data_structures/list_array.cpp @@ -41,9 +41,7 @@ struct list { if (isSorted) { pos = BinarySearch(data, 0, top - 1, x); - } - - else { + } else { pos = LinarSearch(data, x); } @@ -81,9 +79,7 @@ struct list { data[top] = x; top++; } - } - - else { + } else { int pos = 0; for (int i = 0; i < top - 1; i++) { From b9658104cb024a1044f2b621566dadf9a184f8a2 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 17:56:53 +0100 Subject: [PATCH 050/261] fix: Taken onboard some suggested changes --- math/complex_numbers.cpp | 70 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9d6ede15d..03dfe1069 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -12,11 +12,6 @@ #include #include -/** - * Global constant for pi to work with Windows environment - */ -const double pi = 3.14159265358979323846; - /** * Class Complex to represent complex numbers as a field. */ @@ -30,8 +25,8 @@ class Complex { /** * Complex Constructor which initialises the complex number which takes two * arguments. - * @param x The real value of the complex number. - * @param y The imaginary value of the complex number. + * @param x The real value of the complex number (optional). + * @param y The imaginary value of the complex number (optional). */ explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } @@ -63,23 +58,9 @@ class Complex { /** * Member function which gives the argument of our complex number. - * @return Argument of our Complex number. + * @return Argument of our Complex number in radians. */ - double arg() const { - if (this->re > 0) { - return std::atan(this->im / this->re); - } else if (this->re < 0 && this->im >= 0) { - return std::atan(this->im / this->re) + pi; - } else if (this->re < 0 && this->im < 0) { - return std::atan(this->im / this->re) - pi; - } else if (this->re == 0 && this->im > 0) { - return pi / 2; - } else if (this->re == 0 && this->im < 0) { - return -pi / 2; - } else { - throw std::invalid_argument("Undefined Value"); - } - } + double arg() const { return atan2(this->im, this->re); } /** * Operator overload to be able to add two complex numbers. @@ -181,41 +162,60 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { return os; } +/** + * Function to get random numbers to generate our complex numbers for test + */ +double get_rand() { return (std::rand() % 100 - 50) / 100.f; } + /** * Tests Function */ void tests() { - Complex num1(1, 1), num2(1, 1); - std::complex cnum1(1, 1), cnum2(1, 1); + std::srand(std::time(nullptr)); + double x1 = get_rand(), y1 = get_rand(), x2 = get_rand(), y2 = get_rand(); + Complex num1(x1, y1), num2(x2, y2); + std::complex cnum1(x1, y1), cnum2(x2, y2); + Complex result; + std::complex expected; // Test for addition + result = num1 + num2; + expected = cnum1 + cnum2; assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " "add up \n", - ((num1 + num2).real() == (cnum1 + cnum2).real() && - (num1 + num2).imag() == (cnum1 + cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "First test passes." << std::endl; // Test for subtraction + result = num1 - num2; + expected = cnum1 - cnum2; assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " "otherwise. \n", - ((num1 - num2).real() == (cnum1 - cnum2).real() && - (num1 - num2).imag() == (cnum1 - cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Second test passes." << std::endl; // Test for multiplication + result = num1 * num2; + expected = cnum1 * cnum2; assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " "otherwise. \n", - ((num1 * num2).real() == (cnum1 * cnum2).real() && - (num1 * num2).imag() == (cnum1 * cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Third test passes." << std::endl; // Test for division + result = num1 / num2; + expected = cnum1 / cnum2; assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " "otherwise.\n", - ((num1 / num2).real() == (cnum1 / cnum2).real() && - (num1 / num2).imag() == (cnum1 / cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates + result = ~num1; + expected = std::conj(cnum1); assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " "program says otherwise.\n", - ((~num1).real() == std::conj(cnum1).real() && - (~num1).imag() == std::conj(cnum1).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Fifth test passes.\n"; // Test for Argument of our complex number assert(((void)"(1 + 1i) has argument PI / 4 but the program differs from " From 907b8298309d898b6d3b967a9ba5b3fc62a6afe8 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:00:53 +0100 Subject: [PATCH 051/261] docs: copyright message --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 03dfe1069..b2353d785 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2020 @author tjgurwara99 + * @author tjgurwara99 * @file * * A basic implementation of Complex Number field as a class with operators From ce81700380e656ce6ec8898c7e87e3669ec9e5c3 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:04:42 +0100 Subject: [PATCH 052/261] fix: added missing header for std::time --- math/complex_numbers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index b2353d785..43b1d5fda 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -11,6 +11,7 @@ #include #include #include +#include /** * Class Complex to represent complex numbers as a field. From 61084adbd3b73aa5312836aa1836188dc24881f8 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:16:26 +0100 Subject: [PATCH 053/261] fix: fixed forgotten namespace --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 43b1d5fda..9168c08aa 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -61,7 +61,7 @@ class Complex { * Member function which gives the argument of our complex number. * @return Argument of our Complex number in radians. */ - double arg() const { return atan2(this->im, this->re); } + double arg() const { return std::atan2(this->im, this->re); } /** * Operator overload to be able to add two complex numbers. From 2aec4efdd3839cd513218b1738d13e6a324c18fe Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Tue, 23 Jun 2020 23:50:45 +0530 Subject: [PATCH 054/261] fix: integer overflow due to multiplication fixed (#886) * formatting source-code for 72c365dcd34d9776fac3e2b58b41891b3619b02e * Fixed Bug [munmap_chunck() core dumped] * formatting source-code for b06bbf4dc6c46a3284d7852bb570438384eef4ef * fixed line spacing * fixed line spacing * fixed documentation * closed the paranthesis of line 3 * formatting source-code for 8233eda8894f46785f288e72c639d201852f6096 * Bug Fix heap sort [Fresh Implementation] * formatting source-code for e464ddac3688834ce46c59bada5ad3fddbfa2254 * Bug Fix heap sort [Fresh Implementation] * formatting source-code for 803981c831b36bf940d3fa2a901340cb0029717b * switched to normal functions from lambda * formatting source-code for ced5dcd6c4db53ece27d22ecd1dd1c1fcce6afb0 * Added template and test cases * formatting source-code for 7c8617fa46d41481c68ae2ae9d4f6a89ca42a4ff * fixed docs * fixed line spacing in tests * fix docs * Multiplication result may overflow 'int' before it is converted to 'long'. * fixed cpplint long -> int64 * fixed compiler error Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- math/primes_up_to_billion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/primes_up_to_billion.cpp b/math/primes_up_to_billion.cpp index 4fb79a15e..b7377cea5 100644 --- a/math/primes_up_to_billion.cpp +++ b/math/primes_up_to_billion.cpp @@ -14,9 +14,9 @@ void Sieve(int64_t n) { memset(prime, '1', sizeof(prime)); // intitize '1' to every index prime[0] = '0'; // 0 is not prime prime[1] = '0'; // 1 is not prime - for (int p = 2; p * p <= n; p++) { + for (int64_t p = 2; p * p <= n; p++) { if (prime[p] == '1') { - for (int i = p * p; i <= n; i += p) + for (int64_t i = p * p; i <= n; i += p) prime[i] = '0'; // set all multiples of p to false } } From bcd5df725d83e06ae2fb69b0ccacbef5c56e454b Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:23:15 +0100 Subject: [PATCH 055/261] feat: added polar form initialisation to our Complex class --- math/complex_numbers.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9168c08aa..35e11ba1d 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include /** * Class Complex to represent complex numbers as a field. @@ -26,10 +26,22 @@ class Complex { /** * Complex Constructor which initialises the complex number which takes two * arguments. - * @param x The real value of the complex number (optional). - * @param y The imaginary value of the complex number (optional). + * @param x If the third parameter is 'true' then this x is the absolute + * value of the complex number, if the third parameter is 'false' then this + * x is the real value of the complex number (optional). + * @param y If the third parameter is 'true' then this y is the argument of + * the complex number, if the third parameter is 'false' then this y is the + * imaginary value of the complex number (optional). + * @param is_polar 'false' by default. If we want to initialise our complex + * number using polar form then set this to true, otherwise set it to false + * to use initialiser which initialises real and imaginary values using the + * first two parameters (optional). */ - explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } + explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) + : re(is_polar ? x * std::cos(y) : x), + im(is_polar ? x * std::sin(y) : y) { + ; + } /** * Copy Constructor From 95320b38a4a2aefaf0eb6b757438560b36d272f4 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:29:11 +0100 Subject: [PATCH 056/261] fix: cpplint issues --- math/complex_numbers.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 35e11ba1d..a4ee69829 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -22,7 +22,7 @@ class Complex { // The imaginary value of the complex number double im; - public: + public: /** * Complex Constructor which initialises the complex number which takes two * arguments. @@ -39,9 +39,7 @@ class Complex { */ explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) { - ; - } + im(is_polar ? x * std::sin(y) : y) { ; } /** * Copy Constructor From 9048e19184c3df765465c150ec7fa89151c41cd5 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:32:05 +0100 Subject: [PATCH 057/261] fix: cpplint issues --- math/complex_numbers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index a4ee69829..30edf4964 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -39,13 +39,13 @@ class Complex { */ explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) { ; } + im(is_polar ? x * std::sin(y) : y) {} /** * Copy Constructor * @param other The other number to equate our number to. */ - Complex(const Complex &other) : re(other.real()), im(other.imag()) { ; } + Complex(const Complex &other) : re(other.real()), im(other.imag()) {} /** * Member function (getter) to access the class' re value. From 75d8ee7cf07ee546e5f9fdbfad904060840fa607 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:43:56 +0100 Subject: [PATCH 058/261] fix: Readability issues --- math/complex_numbers.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 30edf4964..8b24c6d3c 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -37,9 +37,16 @@ class Complex { * to use initialiser which initialises real and imaginary values using the * first two parameters (optional). */ - explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) - : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) {} + explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) { + if (!is_polar) { + re = x; + im = y; + return; + } + + re = x * std::cos(y); + im = x * std::sin(y); + } /** * Copy Constructor From 7393d88811c7ddb58d73db3fd554eb1fd414f298 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:02:47 +0000 Subject: [PATCH 059/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 080e5f5d8..eb75ce3e5 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -102,6 +102,7 @@ ## Math * [Binary Exponent](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/binary_exponent.cpp) * [Check Prime](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_prime.cpp) + * [Complex Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/complex_numbers.cpp) * [Double Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/double_factorial.cpp) * [Eulers Totient Function](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/eulers_totient_function.cpp) * [Extended Euclid Algorithm](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/extended_euclid_algorithm.cpp) From 46e07288ba5b259ae2fa7b32c289b0305ef2def0 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sat, 20 Jun 2020 21:00:52 +0530 Subject: [PATCH 060/261] Fixed Bug [munmap_chunck() core dumped] --- sorting/merge_sort.cpp | 49 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index fc6d66af5..d6f099cea 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -1,36 +1,37 @@ /** * \addtogroup sorting Sorting Algorithms - * @{ + * @file{ * \file - * \brief [Merege Sort Algorithm + * \breif [Merege Sort Algorithm * (MEREGE SORT)](https://en.wikipedia.org/wiki/Merge_sort) implementation * - * \author [Ayaan Khan](http://github.com/ayaankhan98) + * \author [Ayaan Khan] (http://github.com/ayaankhan98) * - * \details * Merge Sort is an efficient, general purpose, comparison * based sorting algorithm. * Merge Sort is a divide and conquer algorithm - * + * */ + #include /** * - * The merge() function is used for merging two halves. - * The merge(arr, l, m, r) is key process that assumes that - * arr[l..m] and arr[m+1..r] are sorted and merges the two + * The merge() function is used for merging two halves. + * The merge(arr, l, m, r) is key process that assumes that + * arr[l..m] and arr[m+1..r] are sorted and merges the two * sorted sub-arrays into one. * - * @param arr - array with two halves arr[l...m] and arr[m+1...l] - * @param l - left index or start index of first half array - * @param m - right index or end index of first half array - * + * @param arr[] is the array with two halves one is arr[l...m] and + * other is arr[m+1...l] + * @param l is the left index of first half array + * @param m is the end index of right index of first half array + * * (The second array starts form m+1 and goes till l) - * - * @param l - end index or right index of second half array + * + * @param l is the end index of right index of second half array */ -void merge(int *arr, int l, int m, int r) { +void merge(int arr[], int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m; @@ -75,12 +76,12 @@ void merge(int *arr, int l, int m, int r) { * input array into two halves and calls itself for the two halves * and then calls merge() to merge the two halves * - * @param arr - array to be sorted - * @param l - left index or start index of array - * @param r - right index or end index of array + * @param arr[] the array which is to be sorted + * @param l define the left index of array + * @param r defines the right index of array * */ -void mergeSort(int *arr, int l, int r) { +void mergeSort(int arr[], int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); @@ -90,11 +91,11 @@ void mergeSort(int *arr, int l, int r) { } /** - * Utility function used to print the array after + * A simple utility function used to print the array after * sorting */ -void show(int *arr, int size) { - for (int i = 0; i < size; i++) std::cout << arr[i] << " "; +void show(int arr[], int size) { + for (int i = 0; i < size; i++) std::cout << arr[i] << " "; std::cout << "\n"; } @@ -108,9 +109,9 @@ int main() { for (int i = 0; i < size; ++i) { std::cin >> arr[i]; } - mergeSort(arr, 0, size - 1); + mergeSort(arr, 0, size-1); std::cout << "Sorted array : "; - show(arr, size - 1); + show(arr, size-1); delete[] arr; return 0; } From 5e63bede6fc40e1e5a07abea8d36748200332b27 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sat, 20 Jun 2020 21:02:50 +0530 Subject: [PATCH 061/261] fixed line spacing --- sorting/merge_sort.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index d6f099cea..87d1cd78d 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -12,7 +12,6 @@ * Merge Sort is a divide and conquer algorithm * */ - #include /** From b1d2ad1dfc033a0070479a6f680be3bf876dd03e Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 20 Jun 2020 15:31:59 +0000 Subject: [PATCH 062/261] formatting source-code for b06bbf4dc6c46a3284d7852bb570438384eef4ef --- sorting/merge_sort.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index 87d1cd78d..716c7c64d 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -10,24 +10,24 @@ * Merge Sort is an efficient, general purpose, comparison * based sorting algorithm. * Merge Sort is a divide and conquer algorithm - * + * */ #include /** * - * The merge() function is used for merging two halves. - * The merge(arr, l, m, r) is key process that assumes that - * arr[l..m] and arr[m+1..r] are sorted and merges the two + * The merge() function is used for merging two halves. + * The merge(arr, l, m, r) is key process that assumes that + * arr[l..m] and arr[m+1..r] are sorted and merges the two * sorted sub-arrays into one. * * @param arr[] is the array with two halves one is arr[l...m] and * other is arr[m+1...l] * @param l is the left index of first half array * @param m is the end index of right index of first half array - * + * * (The second array starts form m+1 and goes till l) - * + * * @param l is the end index of right index of second half array */ void merge(int arr[], int l, int m, int r) { @@ -94,7 +94,7 @@ void mergeSort(int arr[], int l, int r) { * sorting */ void show(int arr[], int size) { - for (int i = 0; i < size; i++) std::cout << arr[i] << " "; + for (int i = 0; i < size; i++) std::cout << arr[i] << " "; std::cout << "\n"; } @@ -108,9 +108,9 @@ int main() { for (int i = 0; i < size; ++i) { std::cin >> arr[i]; } - mergeSort(arr, 0, size-1); + mergeSort(arr, 0, size - 1); std::cout << "Sorted array : "; - show(arr, size-1); + show(arr, size - 1); delete[] arr; return 0; } From 0a09c1e382acef49ebbeaf1ad810e0455ea08206 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sat, 20 Jun 2020 21:05:19 +0530 Subject: [PATCH 063/261] fixed line spacing --- sorting/merge_sort.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index 716c7c64d..34600d06a 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -7,6 +7,7 @@ * * \author [Ayaan Khan] (http://github.com/ayaankhan98) * + * \details * Merge Sort is an efficient, general purpose, comparison * based sorting algorithm. * Merge Sort is a divide and conquer algorithm From 99ca279ff6555fd9ef25b1c87d710a3b3bb4300b Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sat, 20 Jun 2020 21:41:25 +0530 Subject: [PATCH 064/261] fixed documentation --- sorting/merge_sort.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index 34600d06a..fc6d66af5 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -1,11 +1,11 @@ /** * \addtogroup sorting Sorting Algorithms - * @file{ + * @{ * \file - * \breif [Merege Sort Algorithm + * \brief [Merege Sort Algorithm * (MEREGE SORT)](https://en.wikipedia.org/wiki/Merge_sort) implementation * - * \author [Ayaan Khan] (http://github.com/ayaankhan98) + * \author [Ayaan Khan](http://github.com/ayaankhan98) * * \details * Merge Sort is an efficient, general purpose, comparison @@ -22,16 +22,15 @@ * arr[l..m] and arr[m+1..r] are sorted and merges the two * sorted sub-arrays into one. * - * @param arr[] is the array with two halves one is arr[l...m] and - * other is arr[m+1...l] - * @param l is the left index of first half array - * @param m is the end index of right index of first half array + * @param arr - array with two halves arr[l...m] and arr[m+1...l] + * @param l - left index or start index of first half array + * @param m - right index or end index of first half array * * (The second array starts form m+1 and goes till l) * - * @param l is the end index of right index of second half array + * @param l - end index or right index of second half array */ -void merge(int arr[], int l, int m, int r) { +void merge(int *arr, int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m; @@ -76,12 +75,12 @@ void merge(int arr[], int l, int m, int r) { * input array into two halves and calls itself for the two halves * and then calls merge() to merge the two halves * - * @param arr[] the array which is to be sorted - * @param l define the left index of array - * @param r defines the right index of array + * @param arr - array to be sorted + * @param l - left index or start index of array + * @param r - right index or end index of array * */ -void mergeSort(int arr[], int l, int r) { +void mergeSort(int *arr, int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); @@ -91,10 +90,10 @@ void mergeSort(int arr[], int l, int r) { } /** - * A simple utility function used to print the array after + * Utility function used to print the array after * sorting */ -void show(int arr[], int size) { +void show(int *arr, int size) { for (int i = 0; i < size; i++) std::cout << arr[i] << " "; std::cout << "\n"; } From 4afe371ba535a837ac67c9a43fae094d5a6949c8 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sat, 20 Jun 2020 22:50:49 +0530 Subject: [PATCH 065/261] closed the paranthesis of line 3 --- sorting/merge_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index fc6d66af5..ce87c8b5c 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -114,4 +114,4 @@ int main() { delete[] arr; return 0; } -/** @} */ +/** @} */ From 5c77f1ebe0d8dcefaf472b90b7a5f3ffd82137c8 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 00:03:36 +0530 Subject: [PATCH 066/261] Bug Fix heap sort [Fresh Implementation] --- sorting/heap_sort.cpp | 110 ++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 69 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index ef9f87094..405e4641d 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -1,31 +1,31 @@ /** + * \addtogroup sorting Sorting Algorithm + * @{ * \file * \brief [Heap Sort Algorithm - * (heap sort)](https://en.wikipedia.org/wiki/Heapsort) implementation + * (HEAP SORT)](https://en.wikipedia.org/wiki/Heapsort) implementation * * \author [Ayaan Khan](http://github.com/ayaankhan98) * * \details - * Heap-sort is a comparison-based sorting algorithm. - * Heap-sort can be thought of as an improved selection sort: - * like selection sort, heap sort divides its input into a sorted - * and an unsorted region, and it iteratively shrinks the unsorted - * region by extracting the largest element from it and inserting - * it into the sorted region. Unlike selection sort, - * heap sort does not waste time with a linear-time scan of the - * unsorted region; rather, heap sort maintains the unsorted region - * in a heap data structure to more quickly find the largest element + * heapsort is a comparison-based sorting algorithm. + * Heapsort can be thought of as an improved selection sort: + * like selection sort, heapsort divides its input into a sorted + * and an unsorted region, and it iteratively shrinks the unsorted + * region by extracting the largest element from it and inserting + * it into the sorted region. Unlike selection sort, + * heapsort does not waste time with a linear-time scan of the + * unsorted region; rather, heap sort maintains the unsorted region + * in a heap data structure to more quickly find the largest element * in each step. - * - * Time Complexity - \f$O(n \log(n))\f$ + * + * Time Complexity - O(nlog(n)) * */ -#include -#include #include /** - * + * * Utility Lambda function to print the array after * sorting. * @@ -33,32 +33,25 @@ * @param sz size of array * */ -template -void printArray(T *arr, int sz) { - for (int i = 0; i < sz; i++) std::cout << arr[i] << " "; +auto printArray = [] (int *arr, int sz) { + for (int i = 0 ; i < sz ; i++) + std::cout << arr[i] <<" "; std::cout << "\n"; -} +}; /** * - * \addtogroup sorting Sorting Algorithm - * @{ - * - * The heapify procedure can be thought of as building a heap from - * the bottom up by successively sifting downward to establish the - * heap property. - * - * @param arr array to be sorted - * @param n size of array - * @param i node position in Binary Tress or element position in - * Array to be compared with it's childern - * + * The heapify procedure can be thought of as building a heap from + * the bottom up by successively sifting downward to establish the + * heap property. + * + * @param arr array be to sorted + * @param */ -template -void heapify(T *arr, int n, int i) { +void(*heapify)(int *arr, int n, int i) = [] (int *arr, int n, int i) { int largest = i; - int l = 2 * i + 1; - int r = 2 * i + 2; + int l = 2*i + 1; + int r = 2*i + 2; if (l < n && arr[l] > arr[largest]) largest = l; @@ -70,54 +63,33 @@ void heapify(T *arr, int n, int i) { std::swap(arr[i], arr[largest]); heapify(arr, n, largest); } -} +}; /** - * Utilizes heapify procedure to sort + * heapSort lambda function utilizes heapify procedure to sort * the array * * @param arr array to be sorted * @param n size of array * */ -template -void heapSort(T *arr, int n) { - for (int i = n - 1; i >= 0; i--) heapify(arr, n, i); +auto heapSort = [] (int *arr, int n) { + for (int i = n-1 ; i >= 0; i--) + heapify(arr, n, i); - for (int i = n - 1; i >= 0; i--) { + for (int i = n-1 ; i >= 0; i--) { std::swap(arr[0], arr[i]); heapify(arr, i, 0); } -} - -/** - * - * @} - * Test cases to test the program - * - */ -void test() { - std::cout << "Test 1\n"; - int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; - int sz = sizeof(arr) / sizeof(arr[0]); // sz - size of array - printArray(arr, sz); // displaying the array before sorting - heapSort(arr, sz); // calling heapsort to sort the array - printArray(arr, sz); // display array after sorting - assert(std::is_sorted(arr, arr + sz)); - std::cout << "Test 1 Passed\n========================\n"; - - std::cout << "Test 2\n"; - double arr2[] = {4.5, -3.6, 7.6, 0, 12.9}; - sz = sizeof(arr2) / sizeof(arr2[0]); - printArray(arr2, sz); - heapSort(arr2, sz); - printArray(arr2, sz); - assert(std::is_sorted(arr2, arr2 + sz)); - std::cout << "Test 2 passed\n"; -} +}; /** Main function */ int main() { - test(); + int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; + int sz = sizeof(arr) / sizeof(arr[0]); // sz - size of array + printArray(arr, sz); // displaying the array before sorting + heapSort(arr, sz); // calling heapsort to sort the array + printArray(arr, sz); // display array after sorting return 0; } +/** @} */ From 549daeebfdabef2e1732568d554e4cc9d5feb08f Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 20 Jun 2020 17:21:37 +0000 Subject: [PATCH 067/261] formatting source-code for 8233eda8894f46785f288e72c639d201852f6096 --- sorting/merge_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/merge_sort.cpp b/sorting/merge_sort.cpp index ce87c8b5c..fc6d66af5 100644 --- a/sorting/merge_sort.cpp +++ b/sorting/merge_sort.cpp @@ -114,4 +114,4 @@ int main() { delete[] arr; return 0; } -/** @} */ +/** @} */ From 38db7fdec0d7254cb559ac89a19fa884d5cd0052 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 00:06:04 +0530 Subject: [PATCH 068/261] Bug Fix heap sort [Fresh Implementation] --- sorting/heap_sort.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 405e4641d..09c4d3193 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -44,9 +44,7 @@ auto printArray = [] (int *arr, int sz) { * The heapify procedure can be thought of as building a heap from * the bottom up by successively sifting downward to establish the * heap property. - * - * @param arr array be to sorted - * @param + * */ void(*heapify)(int *arr, int n, int i) = [] (int *arr, int n, int i) { int largest = i; From 11728ee231858c31f4398633d69a48dc5b0bba22 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 20 Jun 2020 18:34:51 +0000 Subject: [PATCH 069/261] formatting source-code for e464ddac3688834ce46c59bada5ad3fddbfa2254 --- sorting/heap_sort.cpp | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 09c4d3193..ae50e1cfb 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -8,24 +8,24 @@ * \author [Ayaan Khan](http://github.com/ayaankhan98) * * \details - * heapsort is a comparison-based sorting algorithm. - * Heapsort can be thought of as an improved selection sort: - * like selection sort, heapsort divides its input into a sorted - * and an unsorted region, and it iteratively shrinks the unsorted - * region by extracting the largest element from it and inserting - * it into the sorted region. Unlike selection sort, - * heapsort does not waste time with a linear-time scan of the - * unsorted region; rather, heap sort maintains the unsorted region - * in a heap data structure to more quickly find the largest element + * heapsort is a comparison-based sorting algorithm. + * Heapsort can be thought of as an improved selection sort: + * like selection sort, heapsort divides its input into a sorted + * and an unsorted region, and it iteratively shrinks the unsorted + * region by extracting the largest element from it and inserting + * it into the sorted region. Unlike selection sort, + * heapsort does not waste time with a linear-time scan of the + * unsorted region; rather, heap sort maintains the unsorted region + * in a heap data structure to more quickly find the largest element * in each step. - * + * * Time Complexity - O(nlog(n)) * */ #include /** - * + * * Utility Lambda function to print the array after * sorting. * @@ -33,23 +33,24 @@ * @param sz size of array * */ -auto printArray = [] (int *arr, int sz) { - for (int i = 0 ; i < sz ; i++) - std::cout << arr[i] <<" "; +auto printArray = [](int *arr, int sz) { + for (int i = 0; i < sz; i++) std::cout << arr[i] << " "; std::cout << "\n"; }; /** * - * The heapify procedure can be thought of as building a heap from - * the bottom up by successively sifting downward to establish the - * heap property. - * + * The heapify procedure can be thought of as building a heap from + * the bottom up by successively sifting downward to establish the + * heap property. + * + * @param arr array be to sorted + * @param */ -void(*heapify)(int *arr, int n, int i) = [] (int *arr, int n, int i) { +void (*heapify)(int *arr, int n, int i) = [](int *arr, int n, int i) { int largest = i; - int l = 2*i + 1; - int r = 2*i + 2; + int l = 2 * i + 1; + int r = 2 * i + 2; if (l < n && arr[l] > arr[largest]) largest = l; @@ -71,11 +72,10 @@ void(*heapify)(int *arr, int n, int i) = [] (int *arr, int n, int i) { * @param n size of array * */ -auto heapSort = [] (int *arr, int n) { - for (int i = n-1 ; i >= 0; i--) - heapify(arr, n, i); +auto heapSort = [](int *arr, int n) { + for (int i = n - 1; i >= 0; i--) heapify(arr, n, i); - for (int i = n-1 ; i >= 0; i--) { + for (int i = n - 1; i >= 0; i--) { std::swap(arr[0], arr[i]); heapify(arr, i, 0); } @@ -86,7 +86,7 @@ int main() { int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; int sz = sizeof(arr) / sizeof(arr[0]); // sz - size of array printArray(arr, sz); // displaying the array before sorting - heapSort(arr, sz); // calling heapsort to sort the array + heapSort(arr, sz); // calling heapsort to sort the array printArray(arr, sz); // display array after sorting return 0; } From 86bd671c669c35b704162927401d2a7c98d3b57e Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 17:06:17 +0530 Subject: [PATCH 070/261] switched to normal functions from lambda --- sorting/heap_sort.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index ae50e1cfb..6cdb17f4a 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -33,10 +33,10 @@ * @param sz size of array * */ -auto printArray = [](int *arr, int sz) { +void printArray(int *arr, int sz) { for (int i = 0; i < sz; i++) std::cout << arr[i] << " "; std::cout << "\n"; -}; +} /** * @@ -44,10 +44,13 @@ auto printArray = [](int *arr, int sz) { * the bottom up by successively sifting downward to establish the * heap property. * - * @param arr array be to sorted - * @param + * @param arr array to be sorted + * @param n size of array + * @param i node position in Binary Tress or element position in + * Array to be compared with it's childern + * */ -void (*heapify)(int *arr, int n, int i) = [](int *arr, int n, int i) { +void heapify(int *arr, int n, int i) { int largest = i; int l = 2 * i + 1; int r = 2 * i + 2; @@ -62,7 +65,7 @@ void (*heapify)(int *arr, int n, int i) = [](int *arr, int n, int i) { std::swap(arr[i], arr[largest]); heapify(arr, n, largest); } -}; +} /** * heapSort lambda function utilizes heapify procedure to sort @@ -72,14 +75,14 @@ void (*heapify)(int *arr, int n, int i) = [](int *arr, int n, int i) { * @param n size of array * */ -auto heapSort = [](int *arr, int n) { +void heapSort(int *arr, int n) { for (int i = n - 1; i >= 0; i--) heapify(arr, n, i); for (int i = n - 1; i >= 0; i--) { std::swap(arr[0], arr[i]); heapify(arr, i, 0); } -}; +} /** Main function */ int main() { From 2a41d916b05681932021d4130f19af21097f385b Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 17:38:42 +0530 Subject: [PATCH 071/261] Added template and test cases --- sorting/heap_sort.cpp | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 6cdb17f4a..5eaded62a 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -23,6 +23,8 @@ * */ #include +#include +#include /** * @@ -33,7 +35,8 @@ * @param sz size of array * */ -void printArray(int *arr, int sz) { +template +void printArray(T *arr, int sz) { for (int i = 0; i < sz; i++) std::cout << arr[i] << " "; std::cout << "\n"; } @@ -50,7 +53,8 @@ void printArray(int *arr, int sz) { * Array to be compared with it's childern * */ -void heapify(int *arr, int n, int i) { +template +void heapify(T *arr, int n, int i) { int largest = i; int l = 2 * i + 1; int r = 2 * i + 2; @@ -75,7 +79,8 @@ void heapify(int *arr, int n, int i) { * @param n size of array * */ -void heapSort(int *arr, int n) { +template +void heapSort(T *arr, int n) { for (int i = n - 1; i >= 0; i--) heapify(arr, n, i); for (int i = n - 1; i >= 0; i--) { @@ -84,13 +89,27 @@ void heapSort(int *arr, int n) { } } -/** Main function */ -int main() { +void test() { + std::cout << "Test 1\n"; int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; int sz = sizeof(arr) / sizeof(arr[0]); // sz - size of array printArray(arr, sz); // displaying the array before sorting heapSort(arr, sz); // calling heapsort to sort the array printArray(arr, sz); // display array after sorting - return 0; + assert(std::is_sorted(arr, arr+sz)); + std::cout << "Test 1 Passed\n========================\n"; + std::cout << "Test 2\n"; + double arr2[] = {4.5, -3.6, 7.6, 0, 12.9}; + sz = sizeof(arr2) / sizeof(arr2[0]); + printArray(arr2, sz); + heapSort(arr2, sz); + printArray(arr2, sz); + assert(std::is_sorted(arr2, arr2+sz)); + std::cout << "Test 2 passed\n"; +} +/** Main function */ +int main() { + test(); + return 0; } /** @} */ From 6d88c992ed34db27b9f804e159a1a6e4cc9e59c1 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 21 Jun 2020 11:37:08 +0000 Subject: [PATCH 072/261] formatting source-code for ced5dcd6c4db53ece27d22ecd1dd1c1fcce6afb0 --- sorting/heap_sort.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 5eaded62a..42bfc43b2 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -48,8 +48,8 @@ void printArray(T *arr, int sz) { * heap property. * * @param arr array to be sorted - * @param n size of array - * @param i node position in Binary Tress or element position in + * @param n size of array + * @param i node position in Binary Tress or element position in * Array to be compared with it's childern * */ From 555f4fb98f1a2646c36683362e4f72a6e40c1740 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 17:41:39 +0530 Subject: [PATCH 073/261] fixed docs --- sorting/heap_sort.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 42bfc43b2..0945c9a92 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -89,6 +89,7 @@ void heapSort(T *arr, int n) { } } +/** Test cases to test the program */ void test() { std::cout << "Test 1\n"; int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; @@ -107,6 +108,7 @@ void test() { assert(std::is_sorted(arr2, arr2+sz)); std::cout << "Test 2 passed\n"; } + /** Main function */ int main() { test(); From a56e54ca15249a322d2dd98ab83652c20e0753f1 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:09:45 +0000 Subject: [PATCH 074/261] formatting source-code for 7c8617fa46d41481c68ae2ae9d4f6a89ca42a4ff --- sorting/heap_sort.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 0945c9a92..52edddf17 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -22,9 +22,9 @@ * Time Complexity - O(nlog(n)) * */ -#include #include #include +#include /** * @@ -97,7 +97,7 @@ void test() { printArray(arr, sz); // displaying the array before sorting heapSort(arr, sz); // calling heapsort to sort the array printArray(arr, sz); // display array after sorting - assert(std::is_sorted(arr, arr+sz)); + assert(std::is_sorted(arr, arr + sz)); std::cout << "Test 1 Passed\n========================\n"; std::cout << "Test 2\n"; double arr2[] = {4.5, -3.6, 7.6, 0, 12.9}; @@ -105,13 +105,13 @@ void test() { printArray(arr2, sz); heapSort(arr2, sz); printArray(arr2, sz); - assert(std::is_sorted(arr2, arr2+sz)); + assert(std::is_sorted(arr2, arr2 + sz)); std::cout << "Test 2 passed\n"; } /** Main function */ int main() { - test(); - return 0; + test(); + return 0; } /** @} */ From f0ab9a0d3870ab65b054503d77cdf5188d4fdeab Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 17:50:07 +0530 Subject: [PATCH 075/261] fixed line spacing in tests --- sorting/heap_sort.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 52edddf17..6445f0f32 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -99,6 +99,7 @@ void test() { printArray(arr, sz); // display array after sorting assert(std::is_sorted(arr, arr + sz)); std::cout << "Test 1 Passed\n========================\n"; + std::cout << "Test 2\n"; double arr2[] = {4.5, -3.6, 7.6, 0, 12.9}; sz = sizeof(arr2) / sizeof(arr2[0]); From 7f4077505567f3d8c8ea275c9c7b402111769653 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Sun, 21 Jun 2020 19:50:51 +0530 Subject: [PATCH 076/261] fix docs --- sorting/heap_sort.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index 6445f0f32..ef9f87094 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -1,25 +1,23 @@ /** - * \addtogroup sorting Sorting Algorithm - * @{ * \file * \brief [Heap Sort Algorithm - * (HEAP SORT)](https://en.wikipedia.org/wiki/Heapsort) implementation + * (heap sort)](https://en.wikipedia.org/wiki/Heapsort) implementation * * \author [Ayaan Khan](http://github.com/ayaankhan98) * * \details - * heapsort is a comparison-based sorting algorithm. - * Heapsort can be thought of as an improved selection sort: - * like selection sort, heapsort divides its input into a sorted + * Heap-sort is a comparison-based sorting algorithm. + * Heap-sort can be thought of as an improved selection sort: + * like selection sort, heap sort divides its input into a sorted * and an unsorted region, and it iteratively shrinks the unsorted * region by extracting the largest element from it and inserting * it into the sorted region. Unlike selection sort, - * heapsort does not waste time with a linear-time scan of the + * heap sort does not waste time with a linear-time scan of the * unsorted region; rather, heap sort maintains the unsorted region * in a heap data structure to more quickly find the largest element * in each step. * - * Time Complexity - O(nlog(n)) + * Time Complexity - \f$O(n \log(n))\f$ * */ #include @@ -42,6 +40,9 @@ void printArray(T *arr, int sz) { } /** + * + * \addtogroup sorting Sorting Algorithm + * @{ * * The heapify procedure can be thought of as building a heap from * the bottom up by successively sifting downward to establish the @@ -72,7 +73,7 @@ void heapify(T *arr, int n, int i) { } /** - * heapSort lambda function utilizes heapify procedure to sort + * Utilizes heapify procedure to sort * the array * * @param arr array to be sorted @@ -89,7 +90,12 @@ void heapSort(T *arr, int n) { } } -/** Test cases to test the program */ +/** + * + * @} + * Test cases to test the program + * + */ void test() { std::cout << "Test 1\n"; int arr[] = {-10, 78, -1, -6, 7, 4, 94, 5, 99, 0}; @@ -115,4 +121,3 @@ int main() { test(); return 0; } -/** @} */ From c344d8f6f155cca62c183327a0ccaa6e541a4bea Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Tue, 23 Jun 2020 22:58:44 +0530 Subject: [PATCH 077/261] Multiplication result may overflow 'int' before it is converted to 'long'. --- math/primes_up_to_billion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/primes_up_to_billion.cpp b/math/primes_up_to_billion.cpp index b7377cea5..af6d34ff3 100644 --- a/math/primes_up_to_billion.cpp +++ b/math/primes_up_to_billion.cpp @@ -14,9 +14,9 @@ void Sieve(int64_t n) { memset(prime, '1', sizeof(prime)); // intitize '1' to every index prime[0] = '0'; // 0 is not prime prime[1] = '0'; // 1 is not prime - for (int64_t p = 2; p * p <= n; p++) { + for (long p = 2; p * p <= n; p++) { if (prime[p] == '1') { - for (int64_t i = p * p; i <= n; i += p) + for (long i = p * p; i <= n; i += p) prime[i] = '0'; // set all multiples of p to false } } From fa92a18c2e777da1b0361415d16e0fd88ae115bd Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Tue, 23 Jun 2020 23:28:13 +0530 Subject: [PATCH 078/261] fixed cpplint long -> int64 --- math/primes_up_to_billion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/primes_up_to_billion.cpp b/math/primes_up_to_billion.cpp index af6d34ff3..f13a8312b 100644 --- a/math/primes_up_to_billion.cpp +++ b/math/primes_up_to_billion.cpp @@ -14,9 +14,9 @@ void Sieve(int64_t n) { memset(prime, '1', sizeof(prime)); // intitize '1' to every index prime[0] = '0'; // 0 is not prime prime[1] = '0'; // 1 is not prime - for (long p = 2; p * p <= n; p++) { + for (int64 p = 2; p * p <= n; p++) { if (prime[p] == '1') { - for (long i = p * p; i <= n; i += p) + for (int64 i = p * p; i <= n; i += p) prime[i] = '0'; // set all multiples of p to false } } From 886cb520f02f8f358ff6247b3262b822b8c6b300 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Tue, 23 Jun 2020 23:36:14 +0530 Subject: [PATCH 079/261] fixed compiler error --- math/primes_up_to_billion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/primes_up_to_billion.cpp b/math/primes_up_to_billion.cpp index f13a8312b..b7377cea5 100644 --- a/math/primes_up_to_billion.cpp +++ b/math/primes_up_to_billion.cpp @@ -14,9 +14,9 @@ void Sieve(int64_t n) { memset(prime, '1', sizeof(prime)); // intitize '1' to every index prime[0] = '0'; // 0 is not prime prime[1] = '0'; // 1 is not prime - for (int64 p = 2; p * p <= n; p++) { + for (int64_t p = 2; p * p <= n; p++) { if (prime[p] == '1') { - for (int64 i = p * p; i <= n; i += p) + for (int64_t i = p * p; i <= n; i += p) prime[i] = '0'; // set all multiples of p to false } } From 8252816dcc6799c14fb40c6f6bf206013be3add0 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 00:12:36 +0530 Subject: [PATCH 080/261] fixed Code quality and added docs --- data_structures/disjoint_set.cpp | 62 +++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/data_structures/disjoint_set.cpp b/data_structures/disjoint_set.cpp index dd70e4cea..b7bcf3c58 100644 --- a/data_structures/disjoint_set.cpp +++ b/data_structures/disjoint_set.cpp @@ -1,3 +1,24 @@ +/** + * + * \file + * \brief [Disjoint Sets Data Structure + * (Disjoint Sets)](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) + * + * \author + * + * \details + * A disjoint set data structure (also called union find or merge find set) + * is a data structure that tracks a set of elements partitioned into a number + * of disjoint (non-overlapping) subsets. + * Some situations where disjoint sets can be used are- + * to find connected components of a graph, kruskal's algorithm for finding + * Minimum Spanning Tree etc. + * There are two operation which we perform on disjoint sets - + * 1) Union + * 2) Find + * + */ + #include #include @@ -5,16 +26,30 @@ using std::cout; using std::endl; using std::vector; -vector root, rnk; +vector root, rank; +/** + * + * Function to create a set + * @param n number of element + * + */ void CreateSet(int n) { root = vector(n + 1); - rnk = vector(n + 1, 1); + rank = vector(n + 1, 1); for (int i = 1; i <= n; ++i) { root[i] = i; } } +/** + * + * Find operation takes a number x and returns the set to which this number + * belongs to. + * @param x element of some set + * @return set to which x belongs to + * + */ int Find(int x) { if (root[x] == x) { return x; @@ -22,22 +57,39 @@ int Find(int x) { return root[x] = Find(root[x]); } +/** + * + * A utility function to check if x and y are from same set or not + * @param x element of some set + * @param y element of some set + * + */ bool InSameUnion(int x, int y) { return Find(x) == Find(y); } +/** + * + * Union operation combines two disjoint sets to make a single set + * in this union function we pass two elements and check if they are + * from different sets then combine those sets + * @param x element of some set + * @param y element of some set + * + */ void Union(int x, int y) { int a = Find(x), b = Find(y); if (a != b) { - if (rnk[a] < rnk[b]) { + if (rank[a] < rank[b]) { root[a] = b; - } else if (rnk[a] > rnk[b]) { + } else if (rank[a] > rank[b]) { root[b] = a; } else { root[a] = b; - ++rnk[b]; + ++rank[b]; } } } +/** Main function */ int main() { // tests CreateSet & Find int n = 100; From 866c23e19e733884a790de28c251c4c580bf2dc3 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 00:25:52 +0530 Subject: [PATCH 081/261] Added author name --- data_structures/disjoint_set.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/disjoint_set.cpp b/data_structures/disjoint_set.cpp index b7bcf3c58..eebb650bf 100644 --- a/data_structures/disjoint_set.cpp +++ b/data_structures/disjoint_set.cpp @@ -4,7 +4,7 @@ * \brief [Disjoint Sets Data Structure * (Disjoint Sets)](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) * - * \author + * \author [leoyang429](https://github.com/leoyang429) * * \details * A disjoint set data structure (also called union find or merge find set) From 2802dca89557750840cb89b988ce83934091e2d3 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 18:43:35 +0000 Subject: [PATCH 082/261] formatting source-code for a887dc59ed8e790d479773e0ce5e24c6db110afb --- data_structures/disjoint_set.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/disjoint_set.cpp b/data_structures/disjoint_set.cpp index eebb650bf..bd4599603 100644 --- a/data_structures/disjoint_set.cpp +++ b/data_structures/disjoint_set.cpp @@ -28,8 +28,8 @@ using std::vector; vector root, rank; -/** - * +/** + * * Function to create a set * @param n number of element * @@ -57,7 +57,7 @@ int Find(int x) { return root[x] = Find(root[x]); } -/** +/** * * A utility function to check if x and y are from same set or not * @param x element of some set From 91c9c96cf486331bbe00f206b5391911d438001a Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 00:57:31 +0530 Subject: [PATCH 083/261] code quality fix deallocate resorces --- data_structures/binaryheap.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/data_structures/binaryheap.cpp b/data_structures/binaryheap.cpp index 72e56e91a..2396f2e51 100644 --- a/data_structures/binaryheap.cpp +++ b/data_structures/binaryheap.cpp @@ -13,10 +13,14 @@ class MinHeap { int heap_size; ///< Current number of elements in min heap public: - /** Constructor + /** Constructor: Builds a heap from a given array a[] of given size * \param[in] capacity initial heap capacity */ - MinHeap(int capacity); + explicit MinHeap(int cap) { + heap_size = 0; + capacity = cap; + harr = new int[cap]; + } /** to heapify a subtree with the root at given index */ @@ -44,14 +48,12 @@ class MinHeap { /** Inserts a new key 'k' */ void insertKey(int k); + + ~MinHeap() { + delete [] harr; + } }; -/** Constructor: Builds a heap from a given array a[] of given size */ -MinHeap::MinHeap(int cap) { - heap_size = 0; - capacity = cap; - harr = new int[cap]; -} // Inserts a new key 'k' void MinHeap::insertKey(int k) { From 6882b545c75136f82b5294eda0a2333b6c03ca16 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:29:12 +0000 Subject: [PATCH 084/261] formatting source-code for 91c9c96cf486331bbe00f206b5391911d438001a --- data_structures/binaryheap.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/data_structures/binaryheap.cpp b/data_structures/binaryheap.cpp index 2396f2e51..c3a1f5cf6 100644 --- a/data_structures/binaryheap.cpp +++ b/data_structures/binaryheap.cpp @@ -13,13 +13,13 @@ class MinHeap { int heap_size; ///< Current number of elements in min heap public: - /** Constructor: Builds a heap from a given array a[] of given size + /** Constructor: Builds a heap from a given array a[] of given size * \param[in] capacity initial heap capacity */ explicit MinHeap(int cap) { - heap_size = 0; - capacity = cap; - harr = new int[cap]; + heap_size = 0; + capacity = cap; + harr = new int[cap]; } /** to heapify a subtree with the root at given index @@ -49,12 +49,9 @@ class MinHeap { /** Inserts a new key 'k' */ void insertKey(int k); - ~MinHeap() { - delete [] harr; - } + ~MinHeap() { delete[] harr; } }; - // Inserts a new key 'k' void MinHeap::insertKey(int k) { if (heap_size == capacity) { From 1d7a73ea583c27eaa39ed90793db698e6997b6a7 Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Wed, 24 Jun 2020 01:03:42 +0530 Subject: [PATCH 085/261] feat: add check_amicable_pair.cpp (#879) * feat: add check_amicable_pair.cpp * fix: space between else and brace. * fix: spaces between tokens * fix: removed sqrt and test func combined to single * docs: removed wiki link Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: add markdown syntax for wikipedia link Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: change brief to details in comment Line 7 Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: typo fixed Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: removed extra line Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: removed copyright Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * docs: add author name Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * fix: shortened the code in is_amicable() Co-authored-by: David Leal * fix: changed is_amicable to are_amicable * docs: cleared unwanted line Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: David Leal --- math/check_amicable_pair.cpp | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 math/check_amicable_pair.cpp diff --git a/math/check_amicable_pair.cpp b/math/check_amicable_pair.cpp new file mode 100644 index 000000000..83a5d7364 --- /dev/null +++ b/math/check_amicable_pair.cpp @@ -0,0 +1,70 @@ +/** + * + * @file + * \brief A C++ Program to check whether a pair of number is [amicable pair](https://en.wikipedia.org/wiki/Amicable_numbers) or not. + * + * \details + * Amicable Pair are two positive integers such that sum of the proper divisor + * of each number is equal to the other number. + * @author iamnambiar + */ +#include +#include + +/** + * Function to calculate the sum of all the proper divisor + * of an integer. + * @param num First number. + * @return Sum of the proper divisor of the number. + */ +int sum_of_divisor(int num) { + // Variable to store the sum of all proper divisors. + int sum = 0; + // Below loop condition helps to reduce Time complexity by a factor of square root of the number. + for (int div = 2; div * div <= num; ++div) { + // Check 'div' is divisor of 'num'. + if (num % div == 0) { + // If both divisor are same, add once to 'sum' + if (div == (num / div)) { + sum += div; + } else { + // If both divisor are not the same, add both to 'sum'. + sum += (div + (num / div)); + } + } + } + return sum + 1; +} + +/** + * Function to check whether the pair is amicable or not. + * @param x First number. + * @param y Second number. + * @return `true` if the pair is amicable + * @return `false` if the pair is not amicable + */ +bool are_amicable(int x, int y) { + return (sum_of_divisor(x) == y) && (sum_of_divisor(y) == x); +} + +/** + * Function for testing the is_amicable() with + * all the test cases. + */ +void test() { + // are_amicable(220, 284) returns true. + assert(are_amicable(220, 284) == true); + // are_amicable(6232, 6368) returns true. + assert(are_amicable(6368, 6232) == true); + // are_amicable(458, 232) returns false. + assert(are_amicable(458, 232) == false); +} + +/** + * Main Function +*/ +int main() { + test(); + std::cout << "Assertion Success." << std::endl; + return 0; +} From 2d4a1dd19fd6835c63bb533aedcf3ab807fa889a Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:34:19 +0000 Subject: [PATCH 086/261] formatting source-code for 1d7a73ea583c27eaa39ed90793db698e6997b6a7 --- math/check_amicable_pair.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/math/check_amicable_pair.cpp b/math/check_amicable_pair.cpp index 83a5d7364..4f1255d19 100644 --- a/math/check_amicable_pair.cpp +++ b/math/check_amicable_pair.cpp @@ -1,18 +1,19 @@ /** - * + * * @file - * \brief A C++ Program to check whether a pair of number is [amicable pair](https://en.wikipedia.org/wiki/Amicable_numbers) or not. - * + * \brief A C++ Program to check whether a pair of number is [amicable + * pair](https://en.wikipedia.org/wiki/Amicable_numbers) or not. + * * \details - * Amicable Pair are two positive integers such that sum of the proper divisor + * Amicable Pair are two positive integers such that sum of the proper divisor * of each number is equal to the other number. * @author iamnambiar */ -#include #include +#include /** - * Function to calculate the sum of all the proper divisor + * Function to calculate the sum of all the proper divisor * of an integer. * @param num First number. * @return Sum of the proper divisor of the number. @@ -20,7 +21,8 @@ int sum_of_divisor(int num) { // Variable to store the sum of all proper divisors. int sum = 0; - // Below loop condition helps to reduce Time complexity by a factor of square root of the number. + // Below loop condition helps to reduce Time complexity by a factor of + // square root of the number. for (int div = 2; div * div <= num; ++div) { // Check 'div' is divisor of 'num'. if (num % div == 0) { @@ -48,7 +50,7 @@ bool are_amicable(int x, int y) { } /** - * Function for testing the is_amicable() with + * Function for testing the is_amicable() with * all the test cases. */ void test() { @@ -62,7 +64,7 @@ void test() { /** * Main Function -*/ + */ int main() { test(); std::cout << "Assertion Success." << std::endl; From 26ffe8c6d7c30220b05af8071a3bbd0c4c6afb35 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 19:34:19 +0000 Subject: [PATCH 087/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index eb75ce3e5..6e43ba3f2 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -101,6 +101,7 @@ ## Math * [Binary Exponent](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/binary_exponent.cpp) + * [Check Amicable Pair](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_amicable_pair.cpp) * [Check Prime](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_prime.cpp) * [Complex Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/complex_numbers.cpp) * [Double Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/double_factorial.cpp) From 2d0325699f9a832175dd376b66281bf284261c73 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 01:30:14 +0530 Subject: [PATCH 088/261] fixed code quality and added docs --- sorting/comb_sort.cpp | 83 ++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index 1b0a4d706..7e62c04ff 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -1,49 +1,82 @@ -// Kind of better version of Bubble sort. -// While Bubble sort is comparering adjacent value, Combsort is using gap larger -// than 1 Best case: O(n) Worst case: O(n ^ 2) +/** + * + * \file + * \brief [Comb Sort Algorithm + * (Comb Sort)](https://en.wikipedia.org/wiki/Comb_sort) + * + * \author + * + * \details + * - A better version of bubble sort algorithm + * - Bubble sort compares adjacent values whereas comb sort uses gap larger + * than 1 + * - Best case Time complexity O(n) + * Worst case Time complexity O(n^2) + * + */ #include #include -int a[100005]; -int n; +/** + * + * Find the next gap by shrinking the current gap by shrink factor of 1.3 + * @param gap current gap + * @return new gap + * + */ +int FindNextGap(int gap) { + gap = (gap * 10) / 13; -int FindNextGap(int x) { - x = (x * 10) / 13; - - return std::max(1, x); + return std::max(1, gap); } -void CombSort(int a[], int l, int r) { - // Init gap - int gap = n; +/** Function to sort array + * + * @param arr array to be sorted + * @param l start index of array + * @param r end index of array + * + */ +void CombSort(int *arr, int l, int r) { + /** + * + * initial gap will be maximum and the maximum possible value is + * the size of the array that is n and which is equal to r in this + * case so to avoid passing an extra parameter n that is the size of + * the array we are using r to initialize the initial gap. + * + */ + int gap = r; - // Initialize swapped as true to make sure that loop runs + /// Initialize swapped as true to make sure that loop runs bool swapped = true; - // Keep running until gap = 1 or none elements were swapped + /// Keep running until gap = 1 or none elements were swapped while (gap != 1 || swapped) { - // Find next gap + /// Find next gap gap = FindNextGap(gap); swapped = false; - // Compare all elements with current gap + /// Compare all elements with current gap for (int i = l; i <= r - gap; ++i) { - if (a[i] > a[i + gap]) { - std::swap(a[i], a[i + gap]); + if (arr[i] > arr[i + gap]) { + std::swap(arr[i], arr[i + gap]); swapped = true; } } } } +/** Main function */ int main() { - std::cin >> n; - for (int i = 1; i <= n; ++i) std::cin >> a[i]; - - CombSort(a, 1, n); - - for (int i = 1; i <= n; ++i) std::cout << a[i] << ' '; - return 0; + int n; + std::cin >> n; + int *arr = new int[n]; + for (int i = 0; i < n; ++i) std::cin >> arr[i]; + CombSort(arr, 0, n); + for (int i = 0; i < n; ++i) std::cout << arr[i] << ' '; + delete [] arr; + return 0; } From 33b5033adcb1e5551dfd3c6ca33ffe597316301b Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:01:26 +0000 Subject: [PATCH 089/261] formatting source-code for f030a69288662f1d282a9d724501990830c5bda7 --- sorting/comb_sort.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index 7e62c04ff..d44269814 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -71,12 +71,12 @@ void CombSort(int *arr, int l, int r) { /** Main function */ int main() { - int n; - std::cin >> n; - int *arr = new int[n]; - for (int i = 0; i < n; ++i) std::cin >> arr[i]; - CombSort(arr, 0, n); - for (int i = 0; i < n; ++i) std::cout << arr[i] << ' '; - delete [] arr; - return 0; + int n; + std::cin >> n; + int *arr = new int[n]; + for (int i = 0; i < n; ++i) std::cin >> arr[i]; + CombSort(arr, 0, n); + for (int i = 0; i < n; ++i) std::cout << arr[i] << ' '; + delete[] arr; + return 0; } From 0356a9cdf30b0f3ecdf5632e73e9f8a00a924253 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 14:35:13 -0500 Subject: [PATCH 090/261] fix: Various LGTM fixes --- data_structures/binary_search_tree.cpp | 12 ++++++------ math/realtime_stats.cpp | 2 +- sorting/bead_sort.cpp | 2 +- sorting/comb_sort.cpp | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/data_structures/binary_search_tree.cpp b/data_structures/binary_search_tree.cpp index 3cc7d09fb..86057c6c5 100644 --- a/data_structures/binary_search_tree.cpp +++ b/data_structures/binary_search_tree.cpp @@ -14,17 +14,17 @@ struct node { node *right; }; -struct queue { +struct Queue { node *t[100]; int front; int rear; }; -queue q; +Queue queue; -void enqueue(node *n) { q.t[q.rear++] = n; } +void enqueue(node *n) { queue.t[queue.rear++] = n; } -node *dequeue() { return (q.t[q.front++]); } +node *dequeue() { return (queue.t[queue.front++]); } void Insert(node *n, int x) { if (x < n->val) { @@ -123,8 +123,8 @@ void Post(node *n) { } int main() { - q.front = 0; - q.rear = 0; + queue.front = 0; + queue.rear = 0; int value; int ch; node *root = new node; diff --git a/math/realtime_stats.cpp b/math/realtime_stats.cpp index 5f353ac4d..672acfa03 100644 --- a/math/realtime_stats.cpp +++ b/math/realtime_stats.cpp @@ -35,7 +35,7 @@ class stats_computer1 { n++; T tmp = x - K; Ex += tmp; - Ex2 += tmp * tmp; + Ex2 += static_cast(tmp) * tmp; } /** return sample mean computed till last sample */ diff --git a/sorting/bead_sort.cpp b/sorting/bead_sort.cpp index f3276bfcd..4745987d9 100644 --- a/sorting/bead_sort.cpp +++ b/sorting/bead_sort.cpp @@ -14,7 +14,7 @@ void beadSort(int *a, int len) { // allocating memory unsigned char *beads = new unsigned char[max * len]; - memset(beads, 0, max * len); + memset(beads, 0, static_cast(max) * len); // mark the beads for (int i = 0; i < len; i++) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index 1b0a4d706..ab0b456dd 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -14,7 +14,7 @@ int FindNextGap(int x) { return std::max(1, x); } -void CombSort(int a[], int l, int r) { +void CombSort(int b[], int l, int r) { // Init gap int gap = n; @@ -30,8 +30,8 @@ void CombSort(int a[], int l, int r) { // Compare all elements with current gap for (int i = l; i <= r - gap; ++i) { - if (a[i] > a[i + gap]) { - std::swap(a[i], a[i + gap]); + if (b[i] > b[i + gap]) { + std::swap(b[i], b[i + gap]); swapped = true; } } From 92d2bf012ab4687bb973cc52d146740bf72ef9a3 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 01:49:33 +0530 Subject: [PATCH 091/261] Added tests for comb_sort.cpp --- sorting/comb_sort.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index 7e62c04ff..00b12fcb2 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -17,6 +17,7 @@ #include #include +#include /** * @@ -69,8 +70,26 @@ void CombSort(int *arr, int l, int r) { } } +void tests() { + /// Test 1 + int arr1[10] = {34, 56, 6, 23, 76, 34, 76, 343, 4, 76}; + CombSort(arr1, 0, 10); + assert(std::is_sorted(arr1, arr1 + 10)); + std::cout << "Test 1 passed\n"; + + /// Test 2 + int arr2[8] = {-6, 56, -45, 56, 0, -1, 8, 8}; + CombSort(arr2, 0, 8); + assert(std::is_sorted(arr2, arr2 + 8)); + std::cout << "Test 2 Passed\n"; +} + /** Main function */ int main() { + /// Running predefined tests + tests(); + + /// For user interaction int n; std::cin >> n; int *arr = new int[n]; From 48a163e51ab53a73c9edbb02633e6a3673865cea Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 23 Jun 2020 20:22:30 +0000 Subject: [PATCH 092/261] formatting source-code for 3a7a266ada62816c9602bfd9d5b632b80a169617 --- sorting/comb_sort.cpp | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index 00b12fcb2..e99ae9514 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -16,8 +16,8 @@ */ #include -#include #include +#include /** * @@ -71,31 +71,31 @@ void CombSort(int *arr, int l, int r) { } void tests() { - /// Test 1 - int arr1[10] = {34, 56, 6, 23, 76, 34, 76, 343, 4, 76}; - CombSort(arr1, 0, 10); - assert(std::is_sorted(arr1, arr1 + 10)); - std::cout << "Test 1 passed\n"; + /// Test 1 + int arr1[10] = {34, 56, 6, 23, 76, 34, 76, 343, 4, 76}; + CombSort(arr1, 0, 10); + assert(std::is_sorted(arr1, arr1 + 10)); + std::cout << "Test 1 passed\n"; - /// Test 2 - int arr2[8] = {-6, 56, -45, 56, 0, -1, 8, 8}; - CombSort(arr2, 0, 8); - assert(std::is_sorted(arr2, arr2 + 8)); - std::cout << "Test 2 Passed\n"; + /// Test 2 + int arr2[8] = {-6, 56, -45, 56, 0, -1, 8, 8}; + CombSort(arr2, 0, 8); + assert(std::is_sorted(arr2, arr2 + 8)); + std::cout << "Test 2 Passed\n"; } /** Main function */ int main() { - /// Running predefined tests - tests(); + /// Running predefined tests + tests(); - /// For user interaction - int n; - std::cin >> n; - int *arr = new int[n]; - for (int i = 0; i < n; ++i) std::cin >> arr[i]; - CombSort(arr, 0, n); - for (int i = 0; i < n; ++i) std::cout << arr[i] << ' '; - delete [] arr; - return 0; + /// For user interaction + int n; + std::cin >> n; + int *arr = new int[n]; + for (int i = 0; i < n; ++i) std::cin >> arr[i]; + CombSort(arr, 0, n); + for (int i = 0; i < n; ++i) std::cout << arr[i] << ' '; + delete[] arr; + return 0; } From 0767af4a0d20f22c9bb22e569aa9d24ea5a09f5a Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 15:26:55 -0500 Subject: [PATCH 093/261] fix: Revert `comb_sort` changes --- sorting/comb_sort.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sorting/comb_sort.cpp b/sorting/comb_sort.cpp index ab0b456dd..1b0a4d706 100644 --- a/sorting/comb_sort.cpp +++ b/sorting/comb_sort.cpp @@ -14,7 +14,7 @@ int FindNextGap(int x) { return std::max(1, x); } -void CombSort(int b[], int l, int r) { +void CombSort(int a[], int l, int r) { // Init gap int gap = n; @@ -30,8 +30,8 @@ void CombSort(int b[], int l, int r) { // Compare all elements with current gap for (int i = l; i <= r - gap; ++i) { - if (b[i] > b[i + gap]) { - std::swap(b[i], b[i + gap]); + if (a[i] > a[i + gap]) { + std::swap(a[i], a[i + gap]); swapped = true; } } From 2464d438f9a3a579fd3ed97589d4ccb9c353c509 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 02:06:52 +0530 Subject: [PATCH 094/261] deleted line 27 --- data_structures/binaryheap.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/binaryheap.cpp b/data_structures/binaryheap.cpp index c3a1f5cf6..21da4845b 100644 --- a/data_structures/binaryheap.cpp +++ b/data_structures/binaryheap.cpp @@ -24,7 +24,6 @@ class MinHeap { /** to heapify a subtree with the root at given index */ - void MinHeapify(int); int parent(int i) { return (i - 1) / 2; } From 62aafd1c5079260b649e6cae5f8133d9e8287b36 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 24 Jun 2020 02:22:20 +0530 Subject: [PATCH 095/261] reverted line 27 --- data_structures/binaryheap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/binaryheap.cpp b/data_structures/binaryheap.cpp index 21da4845b..483bd7c02 100644 --- a/data_structures/binaryheap.cpp +++ b/data_structures/binaryheap.cpp @@ -22,8 +22,8 @@ class MinHeap { harr = new int[cap]; } - /** to heapify a subtree with the root at given index - */ + /** to heapify a subtree with the root at given index */ + void MinHeapify(int); int parent(int i) { return (i - 1) / 2; } From 48b7773b37fe13792eed229e12aa54bec7d1ce5a Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 16:34:53 -0500 Subject: [PATCH 096/261] fix: Various LGTM fixes --- data_structures/stack_using_array.cpp | 14 +++++++------- data_structures/stack_using_linked_list.cpp | 14 +++++++------- math/fibonacci_fast.cpp | 12 ++++++------ others/paranthesis_matching.cpp | 10 +++++----- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/data_structures/stack_using_array.cpp b/data_structures/stack_using_array.cpp index 36be9eb39..ab2d7d7dd 100644 --- a/data_structures/stack_using_array.cpp +++ b/data_structures/stack_using_array.cpp @@ -1,31 +1,31 @@ #include int *stack; -int top = 0, stack_size; +int top_var = 0, stack_size; void push(int x) { - if (top == stack_size) { + if (top_var == stack_size) { std::cout << "\nOverflow"; } else { - stack[top++] = x; + stack[top_var++] = x; } } void pop() { - if (top == 0) { + if (top_var == 0) { std::cout << "\nUnderflow"; } else { - std::cout << "\n" << stack[--top] << " deleted"; + std::cout << "\n" << stack[--top_var] << " deleted"; } } void show() { - for (int i = 0; i < top; i++) { + for (int i = 0; i < top_var; i++) { std::cout << stack[i] << "\n"; } } -void topmost() { std::cout << "\nTopmost element: " << stack[top - 1]; } +void topmost() { std::cout << "\nTopmost element: " << stack[top_var - 1]; } int main() { std::cout << "\nEnter stack_size of stack : "; std::cin >> stack_size; diff --git a/data_structures/stack_using_linked_list.cpp b/data_structures/stack_using_linked_list.cpp index ae53fe95a..05f0d3d6a 100644 --- a/data_structures/stack_using_linked_list.cpp +++ b/data_structures/stack_using_linked_list.cpp @@ -6,28 +6,28 @@ struct node { node *next; }; -node *top; +node *top_var; void push(int x) { node *n = new node; n->val = x; - n->next = top; - top = n; + n->next = top_var; + top_var = n; } void pop() { - if (top == NULL) { + if (top_var == NULL) { cout << "\nUnderflow"; } else { - node *t = top; + node *t = top_var; cout << "\n" << t->val << " deleted"; - top = top->next; + top_var = top_var->next; delete t; } } void show() { - node *t = top; + node *t = top_var; while (t != NULL) { cout << t->val << "\n"; t = t->next; diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index 8fdb20058..80e9108ea 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -24,23 +24,23 @@ const uint64_t MAX = 93; /** Array of computed fibonacci numbers */ -uint64_t f[MAX] = {0}; +uint64_t numbers[MAX] = {0}; /** Algorithm */ uint64_t fib(uint64_t n) { if (n == 0) return 0; if (n == 1 || n == 2) - return (f[n] = 1); + return (numbers[n] = 1); - if (f[n]) - return f[n]; + if (numbers[n]) + return numbers[n]; uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2; - f[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1)) + numbers[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1)) : (2 * fib(k - 1) + fib(k)) * fib(k); - return f[n]; + return numbers[n]; } /** Main function */ diff --git a/others/paranthesis_matching.cpp b/others/paranthesis_matching.cpp index 2a6358d94..0a1a9e474 100644 --- a/others/paranthesis_matching.cpp +++ b/others/paranthesis_matching.cpp @@ -20,13 +20,13 @@ char stack[MAX]; //! pointer to track stack index -int top = -1; +int top_var = -1; //! push byte to stack variable -void push(char ch) { stack[++top] = ch; } +void push(char ch) { stack[++top_var] = ch; } //! pop a byte out of stack variable -char pop() { return stack[top--]; } +char pop() { return stack[top_var--]; } //! @}-------------- end stack ----------- @@ -56,7 +56,7 @@ int main() { while (valid == 1 && i < exp.length()) { if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[' || exp[i] == '<') { push(exp[i]); - } else if (top >= 0 && stack[top] == opening(exp[i])) { + } else if (top_var >= 0 && stack[top_var] == opening(exp[i])) { pop(); } else { valid = 0; @@ -65,7 +65,7 @@ int main() { } // makes sure the stack is empty after processsing (above) - if (valid == 1 && top == -1) { + if (valid == 1 && top_var == -1) { std::cout << "\nCorrect Expression"; } else { std::cout << "\nWrong Expression"; From cdacbf1998fd060c08897c687f8f695ff27559fa Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 16:37:46 -0500 Subject: [PATCH 097/261] fix: Remove namespace --- data_structures/stack_using_linked_list.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/data_structures/stack_using_linked_list.cpp b/data_structures/stack_using_linked_list.cpp index 05f0d3d6a..3dcf03f8a 100644 --- a/data_structures/stack_using_linked_list.cpp +++ b/data_structures/stack_using_linked_list.cpp @@ -1,5 +1,4 @@ #include -using namespace std; struct node { int val; @@ -17,10 +16,10 @@ void push(int x) { void pop() { if (top_var == NULL) { - cout << "\nUnderflow"; + std::cout << "\nUnderflow"; } else { node *t = top_var; - cout << "\n" << t->val << " deleted"; + std::cout << "\n" << t->val << " deleted"; top_var = top_var->next; delete t; } @@ -29,7 +28,7 @@ void pop() { void show() { node *t = top_var; while (t != NULL) { - cout << t->val << "\n"; + std::cout << t->val << "\n"; t = t->next; } } @@ -37,14 +36,14 @@ void show() { int main() { int ch, x; do { - cout << "\n1. Push"; - cout << "\n2. Pop"; - cout << "\n3. Print"; - cout << "\nEnter Your Choice : "; - cin >> ch; + std::cout << "\n1. Push"; + std::cout << "\n2. Pop"; + std::cout << "\n3. Print"; + std::cout << "\nEnter Your Choice : "; + std::cin >> ch; if (ch == 1) { - cout << "\nInsert : "; - cin >> x; + std::cout << "\nInsert : "; + std::cin >> x; push(x); } else if (ch == 2) { pop(); From a6c3667f308cc27c3b97beafe0123885d38114a2 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 17:38:17 -0500 Subject: [PATCH 098/261] fix: Release allocated memory --- data_structures/stack_using_array.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/stack_using_array.cpp b/data_structures/stack_using_array.cpp index ab2d7d7dd..6702f2d59 100644 --- a/data_structures/stack_using_array.cpp +++ b/data_structures/stack_using_array.cpp @@ -51,5 +51,7 @@ int main() { } } while (ch != 0); + delete stack; + return 0; } From 957a05bd0cd7e21017e13f57be3998ae1cdd7b73 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 17:39:29 -0500 Subject: [PATCH 099/261] fix: Convert global variables to local --- math/fibonacci_fast.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index 80e9108ea..dba8b9dc0 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -19,15 +19,15 @@ #include #include -/** maximum number that can be computed - The result after 93 cannot be stored - * in a `uint64_t` data type. */ -const uint64_t MAX = 93; - -/** Array of computed fibonacci numbers */ -uint64_t numbers[MAX] = {0}; - /** Algorithm */ uint64_t fib(uint64_t n) { + // maximum number that can be computed - The result after 93 cannot be stored + // in a `uint64_t` data type. + static const uint64_t MAX = 93; + + // Array of computed fibonacci numbers */ + static uint64_t numbers[MAX] = {0}; + if (n == 0) return 0; if (n == 1 || n == 2) From cea644bdc31710e1544623934e8ca8646fc9a97d Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 17:52:04 -0500 Subject: [PATCH 100/261] fix: Use delete[] operator --- data_structures/stack_using_array.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/stack_using_array.cpp b/data_structures/stack_using_array.cpp index 6702f2d59..b78e08e37 100644 --- a/data_structures/stack_using_array.cpp +++ b/data_structures/stack_using_array.cpp @@ -51,7 +51,7 @@ int main() { } } while (ch != 0); - delete stack; + delete[] stack; return 0; } From da18b9049898dc061e3cb2e5b73f173a90bf19d4 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 17:53:20 -0500 Subject: [PATCH 101/261] fix: Use #define --- math/fibonacci_fast.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index dba8b9dc0..fa81f9561 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -19,12 +19,15 @@ #include #include +/** + * maximum number that can be computed - The result after 93 cannot be stored + * in a `uint64_t` data type. + */ + +#define MAX 93 + /** Algorithm */ uint64_t fib(uint64_t n) { - // maximum number that can be computed - The result after 93 cannot be stored - // in a `uint64_t` data type. - static const uint64_t MAX = 93; - // Array of computed fibonacci numbers */ static uint64_t numbers[MAX] = {0}; From 01c52789111c8853db3812a36b139e4670431eed Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 18:22:21 -0500 Subject: [PATCH 102/261] fix: fibonacci_fast.cpp fixes --- math/fibonacci_fast.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index fa81f9561..be68bab70 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -28,22 +28,20 @@ /** Algorithm */ uint64_t fib(uint64_t n) { - // Array of computed fibonacci numbers */ - static uint64_t numbers[MAX] = {0}; + static uint64_t f1 = 1, f2 = 1; // using static keyword will retain the values of f1 and f2 for the next function call. - if (n == 0) + if (n <= 2) + return f2; + if (n >= 93) { + std::err << "Cannot compute for n>93 due to limit of 64-bit integers\n"; return 0; - if (n == 1 || n == 2) - return (numbers[n] = 1); + } - if (numbers[n]) - return numbers[n]; + uint64_t temp = f2; // we do not need temp to be static + f2 += f1; + f1 = temp; - uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2; - - numbers[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1)) - : (2 * fib(k - 1) + fib(k)) * fib(k); - return numbers[n]; + return f2; } /** Main function */ From 52b9b0bb98ad730822fc07834e2f06afeaebe8f4 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 18:23:37 -0500 Subject: [PATCH 103/261] docs: Change variable name --- data_structures/stack_using_array.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data_structures/stack_using_array.cpp b/data_structures/stack_using_array.cpp index b78e08e37..22b397ba8 100644 --- a/data_structures/stack_using_array.cpp +++ b/data_structures/stack_using_array.cpp @@ -1,31 +1,31 @@ #include int *stack; -int top_var = 0, stack_size; +int stack_idx = 0, stack_size; void push(int x) { - if (top_var == stack_size) { + if (stack_idx == stack_size) { std::cout << "\nOverflow"; } else { - stack[top_var++] = x; + stack[stack_idx++] = x; } } void pop() { - if (top_var == 0) { + if (stack_idx == 0) { std::cout << "\nUnderflow"; } else { - std::cout << "\n" << stack[--top_var] << " deleted"; + std::cout << "\n" << stack[--stack_idx] << " deleted"; } } void show() { - for (int i = 0; i < top_var; i++) { + for (int i = 0; i < stack_idx; i++) { std::cout << stack[i] << "\n"; } } -void topmost() { std::cout << "\nTopmost element: " << stack[top_var - 1]; } +void topmost() { std::cout << "\nTopmost element: " << stack[stack_idx - 1]; } int main() { std::cout << "\nEnter stack_size of stack : "; std::cin >> stack_size; From f05aadf3b8fddae08331fa127f7e75a6ab44e37a Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 18:26:47 -0500 Subject: [PATCH 104/261] fix: Wrong function name --- math/fibonacci_fast.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index be68bab70..e7582df73 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -33,7 +33,7 @@ uint64_t fib(uint64_t n) { if (n <= 2) return f2; if (n >= 93) { - std::err << "Cannot compute for n>93 due to limit of 64-bit integers\n"; + std::cerr << "Cannot compute for n>93 due to limit of 64-bit integers\n"; return 0; } From b6fdaa63eb5f14c1a8d18aef476707baccd72ee6 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 18:45:56 -0500 Subject: [PATCH 105/261] docs: Change variable names --- data_structures/stack_using_linked_list.cpp | 14 +++++++------- others/paranthesis_matching.cpp | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/data_structures/stack_using_linked_list.cpp b/data_structures/stack_using_linked_list.cpp index 3dcf03f8a..315b4e3b9 100644 --- a/data_structures/stack_using_linked_list.cpp +++ b/data_structures/stack_using_linked_list.cpp @@ -5,28 +5,28 @@ struct node { node *next; }; -node *top_var; +node *stack_idx; void push(int x) { node *n = new node; n->val = x; - n->next = top_var; - top_var = n; + n->next = stack_idx; + stack_idx = n; } void pop() { - if (top_var == NULL) { + if (stack_idx == NULL) { std::cout << "\nUnderflow"; } else { - node *t = top_var; + node *t = stack_idx; std::cout << "\n" << t->val << " deleted"; - top_var = top_var->next; + stack_idx = stack_idx->next; delete t; } } void show() { - node *t = top_var; + node *t = stack_idx; while (t != NULL) { std::cout << t->val << "\n"; t = t->next; diff --git a/others/paranthesis_matching.cpp b/others/paranthesis_matching.cpp index 0a1a9e474..d9c52c813 100644 --- a/others/paranthesis_matching.cpp +++ b/others/paranthesis_matching.cpp @@ -20,13 +20,13 @@ char stack[MAX]; //! pointer to track stack index -int top_var = -1; +int stack_idx = -1; //! push byte to stack variable -void push(char ch) { stack[++top_var] = ch; } +void push(char ch) { stack[++stack_idx] = ch; } //! pop a byte out of stack variable -char pop() { return stack[top_var--]; } +char pop() { return stack[stack_idx--]; } //! @}-------------- end stack ----------- @@ -56,7 +56,7 @@ int main() { while (valid == 1 && i < exp.length()) { if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[' || exp[i] == '<') { push(exp[i]); - } else if (top_var >= 0 && stack[top_var] == opening(exp[i])) { + } else if (stack_idx >= 0 && stack[stack_idx] == opening(exp[i])) { pop(); } else { valid = 0; @@ -65,7 +65,7 @@ int main() { } // makes sure the stack is empty after processsing (above) - if (valid == 1 && top_var == -1) { + if (valid == 1 && stack_idx == -1) { std::cout << "\nCorrect Expression"; } else { std::cout << "\nWrong Expression"; From e0fa86816aee2c41d21a2716c0ef913c5ad1ec3e Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Tue, 23 Jun 2020 18:50:14 -0500 Subject: [PATCH 106/261] fix: Variable name --- data_structures/stack_using_linked_list.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data_structures/stack_using_linked_list.cpp b/data_structures/stack_using_linked_list.cpp index 315b4e3b9..3dcf03f8a 100644 --- a/data_structures/stack_using_linked_list.cpp +++ b/data_structures/stack_using_linked_list.cpp @@ -5,28 +5,28 @@ struct node { node *next; }; -node *stack_idx; +node *top_var; void push(int x) { node *n = new node; n->val = x; - n->next = stack_idx; - stack_idx = n; + n->next = top_var; + top_var = n; } void pop() { - if (stack_idx == NULL) { + if (top_var == NULL) { std::cout << "\nUnderflow"; } else { - node *t = stack_idx; + node *t = top_var; std::cout << "\n" << t->val << " deleted"; - stack_idx = stack_idx->next; + top_var = top_var->next; delete t; } } void show() { - node *t = stack_idx; + node *t = top_var; while (t != NULL) { std::cout << t->val << "\n"; t = t->next; From 95890fdb6642ba584c28368126344a44aa69e2f2 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 24 Jun 2020 10:26:55 -0400 Subject: [PATCH 107/261] create copy constructor --- data_structures/stack.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/data_structures/stack.h b/data_structures/stack.h index f4b8992e7..3957b4d8d 100644 --- a/data_structures/stack.h +++ b/data_structures/stack.h @@ -34,6 +34,36 @@ class stack { size = 0; } + /** Copy constructor*/ + explicit stack(const stack &other) { + node *newNode, *current, *last; + + /* If stack is no empty, make it empty */ + if (stackTop != NULL) { + stackTop = NULL; + } + if (otherStack.stackTop == NULL) { + stackTop = NULL; + } else { + current = otherStack.stackTop; + stackTop = new node; + stackTop->data = current->data; + stackTop->next = NULL; + last = stackTop; + current = current->next; + /* Copy the remaining stack */ + while (current != NULL) { + newNode = new node; + newNode->data = current->data; + newNode->next = NULL; + last->next = newNode; + last = newNode; + current = current->next; + } + } + size = otherStack.size; + } + /** Destructor */ ~stack() {} From 94a494edf59a99ec0457e7fa264e7d17b4c5c6ce Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 24 Jun 2020 10:27:23 -0400 Subject: [PATCH 108/261] replace NULL with nullptr --- data_structures/stack.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/data_structures/stack.h b/data_structures/stack.h index 3957b4d8d..31a5abe34 100644 --- a/data_structures/stack.h +++ b/data_structures/stack.h @@ -20,7 +20,7 @@ class stack { void display() { node *current = stackTop; std::cout << "Top --> "; - while (current != NULL) { + while (current != nullptr) { std::cout << current->data << " "; current = current->next; } @@ -30,7 +30,7 @@ class stack { /** Default constructor*/ stack() { - stackTop = NULL; + stackTop = nullptr; size = 0; } @@ -39,23 +39,23 @@ class stack { node *newNode, *current, *last; /* If stack is no empty, make it empty */ - if (stackTop != NULL) { - stackTop = NULL; + if (stackTop != nullptr) { + stackTop = nullptr; } - if (otherStack.stackTop == NULL) { - stackTop = NULL; + if (otherStack.stackTop == nullptr) { + stackTop = nullptr; } else { current = otherStack.stackTop; stackTop = new node; stackTop->data = current->data; - stackTop->next = NULL; + stackTop->next = nullptr; last = stackTop; current = current->next; /* Copy the remaining stack */ - while (current != NULL) { + while (current != nullptr) { newNode = new node; newNode->data = current->data; - newNode->next = NULL; + newNode->next = nullptr; last->next = newNode; last = newNode; current = current->next; @@ -68,7 +68,7 @@ class stack { ~stack() {} /** Determine whether the stack is empty */ - bool isEmptyStack() { return (stackTop == NULL); } + bool isEmptyStack() { return (stackTop == nullptr); } /** Add new item to the stack */ void push(Type item) { @@ -82,7 +82,7 @@ class stack { /** Return the top element of the stack */ Type top() { - assert(stackTop != NULL); + assert(stackTop != nullptr); return stackTop->data; } @@ -100,30 +100,30 @@ class stack { } /** Clear stack */ - void clear() { stackTop = NULL; } + void clear() { stackTop = nullptr; } /** Overload "=" the assignment operator */ stack &operator=(const stack &otherStack) { node *newNode, *current, *last; /* If stack is no empty, make it empty */ - if (stackTop != NULL) { - stackTop = NULL; + if (stackTop != nullptr) { + stackTop = nullptr; } - if (otherStack.stackTop == NULL) { - stackTop = NULL; + if (otherStack.stackTop == nullptr) { + stackTop = nullptr; } else { current = otherStack.stackTop; stackTop = new node; stackTop->data = current->data; - stackTop->next = NULL; + stackTop->next = nullptr; last = stackTop; current = current->next; /* Copy the remaining stack */ - while (current != NULL) { + while (current != nullptr) { newNode = new node; newNode->data = current->data; - newNode->next = NULL; + newNode->next = nullptr; last->next = newNode; last = newNode; current = current->next; From 631b50cede4ad0cc5ad350f88c2cc01280d54101 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 24 Jun 2020 10:37:15 -0400 Subject: [PATCH 109/261] update documetnation --- data_structures/stack.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/data_structures/stack.h b/data_structures/stack.h index 31a5abe34..429e0265f 100644 --- a/data_structures/stack.h +++ b/data_structures/stack.h @@ -1,18 +1,27 @@ -/* This class specifies the basic operation on a stack as a linked list */ +/** + * @file stack.h + * @author danghai + * @brief This class specifies the basic operation on a stack as a linked list + **/ #ifndef DATA_STRUCTURES_STACK_H_ #define DATA_STRUCTURES_STACK_H_ #include #include -/* Definition of the node */ +/** Definition of the node as a linked-list + * \tparam Type type of data nodes of the linked list should contain + */ template struct node { - Type data; - node *next; + Type data; ///< data at current node + node *next; ///< pointer to the next ::node instance }; -/* Definition of the stack class */ +/** Definition of the stack class + * \tparam Type type of data nodes of the linked list in the stack should + * contain + */ template class stack { public: @@ -135,7 +144,7 @@ class stack { private: node *stackTop; /**< Pointer to the stack */ - int size; + int size; ///< size of stack }; #endif // DATA_STRUCTURES_STACK_H_ From 9b01676b338ee75d6a2eb06574ed660d0ac9c5ea Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 24 Jun 2020 10:48:18 -0400 Subject: [PATCH 110/261] fixed function argument --- data_structures/stack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/stack.h b/data_structures/stack.h index 429e0265f..483648046 100644 --- a/data_structures/stack.h +++ b/data_structures/stack.h @@ -44,7 +44,7 @@ class stack { } /** Copy constructor*/ - explicit stack(const stack &other) { + explicit stack(const stack &otherStack) { node *newNode, *current, *last; /* If stack is no empty, make it empty */ From 5e3307620c8a092a982610fa8f7ced49c7ce06f5 Mon Sep 17 00:00:00 2001 From: Neeraj C Date: Wed, 24 Jun 2020 20:46:23 +0530 Subject: [PATCH 111/261] feat: create math/armstrong_number.cpp --- math/armstrong_number.cpp | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 math/armstrong_number.cpp diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp new file mode 100644 index 000000000..0b5f01cd1 --- /dev/null +++ b/math/armstrong_number.cpp @@ -0,0 +1,77 @@ +/** + * @file + * \brief A C++ program to check whether a number is armstrong number or not. + * + * \details + * Armstrong number or [Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) + * is a number that is the sum of its own digits raised to the power of the number of digits. + * @author iamnambiar +*/ +#include +#include +#include + +/** + * Function to calculate the total number of digits in the number. + * @param num Number + * @return Total number of digits. + */ +int number_of_digits(int num) { + int total_digits = 0; + while (num > 0) { + num = num / 10; + ++total_digits; + } + return total_digits; +} + +/** + * Function to check whether the number is armstrong number or not. + * @param num Number + * @return `true` if the number is armstrong. + * @return `false` if the number is not armstrong. + */ +bool is_armstrong(int number) { + // If the number is less than 0, then it is not a armstrong number. + if (number < 0) { + return false; + } + int sum = 0; + int temp = number; + // Finding the total number of digits in the number + int total_digits = number_of_digits(number); + while (temp > 0) { + int rem = temp % 10; + // Finding each digit raised to the power total digit and add it to the total sum + sum = sum + pow(rem, total_digits); + temp = temp / 10; + } + return number == sum; +} + +/** + * Function for testing the is_amicable() with + * all the test cases. + */ +void test() { + // is_armstrong(370) returns true. + assert(is_armstrong(370) == true); + // is_armstrong(225) returns false. + assert(is_armstrong(225) == false); + // is_armstrong(-23) returns false. + assert(is_armstrong(-23) == false); + // is_armstrong(153) returns true. + assert(is_armstrong(153) == true); + // is_armstrong(0) returns true. + assert(is_armstrong(0) == true); + // is_armstrong(12) returns false. + assert(is_armstrong(12) == false); +} + +/** + * Main Function +*/ +int main() { + test(); + return 0; +} From 5b3e30a937e488b3de38673134db136cb1e19759 Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Wed, 24 Jun 2020 20:52:32 +0530 Subject: [PATCH 112/261] docs: typo fixed --- math/armstrong_number.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index 0b5f01cd1..166c98c07 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -50,8 +50,8 @@ bool is_armstrong(int number) { } /** - * Function for testing the is_amicable() with - * all the test cases. + * Function for testing the is_armstrong() function + * with all the test cases. */ void test() { // is_armstrong(370) returns true. From c7ff9d66f1e7c18b43e51d183f1299b25293ac55 Mon Sep 17 00:00:00 2001 From: Panquesito7 Date: Wed, 24 Jun 2020 12:12:30 -0500 Subject: [PATCH 113/261] feat: Add exit option --- data_structures/stack_using_array.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/stack_using_array.cpp b/data_structures/stack_using_array.cpp index 22b397ba8..0c0813d5e 100644 --- a/data_structures/stack_using_array.cpp +++ b/data_structures/stack_using_array.cpp @@ -32,6 +32,7 @@ int main() { stack = new int[stack_size]; int ch, x; do { + std::cout << "\n0. Exit"; std::cout << "\n1. Push"; std::cout << "\n2. Pop"; std::cout << "\n3. Print"; From 4c6b3b86c1f191339770039b8c7f377a5a18fc4e Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 24 Jun 2020 17:14:57 +0000 Subject: [PATCH 114/261] formatting source-code for c7ff9d66f1e7c18b43e51d183f1299b25293ac55 --- math/fibonacci_fast.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp index e7582df73..0948276a0 100644 --- a/math/fibonacci_fast.cpp +++ b/math/fibonacci_fast.cpp @@ -19,7 +19,7 @@ #include #include -/** +/** * maximum number that can be computed - The result after 93 cannot be stored * in a `uint64_t` data type. */ @@ -28,16 +28,19 @@ /** Algorithm */ uint64_t fib(uint64_t n) { - static uint64_t f1 = 1, f2 = 1; // using static keyword will retain the values of f1 and f2 for the next function call. - + static uint64_t f1 = 1, + f2 = 1; // using static keyword will retain the values of + // f1 and f2 for the next function call. + if (n <= 2) return f2; if (n >= 93) { - std::cerr << "Cannot compute for n>93 due to limit of 64-bit integers\n"; + std::cerr + << "Cannot compute for n>93 due to limit of 64-bit integers\n"; return 0; } - uint64_t temp = f2; // we do not need temp to be static + uint64_t temp = f2; // we do not need temp to be static f2 += f1; f1 = temp; From f1ab19bb33f01b85a2082213dc6ae8c7ab4f22c6 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Thu, 25 Jun 2020 03:39:12 +0530 Subject: [PATCH 115/261] fix: minor docs issue --- sorting/heap_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/heap_sort.cpp b/sorting/heap_sort.cpp index ef9f87094..d91cdb14f 100644 --- a/sorting/heap_sort.cpp +++ b/sorting/heap_sort.cpp @@ -26,7 +26,7 @@ /** * - * Utility Lambda function to print the array after + * Utility function to print the array after * sorting. * * @param arr array to be printed From a190674131ea47919edb5987e3d713b2a9b0c0d1 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 24 Jun 2020 18:27:01 -0400 Subject: [PATCH 116/261] fix errors in matrix_exponentiation --- others/matrix_exponentiation.cpp | 55 +++++++++++++++----------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/others/matrix_exponentiation.cpp b/others/matrix_exponentiation.cpp index d44d22593..d646b3977 100644 --- a/others/matrix_exponentiation.cpp +++ b/others/matrix_exponentiation.cpp @@ -36,21 +36,18 @@ using std::vector; #define endl std::endl /*! shorthand definition for `int64_t` */ -#define pb push_back +#define pb push_back #define MOD 1000000007 -/** returns absolute value */ -inline ll ab(ll x) { return x > 0LL ? x : -x; } - -/** global variable k +/** global variable mat_size * @todo @stepfencurryxiao add documetnation */ -ll k; +ll mat_size; -/** global vector variables +/** global vector variables used in the ::ans function. * @todo @stepfencurryxiao add documetnation */ -vector a, b, c; +vector fib_b, fib_c; /** To multiply 2 matrices * \param [in] A matrix 1 of size (m\f$\times\f$n) @@ -59,10 +56,10 @@ vector a, b, c; */ vector> multiply(const vector> &A, const vector> &B) { - vector> C(k + 1, vector(k + 1)); - for (ll i = 1; i <= k; i++) { - for (ll j = 1; j <= k; j++) { - for (ll z = 1; z <= k; z++) { + vector> C(mat_size + 1, vector(mat_size + 1)); + for (ll i = 1; i <= mat_size; i++) { + for (ll j = 1; j <= mat_size; j++) { + for (ll z = 1; z <= mat_size; z++) { C[i][j] = (C[i][j] + (A[i][z] * B[z][j]) % MOD) % MOD; } } @@ -94,24 +91,24 @@ vector> power(const vector> &A, ll p) { ll ans(ll n) { if (n == 0) return 0; - if (n <= k) - return b[n - 1]; + if (n <= mat_size) + return fib_b[n - 1]; // F1 - vector F1(k + 1); - for (ll i = 1; i <= k; i++) F1[i] = b[i - 1]; + vector F1(mat_size + 1); + for (ll i = 1; i <= mat_size; i++) F1[i] = fib_b[i - 1]; // Transpose matrix - vector> T(k + 1, vector(k + 1)); - for (ll i = 1; i <= k; i++) { - for (ll j = 1; j <= k; j++) { - if (i < k) { + vector> T(mat_size + 1, vector(mat_size + 1)); + for (ll i = 1; i <= mat_size; i++) { + for (ll j = 1; j <= mat_size; j++) { + if (i < mat_size) { if (j == i + 1) T[i][j] = 1; else T[i][j] = 0; continue; } - T[i][j] = c[k - j]; + T[i][j] = fib_c[mat_size - j]; } } // T^n-1 @@ -119,7 +116,7 @@ ll ans(ll n) { // T*F1 ll res = 0; - for (ll i = 1; i <= k; i++) { + for (ll i = 1; i <= mat_size; i++) { res = (res + (T[1][i] * F1[i]) % MOD) % MOD; } return res; @@ -133,19 +130,19 @@ int main() { cin >> t; ll i, j, x; while (t--) { - cin >> k; - for (i = 0; i < k; i++) { + cin >> mat_size; + for (i = 0; i < mat_size; i++) { cin >> x; - b.pb(x); + fib_b.pb(x); } - for (i = 0; i < k; i++) { + for (i = 0; i < mat_size; i++) { cin >> x; - c.pb(x); + fib_c.pb(x); } cin >> x; cout << ans(x) << endl; - b.clear(); - c.clear(); + fib_b.clear(); + fib_c.clear(); } return 0; } From ef5f33083405e4d7f54650173f8aa9fcf9ff9fe7 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 24 Jun 2020 22:28:10 +0000 Subject: [PATCH 117/261] formatting source-code for a190674131ea47919edb5987e3d713b2a9b0c0d1 --- others/matrix_exponentiation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/others/matrix_exponentiation.cpp b/others/matrix_exponentiation.cpp index d646b3977..bde7f521b 100644 --- a/others/matrix_exponentiation.cpp +++ b/others/matrix_exponentiation.cpp @@ -36,7 +36,7 @@ using std::vector; #define endl std::endl /*! shorthand definition for `int64_t` */ -#define pb push_back +#define pb push_back #define MOD 1000000007 /** global variable mat_size From e6ab38c2fdd803ebc241cce2aeb7a28161ac259a Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Thu, 25 Jun 2020 04:13:49 +0530 Subject: [PATCH 118/261] Added docs --- graph/connected_components.cpp | 71 +++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/graph/connected_components.cpp b/graph/connected_components.cpp index 0bfb8bbdb..ab35f7587 100644 --- a/graph/connected_components.cpp +++ b/graph/connected_components.cpp @@ -1,29 +1,86 @@ +/** + * + * \file + * \brief [Connected Components + * (Connected Components)](https://en.wikipedia.org/wiki/Component_(graph_theory)) + * + * \author [Ayaan Khan](http://github.com/ayaankhan98) + * + * \details + * A graph is a collection of nodes also called vertices and these vertices + * are connected by edges. A connected component in a graph refers to a set of + * vertices which are reachable form one another. + * + * Example - Here is graph with 3 connected components + * + * 3 9 6 8 + * / \ / / \ / \ + * 2---4 2 7 3 7 + * + * first second third + * component component component + * + */ + +#include #include #include using std::vector; +/** + * Class for representing graph as a adjacency list. + */ class graph { private: + /** \brief adj stores adjacency list representation of graph */ vector> adj; + + /** \brief keep track of connected components */ int connected_components; + + /** \brief Utility function to perform depth first search on graph */ void depth_first_search(); + + /** \brief Utility function that explores given vertex in graph */ void explore(int, vector &); public: + /** + * \brief Constructor that intiliazes the graph on creation and set + * the connected components to 0 + */ explicit graph(int n) : adj(n, vector()) { connected_components = 0; } + + /** \brief Function to add a edge between two nodes or vertices of graph */ void addEdge(int, int); + + /** + * \brief Function the calculates the connected compoents in the graph + * by performing the depth first search on graph + * + * @return connected_components total connected components in graph + */ int getConnectedComponents() { depth_first_search(); return connected_components; } }; +/** + * \brief Function that add edge between two nodes or vertices of graph + * + * @param u any node or vertex of graph + * @param v any node or vertex of graph + */ void graph::addEdge(int u, int v) { adj[u - 1].push_back(v - 1); adj[v - 1].push_back(u - 1); } +/** + * \brief Function that perfoms depth first search algorithm on graph + */ void graph::depth_first_search() { int n = adj.size(); vector visited(n, false); @@ -35,7 +92,13 @@ void graph::depth_first_search() { } } } - +/** + * \brief Utility function for depth first seach algorithm + * this function explores the vertex which is passed into. + * + * @param u vertex or node to be explored + * @param visited already visited vertex + */ void graph::explore(int u, vector &visited) { visited[u] = true; for (auto v : adj[u]) { @@ -45,10 +108,16 @@ void graph::explore(int u, vector &visited) { } } +/** Main function */ int main() { + /// creating a graph with 4 vertex graph g(4); + + /// Adding edges between vertices g.addEdge(1, 2); g.addEdge(3, 2); + + /// printing the connected components std::cout << g.getConnectedComponents(); return 0; } From 6980792eff787eb58023042f4103be4af3f5ab14 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 24 Jun 2020 22:44:37 +0000 Subject: [PATCH 119/261] formatting source-code for e6ab38c2fdd803ebc241cce2aeb7a28161ac259a --- graph/connected_components.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/graph/connected_components.cpp b/graph/connected_components.cpp index ab35f7587..efff4e4c7 100644 --- a/graph/connected_components.cpp +++ b/graph/connected_components.cpp @@ -2,7 +2,8 @@ * * \file * \brief [Connected Components - * (Connected Components)](https://en.wikipedia.org/wiki/Component_(graph_theory)) + * (Connected + * Components)](https://en.wikipedia.org/wiki/Component_(graph_theory)) * * \author [Ayaan Khan](http://github.com/ayaankhan98) * @@ -33,7 +34,7 @@ using std::vector; */ class graph { private: - /** \brief adj stores adjacency list representation of graph */ + /** \brief adj stores adjacency list representation of graph */ vector> adj; /** \brief keep track of connected components */ @@ -46,16 +47,16 @@ class graph { void explore(int, vector &); public: - /** + /** * \brief Constructor that intiliazes the graph on creation and set * the connected components to 0 */ explicit graph(int n) : adj(n, vector()) { connected_components = 0; } - + /** \brief Function to add a edge between two nodes or vertices of graph */ void addEdge(int, int); - /** + /** * \brief Function the calculates the connected compoents in the graph * by performing the depth first search on graph * @@ -110,14 +111,14 @@ void graph::explore(int u, vector &visited) { /** Main function */ int main() { - /// creating a graph with 4 vertex + /// creating a graph with 4 vertex graph g(4); - /// Adding edges between vertices + /// Adding edges between vertices g.addEdge(1, 2); g.addEdge(3, 2); - /// printing the connected components + /// printing the connected components std::cout << g.getConnectedComponents(); return 0; } From 9c75856235a9cae35ae9833633ef37d65714bdef Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Thu, 25 Jun 2020 07:59:39 +0530 Subject: [PATCH 120/261] docs: clean the comment Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/armstrong_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index 166c98c07..3b7e67cc5 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -1,6 +1,6 @@ /** * @file - * \brief A C++ program to check whether a number is armstrong number or not. + * \brief Program to check if a number is an [Armstrong/Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) in decimal system. * * \details * Armstrong number or [Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) From 06ca2a69532bb1bc17173d14804a2329450fe2e8 Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Thu, 25 Jun 2020 08:00:37 +0530 Subject: [PATCH 121/261] fix: spaces between include and header file Co-authored-by: David Leal --- math/armstrong_number.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index 3b7e67cc5..f8c7510e8 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -7,9 +7,9 @@ * is a number that is the sum of its own digits raised to the power of the number of digits. * @author iamnambiar */ -#include -#include -#include +#include +#include +#include /** * Function to calculate the total number of digits in the number. From 06f425493b1567a7394d533dda525b4d64583be9 Mon Sep 17 00:00:00 2001 From: Neeraj C <35414531+iamnambiar@users.noreply.github.com> Date: Thu, 25 Jun 2020 10:59:44 +0530 Subject: [PATCH 122/261] fix: changed to std::pow Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/armstrong_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index f8c7510e8..db8eb0fb7 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -43,7 +43,7 @@ bool is_armstrong(int number) { while (temp > 0) { int rem = temp % 10; // Finding each digit raised to the power total digit and add it to the total sum - sum = sum + pow(rem, total_digits); + sum = sum + std::pow(rem, total_digits); temp = temp / 10; } return number == sum; From 64bb640391f0d60bed8f87356ac86a487a94aac9 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Thu, 25 Jun 2020 13:02:12 +0530 Subject: [PATCH 123/261] Wrapped example in

---
 graph/connected_components.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/graph/connected_components.cpp b/graph/connected_components.cpp
index ab35f7587..18c99cf45 100644
--- a/graph/connected_components.cpp
+++ b/graph/connected_components.cpp
@@ -11,6 +11,7 @@
  * are connected by edges. A connected component in a graph refers to a set of
  * vertices which are reachable form one another.
  *
+ * 
  * Example - Here is graph with 3 connected components
  *
  *      3   9           6               8
@@ -19,6 +20,7 @@
  *
  *    first          second           third
  *    component      component        component
+ * 
* */ From 351a1b712a982f72396559be40e7dd37d9b6db2c Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:51:24 +0000 Subject: [PATCH 124/261] formatting source-code for ca70c3097e51f7a3845cabf3a140d3a1fb2f3cb3 --- math/armstrong_number.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index db8eb0fb7..426de327b 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -1,15 +1,17 @@ /** * @file - * \brief Program to check if a number is an [Armstrong/Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) in decimal system. - * + * \brief Program to check if a number is an [Armstrong/Narcissistic + * number](https://en.wikipedia.org/wiki/Narcissistic_number) in decimal system. + * * \details - * Armstrong number or [Narcissistic number](https://en.wikipedia.org/wiki/Narcissistic_number) - * is a number that is the sum of its own digits raised to the power of the number of digits. + * Armstrong number or [Narcissistic + * number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that + * is the sum of its own digits raised to the power of the number of digits. * @author iamnambiar -*/ + */ #include -#include #include +#include /** * Function to calculate the total number of digits in the number. @@ -42,7 +44,8 @@ bool is_armstrong(int number) { int total_digits = number_of_digits(number); while (temp > 0) { int rem = temp % 10; - // Finding each digit raised to the power total digit and add it to the total sum + // Finding each digit raised to the power total digit and add it to the + // total sum sum = sum + std::pow(rem, total_digits); temp = temp / 10; } @@ -50,7 +53,7 @@ bool is_armstrong(int number) { } /** - * Function for testing the is_armstrong() function + * Function for testing the is_armstrong() function * with all the test cases. */ void test() { @@ -70,7 +73,7 @@ void test() { /** * Main Function -*/ + */ int main() { test(); return 0; From 21093365cd2b3ac8ba4e081329a4eb24827e42d0 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:51:24 +0000 Subject: [PATCH 125/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 6e43ba3f2..257b4160d 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -100,6 +100,7 @@ * [Kohonen Som Trace](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/kohonen_som_trace.cpp) ## Math + * [Armstrong Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/armstrong_number.cpp) * [Binary Exponent](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/binary_exponent.cpp) * [Check Amicable Pair](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_amicable_pair.cpp) * [Check Prime](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/check_prime.cpp) From 05789603ab82ac5e00e2e5d415509719066687c8 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Thu, 25 Jun 2020 15:49:30 +0530 Subject: [PATCH 126/261] fix: repeated sentences --- graph/connected_components.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/graph/connected_components.cpp b/graph/connected_components.cpp index ec7ef19e6..e53dbf424 100644 --- a/graph/connected_components.cpp +++ b/graph/connected_components.cpp @@ -1,9 +1,9 @@ /** * * \file - * \brief [Connected Components - * (Connected - * Components)](https://en.wikipedia.org/wiki/Component_(graph_theory)) + * \brief [Graph Connected Components + * (Connected Components)] + * (https://en.wikipedia.org/wiki/Component_(graph_theory)) * * \author [Ayaan Khan](http://github.com/ayaankhan98) * @@ -42,10 +42,7 @@ class graph { /** \brief keep track of connected components */ int connected_components; - /** \brief Utility function to perform depth first search on graph */ void depth_first_search(); - - /** \brief Utility function that explores given vertex in graph */ void explore(int, vector &); public: @@ -55,7 +52,6 @@ class graph { */ explicit graph(int n) : adj(n, vector()) { connected_components = 0; } - /** \brief Function to add a edge between two nodes or vertices of graph */ void addEdge(int, int); /** From 5939792a9dbef599055b3cc88e9835e6065ce2f2 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:14:21 -0400 Subject: [PATCH 127/261] fix self-tests and unsigned comparision to zero refer #897 and https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/rev/pr-f6e7cda8faf908e87511f30e782190233bdee68c --- math/double_factorial.cpp | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index 8e5ffcefa..1d1f7dae4 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -32,10 +32,33 @@ uint64_t double_factorial_recursive(uint64_t n) { 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); +/** Wrapper to run tests using both recursive and iterative implementations. + * The checks are only valid in debug builds due to the use of `assert()` + * statements. + * \param [in] n number to check double factorial for + * \param [in] expected expected result + */ +void test(uint64_t n, uint64_t expected) { + assert(double_factorial_iterative(n) == expected); + assert(double_factorial_recursive(n) == expected); } + +/** + * Test implementations + */ +void tests() { + std::cout << "Test 1:\t n=5\t..."; + test(5, 15); + std::cout << "passed\n"; + + std::cout << "Test 2:\t n=15\t..."; + test(15, 2027025); + std::cout << "passed\n"; + + std::cout << "Test 3:\t n=0\t..."; + test(0, 1); + std::cout << "passed\n"; +} + +/// main function +int main() { tests(); } From d8b121b1191fed37442a52873692af36091f3c16 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:26:20 -0400 Subject: [PATCH 128/261] disable timestamps in footer of html docs --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 957be35f5..adb1c740a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ if(DOXYGEN_FOUND) set(DOXYGEN_GENERATE_MAN NO) set(DOXYGEN_USE_MATHJAX YES) set(DOXYGEN_GENERATE_HTML YES) - set(DOXYGEN_HTML_TIMESTAMP YES) + # set(DOXYGEN_HTML_TIMESTAMP YES) set(DOXYGEN_EXTRACT_STATIC YES) set(DOXYGEN_INLINE_SOURCES YES) set(DOXYGEN_CREATE_SUBDIRS YES) From 66eb05e0daf68fdc43e0da3bf4a7b56038191b45 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 09:59:36 -0400 Subject: [PATCH 129/261] added wiki link in file brieff --- 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 1d1f7dae4..a400ae147 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -1,8 +1,9 @@ /** * @file - * @brief Compute double factorial: \f$n!!\f$ + * @brief Compute [double + * factorial](https://en.wikipedia.org/wiki/Double_factorial): \f$n!!\f$ * - * Double factorial of a non-negative integer n, is defined as the product of + * 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$ From 2c61414a838611dc19ce6296164133d642b185fa Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 13:38:11 -0400 Subject: [PATCH 130/261] split lu_decomposition to a header file and templated the function --- numerical_methods/lu_decompose.cpp | 74 +++------------------------- numerical_methods/lu_decomposition.h | 65 ++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 66 deletions(-) create mode 100644 numerical_methods/lu_decomposition.h diff --git a/numerical_methods/lu_decompose.cpp b/numerical_methods/lu_decompose.cpp index a0a2d00ab..2ce5fb653 100644 --- a/numerical_methods/lu_decompose.cpp +++ b/numerical_methods/lu_decompose.cpp @@ -7,73 +7,15 @@ #include #include #include -#include -#ifdef _OPENMP -#include -#endif -/** Perform LU decomposition on matrix - * \param[in] A matrix to decompose - * \param[out] L output L matrix - * \param[out] U output U matrix - * \returns 0 if no errors - * \returns negative if error occurred - */ -int lu_decomposition(const std::vector> &A, - std::vector> *L, - std::vector> *U) { - int row, col, j; - int mat_size = A.size(); - - if (mat_size != A[0].size()) { - // check matrix is a square matrix - std::cerr << "Not a square matrix!\n"; - return -1; - } - - // regularize each row - for (row = 0; row < mat_size; row++) { - // Upper triangular matrix -#ifdef _OPENMP -#pragma omp for -#endif - for (col = row; col < mat_size; col++) { - // Summation of L[i,j] * U[j,k] - double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][row][j] * U[0][j][col]; - - // Evaluate U[i,k] - U[0][row][col] = A[row][col] - lu_sum; - } - - // Lower triangular matrix -#ifdef _OPENMP -#pragma omp for -#endif - for (col = row; col < mat_size; col++) { - if (row == col) { - L[0][row][col] = 1.; - continue; - } - - // Summation of L[i,j] * U[j,k] - double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][col][j] * U[0][j][row]; - - // Evaluate U[i,k] - L[0][col][row] = (A[col][row] - lu_sum) / U[0][row][row]; - } - } - - return 0; -} +#include "./lu_decomposition.h" /** * operator to print a matrix */ template std::ostream &operator<<(std::ostream &out, - std::vector> const &v) { + std::vector> const &v) { const int width = 10; const char separator = ' '; @@ -99,14 +41,14 @@ int main(int argc, char **argv) { std::srand(std::time(NULL)); // random number initializer /* Create a square matrix with random values */ - std::vector> A(mat_size); - std::vector> L(mat_size); // output - std::vector> U(mat_size); // output + std::vector> A(mat_size, + std::valarray(mat_size)); + std::vector> L( + mat_size, std::valarray(mat_size)); // output + std::vector> U( + mat_size, std::valarray(mat_size)); // output for (int i = 0; i < mat_size; i++) { // calloc so that all valeus are '0' by default - A[i] = std::vector(mat_size); - L[i] = std::vector(mat_size); - U[i] = std::vector(mat_size); for (int j = 0; j < mat_size; j++) /* create random values in the limits [-range2, range-1] */ A[i][j] = static_cast(std::rand() % range - range2); diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h new file mode 100644 index 000000000..9cb881ba9 --- /dev/null +++ b/numerical_methods/lu_decomposition.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#ifdef _OPENMP +#include +#endif + +/** Perform LU decomposition on matrix + * \param[in] A matrix to decompose + * \param[out] L output L matrix + * \param[out] U output U matrix + * \returns 0 if no errors + * \returns negative if error occurred + */ +template +int lu_decomposition(const std::vector> &A, + std::vector> *L, + std::vector> *U) { + int row, col, j; + int mat_size = A.size(); + + if (mat_size != A[0].size()) { + // check matrix is a square matrix + std::cerr << "Not a square matrix!\n"; + return -1; + } + + // regularize each row + for (row = 0; row < mat_size; row++) { + // Upper triangular matrix +#ifdef _OPENMP +#pragma omp for +#endif + for (col = row; col < mat_size; col++) { + // Summation of L[i,j] * U[j,k] + double lu_sum = 0.; + for (j = 0; j < row; j++) lu_sum += L[0][row][j] * U[0][j][col]; + + // Evaluate U[i,k] + U[0][row][col] = A[row][col] - lu_sum; + } + + // Lower triangular matrix +#ifdef _OPENMP +#pragma omp for +#endif + for (col = row; col < mat_size; col++) { + if (row == col) { + L[0][row][col] = 1.; + continue; + } + + // Summation of L[i,j] * U[j,k] + double lu_sum = 0.; + for (j = 0; j < row; j++) lu_sum += L[0][col][j] * U[0][j][row]; + + // Evaluate U[i,k] + L[0][col][row] = (A[col][row] - lu_sum) / U[0][row][row]; + } + } + + return 0; +} From e1b1c71e7cca268c9fbad41d2d6b315ff63b9756 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 14:40:47 -0400 Subject: [PATCH 131/261] Apply suggestions from code review Co-authored-by: David Leal --- math/double_factorial.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index a400ae147..db22cc672 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -61,5 +61,10 @@ void tests() { std::cout << "passed\n"; } -/// main function -int main() { tests(); } +/** + * Main function + */ +int main() { + tests(); + return 0; +} From b1620ff2f57036bbd81faf57d09268d7b368c1a3 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 25 Jun 2020 18:41:27 +0000 Subject: [PATCH 132/261] formatting source-code for e1b1c71e7cca268c9fbad41d2d6b315ff63b9756 --- math/double_factorial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/double_factorial.cpp b/math/double_factorial.cpp index db22cc672..72feda60c 100644 --- a/math/double_factorial.cpp +++ b/math/double_factorial.cpp @@ -61,7 +61,7 @@ void tests() { std::cout << "passed\n"; } -/** +/** * Main function */ int main() { From e22f56c90628fa02017a43f581384a0c06551821 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 25 Jun 2020 18:43:00 +0000 Subject: [PATCH 133/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 257b4160d..679e6f7d8 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -140,6 +140,7 @@ * [Gaussian Elimination](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/gaussian_elimination.cpp) * [Golden Search Extrema](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/golden_search_extrema.cpp) * [Lu Decompose](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/lu_decompose.cpp) + * [Lu Decomposition](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/lu_decomposition.h) * [Newton Raphson Method](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/newton_raphson_method.cpp) * [Ode Forward Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_forward_euler.cpp) * [Ode Midpoint Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_midpoint_euler.cpp) From f29c14032a73160444f5be4df03a2c03ca4acbb5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 14:51:54 -0400 Subject: [PATCH 134/261] added determinant computation using LU decomposition --- numerical_methods/lu_decomposition.h | 34 ++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h index 9cb881ba9..42c29e4f2 100644 --- a/numerical_methods/lu_decomposition.h +++ b/numerical_methods/lu_decomposition.h @@ -36,7 +36,9 @@ int lu_decomposition(const std::vector> &A, for (col = row; col < mat_size; col++) { // Summation of L[i,j] * U[j,k] double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][row][j] * U[0][j][col]; + for (j = 0; j < row; j++) { + lu_sum += L[0][row][j] * U[0][j][col]; + } // Evaluate U[i,k] U[0][row][col] = A[row][col] - lu_sum; @@ -54,7 +56,9 @@ int lu_decomposition(const std::vector> &A, // Summation of L[i,j] * U[j,k] double lu_sum = 0.; - for (j = 0; j < row; j++) lu_sum += L[0][col][j] * U[0][j][row]; + for (j = 0; j < row; j++) { + lu_sum += L[0][col][j] * U[0][j][row]; + } // Evaluate U[i,k] L[0][col][row] = (A[col][row] - lu_sum) / U[0][row][row]; @@ -63,3 +67,29 @@ int lu_decomposition(const std::vector> &A, return 0; } + +/** + * @brief Compute determinant of an NxN square matrix using LU decomposition. + * Using LU decomposition, the determinant is given by the product of diagonal + * elements of matrices L and U. + * + * @tparam T datatype of input matrix - int, unsigned int, double, etc + * @param A input square matrix + * @return determinant of matrix A + */ +template +double determinant_lu(const std::vector> &A) { + std::vector> L(A.size(), + std::valarray(A.size())); + std::vector> U(A.size(), + std::valarray(A.size())); + + if (lu_decomposition(A, &L, &U) < 0) + return 0; + + double result = 1.f; + for (size_t i = 0; i < A.size(); i++) { + result *= L[i][i] * U[i][i]; + } + return result; +} From c1b0635f993c72fa32de11bc4df73b7dc77509b8 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:03:12 -0400 Subject: [PATCH 135/261] create and added matrix type --- numerical_methods/lu_decomposition.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h index 42c29e4f2..22af249a5 100644 --- a/numerical_methods/lu_decomposition.h +++ b/numerical_methods/lu_decomposition.h @@ -7,6 +7,10 @@ #include #endif +/** Define matrix type as a `std::vector` of `std::valarray` */ +template +using matrix = std::vector>; + /** Perform LU decomposition on matrix * \param[in] A matrix to decompose * \param[out] L output L matrix @@ -15,9 +19,7 @@ * \returns negative if error occurred */ template -int lu_decomposition(const std::vector> &A, - std::vector> *L, - std::vector> *U) { +int lu_decomposition(const matrix &A, matrix *L, matrix *U) { int row, col, j; int mat_size = A.size(); @@ -78,11 +80,9 @@ int lu_decomposition(const std::vector> &A, * @return determinant of matrix A */ template -double determinant_lu(const std::vector> &A) { - std::vector> L(A.size(), - std::valarray(A.size())); - std::vector> U(A.size(), - std::valarray(A.size())); +double determinant_lu(const matrix &A) { + matrix L(A.size(), std::valarray(A.size())); + matrix U(A.size(), std::valarray(A.size())); if (lu_decomposition(A, &L, &U) < 0) return 0; From 84cf0da2bbf3dc7c1dd0dd8ff916317208068cef Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:03:57 -0400 Subject: [PATCH 136/261] automated self-test of LU decomposition using sample case and determinant checks --- numerical_methods/lu_decompose.cpp | 52 +++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/numerical_methods/lu_decompose.cpp b/numerical_methods/lu_decompose.cpp index 2ce5fb653..b27fed2ee 100644 --- a/numerical_methods/lu_decompose.cpp +++ b/numerical_methods/lu_decompose.cpp @@ -4,6 +4,7 @@ * square matrix * \author [Krishna Vedala](https://github.com/kvedala) */ +#include #include #include #include @@ -14,8 +15,7 @@ * operator to print a matrix */ template -std::ostream &operator<<(std::ostream &out, - std::vector> const &v) { +std::ostream &operator<<(std::ostream &out, matrix const &v) { const int width = 10; const char separator = ' '; @@ -29,24 +29,19 @@ std::ostream &operator<<(std::ostream &out, return out; } -/** Main function */ -int main(int argc, char **argv) { +/** + * Test LU decomposition + * \todo better ways to self-check a matrix output? + */ +void test1() { int mat_size = 3; // default matrix size const int range = 50; const int range2 = range >> 1; - if (argc == 2) - mat_size = atoi(argv[1]); - - std::srand(std::time(NULL)); // random number initializer - /* Create a square matrix with random values */ - std::vector> A(mat_size, - std::valarray(mat_size)); - std::vector> L( - mat_size, std::valarray(mat_size)); // output - std::vector> U( - mat_size, std::valarray(mat_size)); // output + matrix A(mat_size, std::valarray(mat_size)); + matrix L(mat_size, std::valarray(mat_size)); // output + matrix U(mat_size, std::valarray(mat_size)); // output for (int i = 0; i < mat_size; i++) { // calloc so that all valeus are '0' by default for (int j = 0; j < mat_size; j++) @@ -63,6 +58,33 @@ int main(int argc, char **argv) { std::cout << "A = \n" << A << "\n"; std::cout << "L = \n" << L << "\n"; std::cout << "U = \n" << U << "\n"; +} +/** + * @brief Test determinant computation using LU decomposition + */ +void test2() { + std::cout << "Determinant test 1..."; + matrix A1({{1, 2, 3}, {4, 9, 6}, {7, 8, 9}}); + assert(determinant_lu(A1) == -48); + std::cout << "passed\n"; + + std::cout << "Determinant test 2..."; + matrix A2({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}); + assert(determinant_lu(A2) == 0); + std::cout << "passed\n"; + + std::cout << "Determinant test 3..."; + matrix A3({{1.2, 2.3, 3.4}, {4.5, 5.6, 6.7}, {7.8, 8.9, 9.0}}); + assert(determinant_lu(A3) == 3.63); + std::cout << "passed\n"; +} + +/** Main function */ +int main(int argc, char **argv) { + std::srand(std::time(NULL)); // random number initializer + + test1(); + test2(); return 0; } From 68dd9b1235f1d2a33d0a873a33ff55846bc8a4f6 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 15:22:02 -0400 Subject: [PATCH 137/261] added file documentation --- numerical_methods/lu_decomposition.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h index 22af249a5..4999fc40f 100644 --- a/numerical_methods/lu_decomposition.h +++ b/numerical_methods/lu_decomposition.h @@ -1,3 +1,10 @@ +/** + * @file lu_decomposition.h + * @author [Krishna Vedala](https://github.com/kvedala) + * @brief Functions associated with [LU + * Decomposition](https://en.wikipedia.org/wiki/LU_decomposition) + * of a square matrix. + */ #pragma once #include From 0429b5dd888030ce9b0c069875491aac1261660e Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 25 Jun 2020 18:01:41 -0400 Subject: [PATCH 138/261] fix documentation --- numerical_methods/lu_decompose.cpp | 2 +- numerical_methods/lu_decomposition.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/numerical_methods/lu_decompose.cpp b/numerical_methods/lu_decompose.cpp index b27fed2ee..66f1a8551 100644 --- a/numerical_methods/lu_decompose.cpp +++ b/numerical_methods/lu_decompose.cpp @@ -61,7 +61,7 @@ void test1() { } /** - * @brief Test determinant computation using LU decomposition + * Test determinant computation using LU decomposition */ void test2() { std::cout << "Determinant test 1..."; diff --git a/numerical_methods/lu_decomposition.h b/numerical_methods/lu_decomposition.h index 4999fc40f..402fe6e3b 100644 --- a/numerical_methods/lu_decomposition.h +++ b/numerical_methods/lu_decomposition.h @@ -78,7 +78,7 @@ int lu_decomposition(const matrix &A, matrix *L, matrix *U) { } /** - * @brief Compute determinant of an NxN square matrix using LU decomposition. + * Compute determinant of an NxN square matrix using LU decomposition. * Using LU decomposition, the determinant is given by the product of diagonal * elements of matrices L and U. * From b964f9af009a35018059a4bc08653774b71ee61a Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Fri, 26 Jun 2020 17:04:19 +0530 Subject: [PATCH 139/261] fix: minor typo --- numerical_methods/ordinary_least_squares_regressor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index bbd75a742..832d6edf7 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -369,7 +369,7 @@ int main() { std::vector Y(N); std::cout - << "Enter training data. Per sample, provide features ad one output." + << "Enter training data. Per sample, provide features and one output." << std::endl; for (size_t rows = 0; rows < N; rows++) { From 11a6542bf2704de3cbba22843fa8322e87569cc0 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:04:01 -0400 Subject: [PATCH 140/261] added test cases --- .../ordinary_least_squares_regressor.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index bbd75a742..d36a84042 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -9,6 +9,7 @@ * * \author [Krishna Vedala](https://github.com/kvedala) */ +#include #include // for print formatting #include #include @@ -352,10 +353,48 @@ std::vector predict_OLS_regressor(std::vector> const &X, return result; } +/** Self test checks */ +void test() { + int F = 3, N = 5; + + // test function = x^2 -5 + std::cout << "Test 1 (quadratic function)...."; + std::vector> data1( + {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}}); + std::vector Y1({20, -4, -5, -4, 31}); + std::vector beta1 = fit_OLS_regressor(data1, Y1); + std::vector> test1( + {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); + std::vector expected1({-1, -1, 95, 95}); + std::vector out1 = predict_OLS_regressor(test1, beta1); + for (size_t rows = 0; rows < out1.size(); rows++) + assert(std::abs(out1[rows] - expected1[rows]) < 0.01); // accuracy + std::cout << "passed\n"; + + // test function = x^3 + x^2 - 100 + std::cout << "Test 2 (cubic function)...."; + std::vector> data2( + {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}}); + std::vector Y2({-200, -100, -100, 98, 152}); + std::vector beta2 = fit_OLS_regressor(data2, Y2); + std::vector> test2( + {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); + std::vector expected2({-104, -88, -1000, 1000}); + std::vector out2 = predict_OLS_regressor(test2, beta2); + for (size_t rows = 0; rows < out2.size(); rows++) + assert(std::abs(out2[rows] - expected2[rows]) < 0.01); // accuracy + std::cout << "passed\n"; + + std::cout << std::endl; // ensure test results are displayed on screen + // (flush stdout) +} + /** * main function */ int main() { + test(); + size_t N, F; std::cout << "Enter number of features: "; From 6d127e3adfbbb0f64abb94d1800fa5f5c66ec3cc Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:09:34 -0400 Subject: [PATCH 141/261] added inline documentation --- .../ordinary_least_squares_regressor.cpp | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index d36a84042..614fdab9a 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -357,32 +357,46 @@ std::vector predict_OLS_regressor(std::vector> const &X, void test() { int F = 3, N = 5; - // test function = x^2 -5 + /* test function = x^2 -5 */ std::cout << "Test 1 (quadratic function)...."; + // create training data set with features = x, x^2, x^3 std::vector> data1( {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}}); + // create corresponding outputs std::vector Y1({20, -4, -5, -4, 31}); + // perform regression modelling std::vector beta1 = fit_OLS_regressor(data1, Y1); + // create test data set with same features = x, x^2, x^3 std::vector> test1( {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); + // expected regression outputs std::vector expected1({-1, -1, 95, 95}); + // predicted regression outputs std::vector out1 = predict_OLS_regressor(test1, beta1); + // compare predicted results are within +-0.01 limit of expected for (size_t rows = 0; rows < out1.size(); rows++) - assert(std::abs(out1[rows] - expected1[rows]) < 0.01); // accuracy + assert(std::abs(out1[rows] - expected1[rows]) < 0.01); std::cout << "passed\n"; - // test function = x^3 + x^2 - 100 + /* test function = x^3 + x^2 - 100 */ std::cout << "Test 2 (cubic function)...."; + // create training data set with features = x, x^2, x^3 std::vector> data2( {{-5, 25, -125}, {-1, 1, -1}, {0, 0, 0}, {1, 1, 1}, {6, 36, 216}}); + // create corresponding outputs std::vector Y2({-200, -100, -100, 98, 152}); + // perform regression modelling std::vector beta2 = fit_OLS_regressor(data2, Y2); + // create test data set with same features = x, x^2, x^3 std::vector> test2( {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); + // expected regression outputs std::vector expected2({-104, -88, -1000, 1000}); + // predicted regression outputs std::vector out2 = predict_OLS_regressor(test2, beta2); + // compare predicted results are within +-0.01 limit of expected for (size_t rows = 0; rows < out2.size(); rows++) - assert(std::abs(out2[rows] - expected2[rows]) < 0.01); // accuracy + assert(std::abs(out2[rows] - expected2[rows]) < 0.01); std::cout << "passed\n"; std::cout << std::endl; // ensure test results are displayed on screen From 0d2a58409e3c9c4a1c77878555b93c8de36c1a01 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:14:50 -0400 Subject: [PATCH 142/261] include cstdlib for std::abs() --- numerical_methods/ordinary_least_squares_regressor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index 614fdab9a..4761a6d96 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -10,6 +10,7 @@ * \author [Krishna Vedala](https://github.com/kvedala) */ #include +#include // for std::abs #include // for print formatting #include #include From 7ff384e59b5741b2b1d0ff981efa10ed891b5350 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:20:53 -0400 Subject: [PATCH 143/261] replace cstdlib with cmath for float overload of std::abs() --- numerical_methods/ordinary_least_squares_regressor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index 4761a6d96..7482d84da 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -10,7 +10,7 @@ * \author [Krishna Vedala](https://github.com/kvedala) */ #include -#include // for std::abs +#include // for std::abs #include // for print formatting #include #include From 9a8b6ddd2ee2854032245a348298a33fdaf8202d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 08:22:12 -0400 Subject: [PATCH 144/261] typo correction from #910 --- numerical_methods/ordinary_least_squares_regressor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index 7482d84da..dcbbcf8c7 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -423,7 +423,7 @@ int main() { std::vector Y(N); std::cout - << "Enter training data. Per sample, provide features ad one output." + << "Enter training data. Per sample, provide features and one output." << std::endl; for (size_t rows = 0; rows < N; rows++) { From 0690a140ecfbe55583186169577aab3b2cd16103 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 09:03:20 -0400 Subject: [PATCH 145/261] move OLS regressor to machine learning folder --- .../ordinary_least_squares_regressor.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {numerical_methods => machine_learning}/ordinary_least_squares_regressor.cpp (100%) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/machine_learning/ordinary_least_squares_regressor.cpp similarity index 100% rename from numerical_methods/ordinary_least_squares_regressor.cpp rename to machine_learning/ordinary_least_squares_regressor.cpp From dcd0d6b47864468cd9645e22e206e5b59bea4c6f Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Fri, 26 Jun 2020 13:04:18 +0000 Subject: [PATCH 146/261] updating DIRECTORY.md --- DIRECTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DIRECTORY.md b/DIRECTORY.md index 679e6f7d8..d678276bc 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -98,6 +98,7 @@ * [Adaline Learning](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/adaline_learning.cpp) * [Kohonen Som Topology](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/kohonen_som_topology.cpp) * [Kohonen Som Trace](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/kohonen_som_trace.cpp) + * [Ordinary Least Squares Regressor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/machine_learning/ordinary_least_squares_regressor.cpp) ## Math * [Armstrong Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/armstrong_number.cpp) @@ -145,7 +146,6 @@ * [Ode Forward Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_forward_euler.cpp) * [Ode Midpoint Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_midpoint_euler.cpp) * [Ode Semi Implicit Euler](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ode_semi_implicit_euler.cpp) - * [Ordinary Least Squares Regressor](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/ordinary_least_squares_regressor.cpp) * [Qr Decompose](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_decompose.h) * [Qr Decomposition](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_decomposition.cpp) * [Qr Eigen Values](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/qr_eigen_values.cpp) From 052c3fbca87802cc8ab95f5deb08bd94badab4fa Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 10:37:56 -0400 Subject: [PATCH 147/261] use better test function names to avoid conflict --- machine_learning/ordinary_least_squares_regressor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/machine_learning/ordinary_least_squares_regressor.cpp b/machine_learning/ordinary_least_squares_regressor.cpp index dcbbcf8c7..54d100300 100644 --- a/machine_learning/ordinary_least_squares_regressor.cpp +++ b/machine_learning/ordinary_least_squares_regressor.cpp @@ -355,7 +355,7 @@ std::vector predict_OLS_regressor(std::vector> const &X, } /** Self test checks */ -void test() { +void ols_test() { int F = 3, N = 5; /* test function = x^2 -5 */ @@ -408,7 +408,7 @@ void test() { * main function */ int main() { - test(); + ols_test(); size_t N, F; From b9c1f6bf363aa6e34fcaa664adafef3158ce7841 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 10:53:42 -0400 Subject: [PATCH 148/261] use better test data variable names to avoid conflict --- machine_learning/ordinary_least_squares_regressor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/machine_learning/ordinary_least_squares_regressor.cpp b/machine_learning/ordinary_least_squares_regressor.cpp index 54d100300..896504e20 100644 --- a/machine_learning/ordinary_least_squares_regressor.cpp +++ b/machine_learning/ordinary_least_squares_regressor.cpp @@ -368,12 +368,12 @@ void ols_test() { // perform regression modelling std::vector beta1 = fit_OLS_regressor(data1, Y1); // create test data set with same features = x, x^2, x^3 - std::vector> test1( + std::vector> test_data1( {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); // expected regression outputs std::vector expected1({-1, -1, 95, 95}); // predicted regression outputs - std::vector out1 = predict_OLS_regressor(test1, beta1); + std::vector out1 = predict_OLS_regressor(test_data1, beta1); // compare predicted results are within +-0.01 limit of expected for (size_t rows = 0; rows < out1.size(); rows++) assert(std::abs(out1[rows] - expected1[rows]) < 0.01); @@ -389,12 +389,12 @@ void ols_test() { // perform regression modelling std::vector beta2 = fit_OLS_regressor(data2, Y2); // create test data set with same features = x, x^2, x^3 - std::vector> test2( + std::vector> test_data2( {{-2, 4, -8}, {2, 4, 8}, {-10, 100, -1000}, {10, 100, 1000}}); // expected regression outputs std::vector expected2({-104, -88, -1000, 1000}); // predicted regression outputs - std::vector out2 = predict_OLS_regressor(test2, beta2); + std::vector out2 = predict_OLS_regressor(test_data2, beta2); // compare predicted results are within +-0.01 limit of expected for (size_t rows = 0; rows < out2.size(); rows++) assert(std::abs(out2[rows] - expected2[rows]) < 0.01); From 9379ae1a6c0731780c0b5260a553051ab5a46d82 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 13:46:46 -0400 Subject: [PATCH 149/261] added LGTM status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8734158b7..a6cde5f50 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # The Algorithms - C++ # {#mainpage} -[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp) [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) ![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square) ![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C-Plus-Plus?color=red&style=flat-square) From b3d85cd8e158bb6482735101762f6f73d6348e74 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 14:23:25 -0400 Subject: [PATCH 150/261] add LGTM status + remove HTML tags and use Markdown syntax Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a6cde5f50..53320a5b1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # The Algorithms - C++ # {#mainpage} + [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp) [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) -![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square) +[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)]("https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md") ![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C-Plus-Plus?color=red&style=flat-square) ![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/TheAlgorithms/C-Plus-Plus?color=green&style=flat-square) -![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg) -![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg) +[![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)]("https://TheAlgorithms.github.io/C-Plus-Plus") +[![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)]("https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22") [Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus). From c5933c8525452c300ef961881bf883646db359dc Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 14:29:10 -0400 Subject: [PATCH 151/261] updated project summary description Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 53320a5b1..aa0f96e80 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,15 @@ [![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)]("https://TheAlgorithms.github.io/C-Plus-Plus") [![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)]("https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22") -[Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus). +## Algorithms implemented in C++ (for education) +The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations are meant to be a learning resource for educators and students. Hence, one may find more than one implementation for the same algorithm with different optimizations and different strategies used that would be documented therein. + +## Documentation + +[Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus) is generated from the repository source codes directly. The documentation contains all resources including source code snippets, details on execution of the programs, diagrammatic representation of program flow, and links to external resources where necessary. The documentation also introduces interactive source code with links to documentation for C++ STL library functions used. Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to see the list of all the files documented with the code. -### Algorithms implemented in C++ (for education) -The implementations are for learning purpose. They may be less efficient than the implementation in the standard library. +## Contributions -### Contribute Guidelines -Read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md) before you contribute. +As a community developed and community maintained repository, we welcome new un-plagiarized contributions. Read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md) before you contribute. From aa16f4d113c028be73c9871d554b95e233ede32d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 14:29:45 -0400 Subject: [PATCH 152/261] added features description Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index aa0f96e80..bb8d32dcb 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,16 @@ The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations are meant to be a learning resource for educators and students. Hence, one may find more than one implementation for the same algorithm with different optimizations and different strategies used that would be documented therein. +## Features + +* The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B). +* Well documented source code with detailed explanations provide a valuable resource for educators and students alike. +* Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth. +* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. +* Strict adherence [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc with little to no changes. +* Self-checks within programs ensure correct implementations with confidence. +* Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications. + ## Documentation [Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus) is generated from the repository source codes directly. The documentation contains all resources including source code snippets, details on execution of the programs, diagrammatic representation of program flow, and links to external resources where necessary. The documentation also introduces interactive source code with links to documentation for C++ STL library functions used. From 54dcadf07d5e7810655172fb9ed9f3b94e714c2a Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 14:38:03 -0400 Subject: [PATCH 153/261] fix contributions description Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb8d32dcb..f711c58b8 100644 --- a/README.md +++ b/README.md @@ -29,4 +29,4 @@ Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to ## Contributions -As a community developed and community maintained repository, we welcome new un-plagiarized contributions. Read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md) before you contribute. +As a community developed and community maintained repository, we welcome new un-plagiarized quality contributions. Please read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md). From a9c005da70569a168ffaf17ddd3ee286a6bd31dd Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 14:49:05 -0400 Subject: [PATCH 154/261] overview + comment why mainpage Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f711c58b8..0dfb173bf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # The Algorithms - C++ # {#mainpage} + [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp) [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) @@ -8,7 +9,7 @@ [![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)]("https://TheAlgorithms.github.io/C-Plus-Plus") [![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)]("https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22") -## Algorithms implemented in C++ (for education) +## Overview The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations are meant to be a learning resource for educators and students. Hence, one may find more than one implementation for the same algorithm with different optimizations and different strategies used that would be documented therein. @@ -18,7 +19,7 @@ The repository is a collection of implementation of a variety of algorithms impl * Well documented source code with detailed explanations provide a valuable resource for educators and students alike. * Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth. * Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. -* Strict adherence [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc with little to no changes. +* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc with little to no changes. * Self-checks within programs ensure correct implementations with confidence. * Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications. From 8f72445a6dcce05be377bcaf31495385c0f1baf4 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 20:14:36 -0400 Subject: [PATCH 155/261] minor punctuations --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0dfb173bf..e5755c3a5 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ The repository is a collection of implementation of a variety of algorithms impl * The repository provides implementations of various algorithms in one of the most fundamental general purpose languages - [C++](https://en.wikipedia.org/wiki/C%2B%2B). * Well documented source code with detailed explanations provide a valuable resource for educators and students alike. * Each source code is atomic using [STL classes](https://en.wikipedia.org/wiki/Standard_Template_Library) and _no external libraries_ are required for their compilation and execution. Thus the fundamentals of the algorithms can be studied in much depth. -* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. -* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc with little to no changes. +* Source codes are [compiled and tested](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) for every commit on the latest versions of three major operating systems viz., Windows, MacOS and Ubuntu (Linux) using MSVC 16 2019, AppleClang 11.0 and GNU 7.5.0 respectively. +* Strict adherence to [C++11](https://en.wikipedia.org/wiki/C%2B%2B11) standard ensures portability of code to embedded systems as well like ESP32, ARM Cortex, etc. with little to no changes. * Self-checks within programs ensure correct implementations with confidence. * Modular implementations and OpenSource licensing enable the functions to be utilized conveniently in other applications. From 0f42f8f96ca404a90ef9b9a24293782c00f8505e Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 20:20:43 -0400 Subject: [PATCH 156/261] apply suggestions by reviewers --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e5755c3a5..e99ec1311 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Overview -The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations are meant to be a learning resource for educators and students. Hence, one may find more than one implementation for the same algorithm with different optimizations and different strategies used that would be documented therein. +The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. ## Features @@ -30,4 +30,4 @@ Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to ## Contributions -As a community developed and community maintained repository, we welcome new un-plagiarized quality contributions. Please read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md). +As a community developed and maintained repository, we welcome new un-plagiarized quality contributions. Please read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md). From 7218eeb5b8440499d4ce477255486fd788ecc91d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 20:36:03 -0400 Subject: [PATCH 157/261] initial cipher folder commit --- ciphers/CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 ciphers/CMakeLists.txt diff --git a/ciphers/CMakeLists.txt b/ciphers/CMakeLists.txt new file mode 100644 index 000000000..1efde3087 --- /dev/null +++ b/ciphers/CMakeLists.txt @@ -0,0 +1,18 @@ +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + if(OpenMP_CXX_FOUND) + target_link_libraries(${testname} OpenMP::OpenMP_CXX) + endif() + install(TARGETS ${testname} DESTINATION "bin/ciphers") + +endforeach( testsourcefile ${APP_SOURCES} ) From db28999ca3f01f0bf779875ccf7295d354ff8ade Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 20:36:46 -0400 Subject: [PATCH 158/261] initial hill-cipher commit - does not execute corectly --- ciphers/hill_cipher.cpp | 411 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 ciphers/hill_cipher.cpp diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp new file mode 100644 index 000000000..10fed923d --- /dev/null +++ b/ciphers/hill_cipher.cpp @@ -0,0 +1,411 @@ +/** + * @file hill_cipher.cpp + * @author [Krishna Vedala](https://github.com/kvedala) + * @brief Implementation of [Hill + * cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm. + * + * Program to generate the encryption-decryption key and perform encryption and + * decryption of ASCII text. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _OPENMP +#include +#endif + +#include "../numerical_methods/lu_decomposition.h" + +/** + * operator to print a matrix + */ +template +static std::ostream &operator<<(std::ostream &out, matrix const &v) { + const int width = 15; + const char separator = ' '; + + for (size_t row = 0; row < v.size(); row++) { + for (size_t col = 0; col < v[row].size(); col++) + out << std::left << std::setw(width) << std::setfill(separator) + << v[row][col]; + out << std::endl; + } + + return out; +} + +/** \namespace ciphers + * \brief Algorithms for encryption and decryption + */ +namespace ciphers { +/** dictionary of characters that can be encrypted and decrypted */ +static const std::string STRKEY = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&" + "*()_+`-=[]{}|;':\",./<>?\\\r\n "; + +/** + * @brief Implementation of [Hill + * Cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm + */ +class HillCipher { + private: + /** + * @brief Function to generate a random integer in a given interval + * + * @param a lower limit of interval + * @param b upper limit of interval + * @tparam T type of output + * @return random integer in the interval \f$[a,b)\f$ + */ + template + static const T2 rand_range(T1 a, T1 b) { + // generate random number between 0 and 1 + long double r = static_cast(std::rand()) / RAND_MAX; + + // scale and return random number as integer + return static_cast(r * (b - a) + a); + } + + /** + * @brief Function overload to fill a matrix with random integers in a given + * interval + * + * @param M pointer to matrix to be filled with random numbers + * @param a lower limit of interval + * @param b upper limit of interval + * @tparam T1 type of input range + * @tparam T2 type of matrix + * @return determinant of generated random matrix + */ + template + static const double rand_range(matrix *M, T1 a, T1 b) { + for (size_t i = 0; i < M->size(); i++) { + for (size_t j = 0; j < M[0][0].size(); j++) { + M[0][i][j] = rand_range(a, b); + } + } + + return determinant_lu(*M); + } + + /** + * @brief Compute + * [GCD](https://en.wikipedia.org/wiki/Greatest_common_divisor) of two + * integers using Euler's algorithm + * + * @param a first number + * @param b second number + * @return GCD of \f$a\f$ and \f$b\f$ + */ + template + static const T gcd(T a, T b) { + if (b > a) // ensure always a < b + std::swap(a, b); + + while (b != 0) { + T tmp = b; + b = a % b; + a = tmp; + } + + return a; + } + + /** + * @brief helper function to perform vector multiplication with encryption + * or decryption matrix + * + * @param vector vector to multiply + * @param key encryption or decryption key matrix + * @return corresponding encrypted or decrypted text + */ + static const std::valarray mat_mul( + const std::valarray &vector, const matrix &key) { + std::valarray out(vector); // make a copy + + for (size_t i = 0; i < key.size(); i++) { + int tmp = 0; + for (size_t j = 0; j < vector.size(); j++) { + tmp += key[i][j] * vector[j]; + } + out[i] = static_cast(tmp % STRKEY.length()); + } + + return out; + } + + /** + * @brief Convenience function to perform block cipher operations. The + * operations are identical for both encryption and decryption. + * + * @param text input text to encrypt or decrypt + * @param key key for encryption or decryption + * @return encrypted/decrypted output + */ + static const std::string codec(const std::string &text, + const matrix &key) { + size_t text_len = text.length(); + size_t key_len = key.size(); + + // length of output string must be a multiple of key_len + // create output string and initialize with '\0' character + size_t L2 = text_len % key_len == 0 + ? text_len + : text_len + key_len - (text_len % key_len); + std::string coded_text(L2, '\0'); + + // temporary array for batch processing + std::valarray batch_int(key_len); + for (size_t i = 0; i < L2 - key_len + 1; i += key_len) { + for (size_t j = 0; j < key_len; j++) { + batch_int[j] = static_cast( + STRKEY.find(text[i + j])); // get index of character in key + } + + batch_int = mat_mul(batch_int, key); + + for (size_t j = 0; j < key_len; j++) { + coded_text[i + j] = + STRKEY[batch_int[j]]; // get character at key + } + } + + return coded_text; + } + + /** + * Get matrix inverse using Row-transformations. Given matrix must + * be a square and non-singular. + * \returns inverse matrix + **/ + template + static matrix get_inverse(matrix const &A) { + // Assuming A is square matrix + size_t N = A.size(); + + matrix inverse(N, std::valarray(N)); + for (size_t row = 0; row < N; row++) { + for (size_t col = 0; col < N; col++) { + // create identity matrix + inverse[row][col] = (row == col) ? 1.f : 0.f; + } + } + + if (A.size() != A[0].size()) { + std::cerr << "A must be a square matrix!" << std::endl; + return inverse; + } + + // preallocate a temporary matrix identical to A + matrix temp(N, std::valarray(N)); + for (size_t row = 0; row < N; row++) { + for (size_t col = 0; col < N; col++) + temp[row][col] = static_cast(A[row][col]); + } + + // start transformations + for (size_t row = 0; row < N; row++) { + for (size_t row2 = row; row2 < N && temp[row][row] == 0; row2++) { + // this to ensure diagonal elements are not 0 + temp[row] = temp[row] + temp[row2]; + inverse[row] = inverse[row] + inverse[row2]; + } + + for (size_t col2 = row; col2 < N && temp[row][row] == 0; col2++) { + // this to further ensure diagonal elements are not 0 + for (size_t row2 = 0; row2 < N; row2++) { + temp[row2][row] = temp[row2][row] + temp[row2][col2]; + inverse[row2][row] = + inverse[row2][row] + inverse[row2][col2]; + } + } + + if (temp[row][row] == 0) { + // Probably a low-rank matrix and hence singular + std::cerr << "Low-rank matrix, no inverse!" << std::endl; + return inverse; + } + + // set diagonal to 1 + double divisor = temp[row][row]; + temp[row] = temp[row] / divisor; + inverse[row] = inverse[row] / divisor; + // Row transformations + for (size_t row2 = 0; row2 < N; row2++) { + if (row2 == row) + continue; + double factor = temp[row2][row]; + temp[row2] = temp[row2] - factor * temp[row]; + inverse[row2] = inverse[row2] - factor * inverse[row]; + } + } + + return inverse; + } + + static int modulo(int a, int b) { + int ret = a % b; + if (ret < 0) + ret += b; + return ret; + } + + public: + /** + * @brief Generate encryption matrix of a given size. Larger size matrices + * are difficult to generate but provide more security. + * + * @param size size of matrix (typically \f$\text{size}\le10\f$) + * @return Encryption martix + */ + static matrix generate_encryption_key(size_t size) { + matrix encrypt_key(size, std::valarray(size)); + int mat_determinant = -1; // because matrix has only ints, the + // determinant will also be an int + + int L = static_cast(STRKEY.length()); + + double dd; + do { + dd = rand_range(&encrypt_key, 0, L); + mat_determinant = static_cast(dd); + + if (mat_determinant < 0) + mat_determinant = (mat_determinant % L) + L; + } while (dd <= 0.1 || // while singular or ill-defined + !std::isfinite(dd) || // while determinant is not finite + gcd(mat_determinant, L) != 1); // while no common factors + // std::cout << + + return encrypt_key; + } + + /** + * @brief Generate decryption matrix from an encryption matrix key. + * + * @param encrypt_key encryption key for which to create a decrypt key + * @return Decryption martix + */ + static matrix generate_decryption_key(matrix const &encrypt_key) { + size_t size = encrypt_key.size(); + int L = static_cast(STRKEY.length()); + + matrix decrypt_key(size, std::valarray(size)); + int det_encrypt = static_cast(determinant_lu(encrypt_key)); + + int mat_determinant = det_encrypt < 0 ? det_encrypt % L : det_encrypt; + + matrix tmp_inverse = get_inverse(encrypt_key); + double d2 = determinant_lu(decrypt_key); + + // find co-prime factor for inversion + int det_inv = -1; + for (int i = 0; i < L; i++) { + if (modulo(mat_determinant * i, L) == 1) { + det_inv = i; + break; + } + } + + if (det_inv == -1) { + std::cerr << "Could not find a co-prime for inversion\n"; + std::exit(EXIT_FAILURE); + } + + mat_determinant = det_inv * det_encrypt; + + // perform modular inverse of encryption matrix + int i; +#ifdef _OPENMP +#pragma parallel omp for private(i) +#endif + for (i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + int temp = std::round(tmp_inverse[i][j] * mat_determinant); + decrypt_key[i][j] = modulo(temp, L); + } + } + return decrypt_key; + } + + /** + * @brief Generate encryption and decryption key pair + * + * @param size size of matrix key (typically \f$\text{size}\le10\f$) + * @return std::pair, matrix> encryption and decryption + * keys as a pair + */ + static std::pair, matrix> generate_keys(size_t size) { + matrix encrypt_key = generate_encryption_key(size); + matrix decrypt_key = generate_decryption_key(encrypt_key); + double det2 = determinant_lu(decrypt_key); + while (det2 < 0.1) { + encrypt_key = generate_encryption_key(size); + decrypt_key = generate_decryption_key(encrypt_key); + det2 = determinant_lu(decrypt_key); + } + return std::make_pair(encrypt_key, decrypt_key); + } + + /** + * @brief Encrypt a given text using a given key + * + * @param text string to encrypt + * @param encrypt_key key for encryption + * @return encrypted text + */ + static const std::string encrypt_text(const std::string &text, + const matrix &encrypt_key) { + return codec(text, encrypt_key); + } + + /** + * @brief Decrypt a given text using a given key + * + * @param text string to decrypt + * @param decrypt_key key for decryption + * @return decrypted text + */ + static const std::string decrypt_text(const std::string &text, + const matrix &decrypt_key) { + return codec(text, decrypt_key); + } +}; + +} // namespace ciphers + +/** Main function */ +int main() { + std::srand(std::time(nullptr)); + + std::cout << "Key dictionary: (" << ciphers::STRKEY.length() << ")\n\t" + << ciphers::STRKEY << "\n"; + + std::string text = "This is a simple text with numb3r5 and exclamat!0n."; + // std::string text = "Hello world!"; + std::cout << "Original text:\n\t" << text << std::endl; + + std::pair, matrix> p = + ciphers::HillCipher::generate_keys(5); + matrix ekey = p.first; + matrix dkey = p.second; + // matrix ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}}; + // std::cout << "Encryption key: \n" << ekey; + std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey); + std::cout << "Encrypted text:\n\t" << gibberish << std::endl; + + // matrix dkey = ciphers::HillCipher::generate_decryption_key(ekey); + // std::cout << "Decryption key: \n" << dkey; + std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); + std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; + + assert(txt_back == text); + + return 0; +} From 0b57b895439bb6c7539851f5ef42c2b2195bedf8 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 27 Jun 2020 00:37:39 +0000 Subject: [PATCH 159/261] updating DIRECTORY.md --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 679e6f7d8..a3c66cd96 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -10,6 +10,9 @@ * [Rat Maze](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/rat_maze.cpp) * [Sudoku Solve](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/backtracking/sudoku_solve.cpp) +## Ciphers + * [Hill Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/hill_cipher.cpp) + ## Data Structures * [Avltree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/avltree.cpp) * [Binary Search Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/binary_search_tree.cpp) From bade62d0633965f4816b2022717eaf597a6981b6 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 21:44:02 -0400 Subject: [PATCH 160/261] working hill cipher --- ciphers/hill_cipher.cpp | 80 ++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index 10fed923d..59ce73705 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -5,15 +5,31 @@ * cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm. * * Program to generate the encryption-decryption key and perform encryption and - * decryption of ASCII text. + * decryption of ASCII text using the famous block cipher algorithm. This is a + * powerful encryption algorithm that is relatively easy to implement with a + * given key. The strength of the algorithm depends on the size of the block + * encryption matrix key; the bigger the matrix, the stronger the encryption and + * more difficult to break it. However, the important requirement for the matrix + * is that: + * 1. matrix should be invertible - all inversion conditions should be satisfied + * and + * 2. its determinant must not have any common factors with the length of + * character set + * Due to this restriction, most implementations only implement with small 3x3 + * encryption keys and a small subset of ASCII alphabets. + * + * In the current implementation, I present to you an implementation for + * generating larger encryption keys (I have attempted upto 10x10) and an ASCII + * character set of 97 printable characters. Hence, a typical ASCII text file + * could be easily encrypted with the module. */ #include #include +#include #include #include #include -#include #include #include #ifdef _OPENMP @@ -45,7 +61,7 @@ static std::ostream &operator<<(std::ostream &out, matrix const &v) { */ namespace ciphers { /** dictionary of characters that can be encrypted and decrypted */ -static const std::string STRKEY = +static const char *STRKEY = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&" "*()_+`-=[]{}|;':\",./<>?\\\r\n "; @@ -129,17 +145,41 @@ class HillCipher { const std::valarray &vector, const matrix &key) { std::valarray out(vector); // make a copy + size_t L = std::strlen(STRKEY); + for (size_t i = 0; i < key.size(); i++) { int tmp = 0; for (size_t j = 0; j < vector.size(); j++) { tmp += key[i][j] * vector[j]; } - out[i] = static_cast(tmp % STRKEY.length()); + out[i] = static_cast(tmp % L); } return out; } + /** + * @brief Get the character at a given index in the ::STRKEY + * + * @param idx index value + * @return character at the index + */ + static inline char get_idx_char(const uint8_t idx) { return STRKEY[idx]; } + + /** + * @brief Get the index of a character in the ::STRKEY + * + * @param ch character to search + * @return index of character + */ + static inline uint8_t get_char_idx(const char ch) { + size_t L = std::strlen(STRKEY); + + for (uint8_t idx = 0; idx < L; idx++) + if (STRKEY[idx] == ch) + return idx; + } + /** * @brief Convenience function to perform block cipher operations. The * operations are identical for both encryption and decryption. @@ -164,8 +204,7 @@ class HillCipher { std::valarray batch_int(key_len); for (size_t i = 0; i < L2 - key_len + 1; i += key_len) { for (size_t j = 0; j < key_len; j++) { - batch_int[j] = static_cast( - STRKEY.find(text[i + j])); // get index of character in key + batch_int[j] = get_char_idx(text[i + j]); } batch_int = mat_mul(batch_int, key); @@ -259,26 +298,33 @@ class HillCipher { public: /** * @brief Generate encryption matrix of a given size. Larger size matrices - * are difficult to generate but provide more security. + * are difficult to generate but provide more security. Important conditions + * are: + * 1. matrix should be invertible + * 2. determinant must not have any common factors with the length of + * character key * * @param size size of matrix (typically \f$\text{size}\le10\f$) * @return Encryption martix */ static matrix generate_encryption_key(size_t size) { matrix encrypt_key(size, std::valarray(size)); + matrix min_mat = encrypt_key; int mat_determinant = -1; // because matrix has only ints, the // determinant will also be an int - - int L = static_cast(STRKEY.length()); + int L = std::strlen(STRKEY); double dd; do { - dd = rand_range(&encrypt_key, 0, L); + // keeping the random number range smaller generates better + // defined matrices with more ease of cracking + dd = rand_range(&encrypt_key, 0, 10); mat_determinant = static_cast(dd); if (mat_determinant < 0) - mat_determinant = (mat_determinant % L) + L; - } while (dd <= 0.1 || // while singular or ill-defined + mat_determinant = (mat_determinant % L); + } while (std::abs(dd) > 1e3 || // while ill-defined + dd < 0.1 || // while singular !std::isfinite(dd) || // while determinant is not finite gcd(mat_determinant, L) != 1); // while no common factors // std::cout << @@ -294,7 +340,7 @@ class HillCipher { */ static matrix generate_decryption_key(matrix const &encrypt_key) { size_t size = encrypt_key.size(); - int L = static_cast(STRKEY.length()); + int L = std::strlen(STRKEY); matrix decrypt_key(size, std::valarray(size)); int det_encrypt = static_cast(determinant_lu(encrypt_key)); @@ -384,7 +430,7 @@ class HillCipher { int main() { std::srand(std::time(nullptr)); - std::cout << "Key dictionary: (" << ciphers::STRKEY.length() << ")\n\t" + std::cout << "Key dictionary: (" << std::strlen(ciphers::STRKEY) << ")\n\t" << ciphers::STRKEY << "\n"; std::string text = "This is a simple text with numb3r5 and exclamat!0n."; @@ -392,16 +438,16 @@ int main() { std::cout << "Original text:\n\t" << text << std::endl; std::pair, matrix> p = - ciphers::HillCipher::generate_keys(5); + ciphers::HillCipher::generate_keys(8); matrix ekey = p.first; matrix dkey = p.second; // matrix ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}}; - // std::cout << "Encryption key: \n" << ekey; + std::cout << "Encryption key: \n" << ekey; std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey); std::cout << "Encrypted text:\n\t" << gibberish << std::endl; // matrix dkey = ciphers::HillCipher::generate_decryption_key(ekey); - // std::cout << "Decryption key: \n" << dkey; + std::cout << "Decryption key: \n" << dkey; std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; From f932aed5d2aebc4fe1febcdb8a3583a505ac72b4 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 22:02:21 -0400 Subject: [PATCH 161/261] more docs + more control on matrix creation --- ciphers/hill_cipher.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index 59ce73705..f1382f57e 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #ifdef _OPENMP @@ -98,6 +99,12 @@ class HillCipher { * @tparam T1 type of input range * @tparam T2 type of matrix * @return determinant of generated random matrix + * + * @warning There will need to be a balance between the matrix size and the + * range of random numbers. If the matrix is large, the range of random + * numbers must be small to have a well defined keys. Or if the matrix is + * smaller, the random numbers range can be larger. For an 8x8 matrix, range + * should be no more than \f$[0,10]\f$ */ template static const double rand_range(matrix *M, T1 a, T1 b) { @@ -303,11 +310,18 @@ class HillCipher { * 1. matrix should be invertible * 2. determinant must not have any common factors with the length of * character key + * There is no head-fast way to generate hte matrix under the given + * numerical restrictions of the machine but the conditions added achieve + * the goals. Bigger the matrix, greater is the probability of the matrix + * being ill-defined. * * @param size size of matrix (typically \f$\text{size}\le10\f$) + * @param limit1 lower limit of range of random elements (default=0) + * @param limit2 upper limit of range of random elements (default=10) * @return Encryption martix */ - static matrix generate_encryption_key(size_t size) { + static matrix generate_encryption_key(size_t size, int limit1 = 0, + int limit2 = 10) { matrix encrypt_key(size, std::valarray(size)); matrix min_mat = encrypt_key; int mat_determinant = -1; // because matrix has only ints, the @@ -318,7 +332,7 @@ class HillCipher { do { // keeping the random number range smaller generates better // defined matrices with more ease of cracking - dd = rand_range(&encrypt_key, 0, 10); + dd = rand_range(&encrypt_key, limit1, limit2); mat_determinant = static_cast(dd); if (mat_determinant < 0) @@ -384,15 +398,21 @@ class HillCipher { * @brief Generate encryption and decryption key pair * * @param size size of matrix key (typically \f$\text{size}\le10\f$) + * @param limit1 lower limit of range of random elements (default=0) + * @param limit2 upper limit of range of random elements (default=10) * @return std::pair, matrix> encryption and decryption * keys as a pair + * + * @see ::generate_encryption_key */ - static std::pair, matrix> generate_keys(size_t size) { + static std::pair, matrix> generate_keys(size_t size, + int limit1 = 0, + int limit2 = 10) { matrix encrypt_key = generate_encryption_key(size); matrix decrypt_key = generate_decryption_key(encrypt_key); double det2 = determinant_lu(decrypt_key); - while (det2 < 0.1) { - encrypt_key = generate_encryption_key(size); + while (std::abs(det2) < 0.1 || std::abs(det2) > 1e3) { + encrypt_key = generate_encryption_key(size, limit1, limit2); decrypt_key = generate_decryption_key(encrypt_key); det2 = determinant_lu(decrypt_key); } @@ -438,20 +458,20 @@ int main() { std::cout << "Original text:\n\t" << text << std::endl; std::pair, matrix> p = - ciphers::HillCipher::generate_keys(8); + ciphers::HillCipher::generate_keys(10, 0, 5); matrix ekey = p.first; matrix dkey = p.second; // matrix ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}}; - std::cout << "Encryption key: \n" << ekey; + // std::cout << "Encryption key: \n" << ekey; std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey); std::cout << "Encrypted text:\n\t" << gibberish << std::endl; // matrix dkey = ciphers::HillCipher::generate_decryption_key(ekey); - std::cout << "Decryption key: \n" << dkey; + // std::cout << "Decryption key: \n" << dkey; std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; - assert(txt_back == text); + assert((txt_back == text) == true); return 0; } From fc489f7f4514eee705c76e84d908f7b83669840c Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 26 Jun 2020 23:42:16 -0400 Subject: [PATCH 162/261] test2 + refinements --- ciphers/hill_cipher.cpp | 88 +++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index f1382f57e..cdcd795d4 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -1,6 +1,5 @@ /** * @file hill_cipher.cpp - * @author [Krishna Vedala](https://github.com/kvedala) * @brief Implementation of [Hill * cipher](https://en.wikipedia.org/wiki/Hill_cipher) algorithm. * @@ -21,7 +20,14 @@ * In the current implementation, I present to you an implementation for * generating larger encryption keys (I have attempted upto 10x10) and an ASCII * character set of 97 printable characters. Hence, a typical ASCII text file - * could be easily encrypted with the module. + * could be easily encrypted with the module. The larger character set increases + * the modulo of cipher and hence the matrix determinants can get very large + * very quickly rendering them ill-defined. + * + * \note This program uses determinant computation using LU decomposition from + * the file lu_decomposition.h + * + * @author [Krishna Vedala](https://github.com/kvedala) */ #include @@ -31,8 +37,6 @@ #include #include #include -#include -#include #ifdef _OPENMP #include #endif @@ -64,7 +68,7 @@ namespace ciphers { /** dictionary of characters that can be encrypted and decrypted */ static const char *STRKEY = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&" - "*()_+`-=[]{}|;':\",./<>?\\\r\n "; + "*()_+`-=[]{}|;':\",./<>?\\\r\n \0"; /** * @brief Implementation of [Hill @@ -182,9 +186,13 @@ class HillCipher { static inline uint8_t get_char_idx(const char ch) { size_t L = std::strlen(STRKEY); - for (uint8_t idx = 0; idx < L; idx++) + for (uint8_t idx = 0; idx <= L; idx++) if (STRKEY[idx] == ch) return idx; + + std::cerr << __func__ << ":" << __LINE__ << ": (" << ch + << ") Should not reach here!\n"; + return 0; } /** @@ -208,8 +216,12 @@ class HillCipher { std::string coded_text(L2, '\0'); // temporary array for batch processing - std::valarray batch_int(key_len); - for (size_t i = 0; i < L2 - key_len + 1; i += key_len) { + int i; +#ifdef _OPENMP +#pragma parallel omp for private(i) +#endif + for (i = 0; i < L2 - key_len + 1; i += key_len) { + std::valarray batch_int(key_len); for (size_t j = 0; j < key_len; j++) { batch_int[j] = get_char_idx(text[i + j]); } @@ -338,7 +350,7 @@ class HillCipher { if (mat_determinant < 0) mat_determinant = (mat_determinant % L); } while (std::abs(dd) > 1e3 || // while ill-defined - dd < 0.1 || // while singular + std::abs(dd) < 0.1 || // while singular !std::isfinite(dd) || // while determinant is not finite gcd(mat_determinant, L) != 1); // while no common factors // std::cout << @@ -446,21 +458,21 @@ class HillCipher { } // namespace ciphers -/** Main function */ -int main() { - std::srand(std::time(nullptr)); - - std::cout << "Key dictionary: (" << std::strlen(ciphers::STRKEY) << ")\n\t" - << ciphers::STRKEY << "\n"; - - std::string text = "This is a simple text with numb3r5 and exclamat!0n."; +/** + * @brief Self test 1 - using 3x3 randomly generated key + * + * @param text string to encrypt and decrypt + */ +void test1(const std::string &text) { // std::string text = "Hello world!"; - std::cout << "Original text:\n\t" << text << std::endl; + std::cout << "======Test 1 (3x3 key) ======\nOriginal text:\n\t" << text + << std::endl; std::pair, matrix> p = - ciphers::HillCipher::generate_keys(10, 0, 5); + ciphers::HillCipher::generate_keys(3, 0, 100); matrix ekey = p.first; matrix dkey = p.second; + // matrix ekey = {{22, 28, 25}, {5, 26, 15}, {14, 18, 9}}; // std::cout << "Encryption key: \n" << ekey; std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey); @@ -471,7 +483,43 @@ int main() { std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; - assert((txt_back == text) == true); + assert(txt_back == text); +} + +/** + * @brief Self test 2 - using 8x8 randomly generated key + * + * @param text string to encrypt and decrypt + */ +void test2(const std::string &text) { + // std::string text = "Hello world!"; + std::cout << "======Test 2 (8x8 key) ======\nOriginal text:\n\t" << text + << std::endl; + + std::pair, matrix> p = + ciphers::HillCipher::generate_keys(8, 0, 10); + matrix ekey = p.first; + matrix dkey = p.second; + + std::string gibberish = ciphers::HillCipher::encrypt_text(text, ekey); + std::cout << "Encrypted text:\n\t" << gibberish << std::endl; + + std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); + std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; + + assert(text.compare(0, text.length() - 1, txt_back) == 0); +} + +/** Main function */ +int main() { + std::srand(std::time(nullptr)); + std::cout << "Key dictionary: (" << std::strlen(ciphers::STRKEY) << ")\n\t" + << ciphers::STRKEY << "\n"; + + std::string text = "This is a simple text with numb3r5 and exclamat!0n."; + + test1(text); + test2(text); return 0; } From 541f762deb37990d8c38bd50e76b95f12464adb8 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 14:43:11 -0400 Subject: [PATCH 163/261] working algorithm --- ciphers/hill_cipher.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index cdcd795d4..4c8c87d26 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -484,6 +484,7 @@ void test1(const std::string &text) { std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; assert(txt_back == text); + std::cout << "Passed :)\n"; } /** @@ -497,7 +498,7 @@ void test2(const std::string &text) { << std::endl; std::pair, matrix> p = - ciphers::HillCipher::generate_keys(8, 0, 10); + ciphers::HillCipher::generate_keys(8, 0, 5); matrix ekey = p.first; matrix dkey = p.second; @@ -507,7 +508,8 @@ void test2(const std::string &text) { std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; - assert(text.compare(0, text.length() - 1, txt_back) == 0); + assert(txt_back.compare(0, text.size(), text) == 0); + std::cout << "Passed :)\n"; } /** Main function */ From e8849dc36f149906220d7108c4fded29c2ce5f58 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 15:45:48 -0400 Subject: [PATCH 164/261] save keys to file + more docs --- ciphers/hill_cipher.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index 4c8c87d26..45315e088 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -26,6 +26,9 @@ * * \note This program uses determinant computation using LU decomposition from * the file lu_decomposition.h + * \note The matrix generation algorithm is very rudimentary and does not + * guarantee an invertible modulus matrix. \todo Better matrix generation + * algorithm. * * @author [Krishna Vedala](https://github.com/kvedala) */ @@ -34,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -350,7 +354,7 @@ class HillCipher { if (mat_determinant < 0) mat_determinant = (mat_determinant % L); } while (std::abs(dd) > 1e3 || // while ill-defined - std::abs(dd) < 0.1 || // while singular + dd < 0.1 || // while singular or negative determinant !std::isfinite(dd) || // while determinant is not finite gcd(mat_determinant, L) != 1); // while no common factors // std::cout << @@ -483,6 +487,12 @@ void test1(const std::string &text) { std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; + std::ofstream out_file("hill_cipher_test1.txt"); + out_file << "Block size: " << ekey.size() << "\n"; + out_file << "Encryption Key:\n" << ekey; + out_file << "\nDecryption Key:\n" << dkey; + out_file.close(); + assert(txt_back == text); std::cout << "Passed :)\n"; } @@ -498,7 +508,7 @@ void test2(const std::string &text) { << std::endl; std::pair, matrix> p = - ciphers::HillCipher::generate_keys(8, 0, 5); + ciphers::HillCipher::generate_keys(8, 0, 3); matrix ekey = p.first; matrix dkey = p.second; @@ -508,6 +518,12 @@ void test2(const std::string &text) { std::string txt_back = ciphers::HillCipher::decrypt_text(gibberish, dkey); std::cout << "Reconstruct text:\n\t" << txt_back << std::endl; + std::ofstream out_file("hill_cipher_test2.txt"); + out_file << "Block size: " << ekey.size() << "\n"; + out_file << "Encryption Key:\n" << ekey; + out_file << "\nDecryption Key:\n" << dkey; + out_file.close(); + assert(txt_back.compare(0, text.size(), text) == 0); std::cout << "Passed :)\n"; } From 25c2b82e51b3311998973168e2a9b9c0a3f643c7 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 15:49:46 -0400 Subject: [PATCH 165/261] include ciphers folder in cmake compilation Signed-off-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index adb1c740a..712c3db42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ endif() add_subdirectory(math) add_subdirectory(others) add_subdirectory(search) +add_subdirectory(ciphers) add_subdirectory(strings) add_subdirectory(sorting) add_subdirectory(geometry) From 12799c561691ca8d15cd3454bae1d427f5dc6feb Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 16:00:12 -0400 Subject: [PATCH 166/261] fix lgtm errors --- ciphers/hill_cipher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ciphers/hill_cipher.cpp b/ciphers/hill_cipher.cpp index 45315e088..1fef0f32e 100644 --- a/ciphers/hill_cipher.cpp +++ b/ciphers/hill_cipher.cpp @@ -115,7 +115,7 @@ class HillCipher { * should be no more than \f$[0,10]\f$ */ template - static const double rand_range(matrix *M, T1 a, T1 b) { + static double rand_range(matrix *M, T1 a, T1 b) { for (size_t i = 0; i < M->size(); i++) { for (size_t j = 0; j < M[0][0].size(); j++) { M[0][i][j] = rand_range(a, b); @@ -190,7 +190,7 @@ class HillCipher { static inline uint8_t get_char_idx(const char ch) { size_t L = std::strlen(STRKEY); - for (uint8_t idx = 0; idx <= L; idx++) + for (size_t idx = 0; idx <= L; idx++) if (STRKEY[idx] == ch) return idx; From 988df1ba59a9895dfab2293d63bca5b400f16847 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 16:59:31 -0400 Subject: [PATCH 167/261] added licenses - #911 --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e99ec1311..9b79c11ef 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Overview -The repository is a collection of implementation of a variety of algorithms implemented in C++. These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. +The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. ## Features @@ -28,6 +28,9 @@ The repository is a collection of implementation of a variety of algorithms impl [Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus) is generated from the repository source codes directly. The documentation contains all resources including source code snippets, details on execution of the programs, diagrammatic representation of program flow, and links to external resources where necessary. The documentation also introduces interactive source code with links to documentation for C++ STL library functions used. Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to see the list of all the files documented with the code. +[Documentation of Algorithms in C++](https://thealgorithms.github.io/C-Plus-Plus) by [The Algorithms Contributors](https://github.com/TheAlgorithms) is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1)
+Creative Commons LicenseCredit must be given to you, the creatorAdaptations must be shared under the same terms + ## Contributions As a community developed and maintained repository, we welcome new un-plagiarized quality contributions. Please read our [Contribution Guidelines](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md). From 2d67ce3f52c3924b258667d4148905922054eb80 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 17:06:10 -0400 Subject: [PATCH 168/261] fix article `the` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b79c11ef..1d4186d5d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Overview -The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). These algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. +The repository is a collection of open-source implementation of a variety of algorithms implemented in C++ and licensed under [MIT License](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/LICENSE). The algorithms span a variety of topics from computer science, mathematics and statistics, data science, machine learning, engineering, etc.. The implementations and the associated documentation are meant to provide a learning resource for educators and students. Hence, one may find more than one implementation for the same objective but using a different algorithm strategies and optimizations. ## Features From 998c1ce9be4deb4ae7d6098524ead0748c48c2c7 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 17:06:59 -0400 Subject: [PATCH 169/261] remove closed pull-requests info graphic --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1d4186d5d..9db8e85ba 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) [![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)]("https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md") ![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C-Plus-Plus?color=red&style=flat-square) -![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/TheAlgorithms/C-Plus-Plus?color=green&style=flat-square) [![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)]("https://TheAlgorithms.github.io/C-Plus-Plus") [![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)]("https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22") From 695851b2888e143d15eaab00172f38a1eca7f841 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 17:11:19 -0400 Subject: [PATCH 170/261] fix alternatie text for 'by' icon --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9db8e85ba..417d5769f 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The repository is a collection of open-source implementation of a variety of alg Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to see the list of all the files documented with the code. [Documentation of Algorithms in C++](https://thealgorithms.github.io/C-Plus-Plus) by [The Algorithms Contributors](https://github.com/TheAlgorithms) is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1)
-Creative Commons LicenseCredit must be given to you, the creatorAdaptations must be shared under the same terms +Creative Commons LicenseCredit must be given to the creatorAdaptations must be shared under the same terms ## Contributions From de828baa8deed53c9547ea8b2c4d78637039fd75 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 27 Jun 2020 21:13:48 -0400 Subject: [PATCH 171/261] removed incorrect quotes from links --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 417d5769f..f499f06e7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # The Algorithms - C++ # {#mainpage} -[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/C-Plus-Plus) +[![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/TheAlgorithms/C-Plus-Plus.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/TheAlgorithms/C-Plus-Plus/context:cpp) [![Gitter chat](https://img.shields.io/badge/Chat-Gitter-ff69b4.svg?label=Chat&logo=gitter&style=flat-square)](https://gitter.im/TheAlgorithms) -[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)]("https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md") +[![contributions welcome](https://img.shields.io/static/v1.svg?label=Contributions&message=Welcome&color=0059b3&style=flat-square)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/CONTRIBUTING.md) ![GitHub repo size](https://img.shields.io/github/repo-size/TheAlgorithms/C-Plus-Plus?color=red&style=flat-square) -[![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)]("https://TheAlgorithms.github.io/C-Plus-Plus") -[![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)]("https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22") +[![Doxygen CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Doxygen%20CI/badge.svg)](https://TheAlgorithms.github.io/C-Plus-Plus) +[![Awesome CI](https://github.com/TheAlgorithms/C-Plus-Plus/workflows/Awesome%20CI%20Workflow/badge.svg)](https://github.com/TheAlgorithms/C-Plus-Plus/actions?query=workflow%3A%22Awesome+CI+Workflow%22) ## Overview From f87bc251b918cd4674f50ac55185588ceaab078f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 28 Jun 2020 09:14:41 -0400 Subject: [PATCH 172/261] fix link to contributors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f499f06e7..d19ac813d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The repository is a collection of open-source implementation of a variety of alg [Online Documentation](https://TheAlgorithms.github.io/C-Plus-Plus) is generated from the repository source codes directly. The documentation contains all resources including source code snippets, details on execution of the programs, diagrammatic representation of program flow, and links to external resources where necessary. The documentation also introduces interactive source code with links to documentation for C++ STL library functions used. Click on [Files menu](https://TheAlgorithms.github.io/C-Plus-Plus/files.html) to see the list of all the files documented with the code. -[Documentation of Algorithms in C++](https://thealgorithms.github.io/C-Plus-Plus) by [The Algorithms Contributors](https://github.com/TheAlgorithms) is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1)
+[Documentation of Algorithms in C++](https://thealgorithms.github.io/C-Plus-Plus) by [The Algorithms Contributors](https://github.com/TheAlgorithms/C-Plus-Plus/graphs/contributors) is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1)
Creative Commons LicenseCredit must be given to the creatorAdaptations must be shared under the same terms ## Contributions From 97023e1b1cf26e79ad72174d353636d6f9fe0c43 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Mon, 29 Jun 2020 15:27:44 +0100 Subject: [PATCH 173/261] docs: fixed some documentation issues --- math/complex_numbers.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 8b24c6d3c..c75b06ac1 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -1,8 +1,9 @@ /** * @author tjgurwara99 * @file - * - * A basic implementation of Complex Number field as a class with operators + * + * \brief An implementation of Complex Number as Objects + * \details A basic implementation of Complex Number field as a class with operators * overloaded to accommodate (mathematical) field operations. */ @@ -14,7 +15,7 @@ #include /** - * Class Complex to represent complex numbers as a field. + * \brief Class Complex to represent complex numbers as a field. */ class Complex { // The real value of the complex number @@ -24,8 +25,10 @@ class Complex { public: /** - * Complex Constructor which initialises the complex number which takes two - * arguments. + * \brief Complex Constructor which initialises our complex number. + * \details + * Complex Constructor which initialises the complex number which takes + * three arguments. * @param x If the third parameter is 'true' then this x is the absolute * value of the complex number, if the third parameter is 'false' then this * x is the real value of the complex number (optional). @@ -49,25 +52,28 @@ class Complex { } /** - * Copy Constructor + * \brief Copy Constructor * @param other The other number to equate our number to. */ Complex(const Complex &other) : re(other.real()), im(other.imag()) {} /** + * \brief Member function to get real value of our complex number. * Member function (getter) to access the class' re value. */ double real() const { return this->re; } /** + * \brief Member function to get imaginary value of our complex number. * Member function (getter) to access the class' im value. */ double imag() const { return this->im; } /** + * \brief Member function to give the modulus of our complex number. * Member function to which gives the absolute value (modulus) of our * complex number - * @return \f$ \sqrt{z \dot \bar{z}} \f$ where \f$ z \f$ is our complex + * @return \f$ \sqrt{z \dot \overline{z}} \f$ where \f$ z \f$ is our complex * number. */ double abs() const { @@ -75,12 +81,13 @@ class Complex { } /** - * Member function which gives the argument of our complex number. + * \brief Member function to give the argument of our complex number. * @return Argument of our Complex number in radians. */ double arg() const { return std::atan2(this->im, this->re); } /** + * \brief Operator overload of '+' on Complex class. * Operator overload to be able to add two complex numbers. * @param other The other number that is added to the current number. * @return result current number plus other number @@ -91,6 +98,7 @@ class Complex { } /** + * \brief Operator overload of '-' on Complex class. * Operator overload to be able to subtract two complex numbers. * @param other The other number being subtracted from the current number. * @return result current number subtract other number @@ -101,6 +109,7 @@ class Complex { } /** + * \brief Operator overload of '*' on Complex class. * Operator overload to be able to multiple two complex numbers. * @param other The other number to multiply the current number to. * @return result current number times other number. @@ -112,6 +121,7 @@ class Complex { } /** + * \brief Operator overload of '~' on Complex class. * Operator overload of the BITWISE NOT which gives us the conjugate of our * complex number. NOTE: This is overloading the BITWISE operator but its * not a BITWISE operation in this definition. @@ -123,6 +133,7 @@ class Complex { } /** + * \brief Operator overload of '/' on Complex class. * Operator overload to be able to divide two complex numbers. This function * would throw an exception if the other number is zero. * @param other The other number we divide our number by. @@ -142,6 +153,7 @@ class Complex { } /** + * \brief Operator overload of '=' on Complex class. * Operator overload to be able to copy RHS instance of Complex to LHS * instance of Complex */ @@ -153,6 +165,7 @@ class Complex { }; /** + * \brief Operator overload of '==' on Complex class. * Logical Equal overload for our Complex class. * @param a Left hand side of our expression * @param b Right hand side of our expression @@ -164,6 +177,7 @@ bool operator==(const Complex &a, const Complex &b) { } /** + * \brief Operator overload of '<<' of ostream for Complex class. * Overloaded insersion operator to accommodate the printing of our complex * number in their standard form. * @param os The console stream @@ -181,7 +195,7 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { } /** - * Function to get random numbers to generate our complex numbers for test + * \brief Function to get random numbers to generate our complex numbers for test */ double get_rand() { return (std::rand() % 100 - 50) / 100.f; } From 1dfbdde3c62dfcd67d4769dcc8c16904527f8b22 Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 1 Jul 2020 03:28:12 +0530 Subject: [PATCH 174/261] resolve merge conflicts --- numerical_methods/ordinary_least_squares_regressor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numerical_methods/ordinary_least_squares_regressor.cpp b/numerical_methods/ordinary_least_squares_regressor.cpp index 832d6edf7..bbd75a742 100644 --- a/numerical_methods/ordinary_least_squares_regressor.cpp +++ b/numerical_methods/ordinary_least_squares_regressor.cpp @@ -369,7 +369,7 @@ int main() { std::vector Y(N); std::cout - << "Enter training data. Per sample, provide features and one output." + << "Enter training data. Per sample, provide features ad one output." << std::endl; for (size_t rows = 0; rows < N; rows++) { From d3324aaf34b4fde750192ee9259b62835676a0cf Mon Sep 17 00:00:00 2001 From: Ayaan Khan Date: Wed, 1 Jul 2020 03:54:01 +0530 Subject: [PATCH 175/261] Fix: code quality and Docs --- sorting/insertion_sort.cpp | 103 ++++++++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 23 deletions(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index fe920ca59..180330a60 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -1,36 +1,93 @@ -// Insertion Sort +/** + * + * \file + * \brief [Insertion Sort Algorithm + * (Insertion Sort)](https://en.wikipedia.org/wiki/Insertion_sort) + * + * \author + * + * \details + * Insertion sort is a simple sorting algorithm that builds the final + * sorted array one at a time. It is much less efficient compared to + * other sorting algorithms like heap sort, merge sort or quick sort. + * However it has several advantages such as + *
+ * 1 - easy to implement
+ * 2 - For small set of data it is quite efficient
+ * 3 - More efficient that other Quadratic complexity algorithms like
+ *     Selection sort or bubble sort.
+ * 4 - It's stable that is it does not change the relative order of
+ *     elements with equal keys
+ * 5 - Works on hand means it can sort the array or list as it receives.
+ * 
+ * + * It is based on the same idea that people use to sort the playing cards in + * their hands. + * the algorithms goes in the manner that we start iterating over the array + * of elements as soon as we find a unsorted element that is a misplaced + * element we place it at a sorted position. + * + * Suppose initially we have + *
+ * 4 3 2 5 1
+ * 
+ * we start traversing from 4 till we reach 1
+ * when we reach at 3 we find that it is misplaced so we take 3 and place
+ * it at a correct position thus the array will become
+ * 
+ * 3 4 2 5 1
+ *
+ * in the next iteration we are at 2 we find that this is also misplaced so
+ * we place it at the correct sorted position thus the array in this iteration
+ * becomes
+ *
+ * 2 3 4 5 1
+ *
+ * we does not do anything with 5 and move on to the next iteration and select
+ * 1 which is misplaced and place it at correct position. Thus, we have
+ *
+ * 1 2 3 4 5
+ * 
+ * + */ #include -int main() { - int n; - std::cout << "\nEnter the length of your array : "; - std::cin >> n; - int *Array = new int[n]; - std::cout << "\nEnter any " << n << " Numbers for Unsorted Array : "; - - // Input - for (int i = 0; i < n; i++) { - std::cin >> Array[i]; - } - - // Sorting +/** \brief + * Insertion Sort Function + * + * @param arr Array to be sorted + * @param n Size of Array + * + */ +void insertionSort(int *arr, int n) { for (int i = 1; i < n; i++) { - int temp = Array[i]; + int temp = arr[i]; int j = i - 1; - while (j >= 0 && temp < Array[j]) { - Array[j + 1] = Array[j]; + while (j >= 0 && temp < arr[j]) { + arr[j + 1] = arr[j]; j--; } - Array[j + 1] = temp; + arr[j + 1] = temp; } +} + +/** Main Function */ +int main() { + int n; + std::cout << "Enter the length of your array : "; + std::cin >> n; + int *arr = new int[n]; + std::cout << "Enter any " << n << " Numbers for Unsorted Array : "; + + for (int i = 0; i < n; i++) std::cin >> arr[i]; + + insertionSort(arr, n); - // Output std::cout << "\nSorted Array : "; - for (int i = 0; i < n; i++) { - std::cout << Array[i] << "\t"; - } + for (int i = 0; i < n; i++) std::cout << arr[i] << " "; - delete[] Array; + std::cout << std::endl; + delete[] arr; return 0; } From d64f17f94c9278fd072e2e2a3477646bd9d5e5bf Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Tue, 30 Jun 2020 22:26:08 +0000 Subject: [PATCH 176/261] formatting source-code for 9217b4d8a880915d0a53b2408f38325f4b864e79 --- sorting/insertion_sort.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index 180330a60..12c1ead69 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -26,15 +26,15 @@ * the algorithms goes in the manner that we start iterating over the array * of elements as soon as we find a unsorted element that is a misplaced * element we place it at a sorted position. - * + * * Suppose initially we have *
  * 4 3 2 5 1
- * 
+ *
  * we start traversing from 4 till we reach 1
  * when we reach at 3 we find that it is misplaced so we take 3 and place
  * it at a correct position thus the array will become
- * 
+ *
  * 3 4 2 5 1
  *
  * in the next iteration we are at 2 we find that this is also misplaced so
@@ -55,7 +55,7 @@
 
 /** \brief
  * Insertion Sort Function
- * 
+ *
  * @param arr Array to be sorted
  * @param n Size of Array
  *
@@ -80,12 +80,12 @@ int main() {
     int *arr = new int[n];
     std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
 
-    for (int i = 0; i < n; i++)  std::cin >> arr[i];
+    for (int i = 0; i < n; i++) std::cin >> arr[i];
 
     insertionSort(arr, n);
 
     std::cout << "\nSorted Array : ";
-    for (int i = 0; i < n; i++)  std::cout << arr[i] << " ";
+    for (int i = 0; i < n; i++) std::cout << arr[i] << " ";
 
     std::cout << std::endl;
     delete[] arr;

From 8179fbfdec72dda8ea795ad1198525e41dd12740 Mon Sep 17 00:00:00 2001
From: Ayaan Khan 
Date: Wed, 1 Jul 2020 04:03:13 +0530
Subject: [PATCH 177/261] test cases added

---
 sorting/insertion_sort.cpp | 43 +++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp
index 180330a60..cc3216c1e 100644
--- a/sorting/insertion_sort.cpp
+++ b/sorting/insertion_sort.cpp
@@ -52,6 +52,8 @@
  */
 
 #include 
+#include 
+#include 
 
 /** \brief
  * Insertion Sort Function
@@ -72,22 +74,39 @@ void insertionSort(int *arr, int n) {
     }
 }
 
+/** Test Cases to test algorithm */
+void tests() {
+  int arr1[10] = { 78, 34, 35, 6, 34, 56, 3, 56, 2, 4};
+  insertionSort(arr1, 10);
+  assert(std::is_sorted(arr1, arr1 + 10));
+  std::cout << "Test 1 Passed" << std::endl;
+
+  int arr2[5] = {5, -3, 7, -2, 1};
+  insertionSort(arr2, 5);
+  assert(std::is_sorted(arr2, arr2 + 5));
+  std::cout << "Test 2 Passed" << std::endl;
+}
+
 /** Main Function */
 int main() {
-    int n;
-    std::cout << "Enter the length of your array : ";
-    std::cin >> n;
-    int *arr = new int[n];
-    std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
+  /// Running predefined tests to test algorithm
+  tests();
 
-    for (int i = 0; i < n; i++)  std::cin >> arr[i];
+  /// For user insteraction
+  int n;
+  std::cout << "Enter the length of your array : ";
+  std::cin >> n;
+  int *arr = new int[n];
+  std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
 
-    insertionSort(arr, n);
+  for (int i = 0; i < n; i++)  std::cin >> arr[i];
 
-    std::cout << "\nSorted Array : ";
-    for (int i = 0; i < n; i++)  std::cout << arr[i] << " ";
+  insertionSort(arr, n);
 
-    std::cout << std::endl;
-    delete[] arr;
-    return 0;
+  std::cout << "\nSorted Array : ";
+  for (int i = 0; i < n; i++)  std::cout << arr[i] << " ";
+
+  std::cout << std::endl;
+  delete[] arr;
+  return 0;
 }

From 3e1edca0242d83280bd9088a8ea20839cfa7c8c6 Mon Sep 17 00:00:00 2001
From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Date: Tue, 30 Jun 2020 22:35:45 +0000
Subject: [PATCH 178/261] formatting source-code for
 efcccd0148923a03eea0fe95c3e27c38e2d9c46d

---
 sorting/insertion_sort.cpp | 48 +++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp
index 5b20eef47..877e98f27 100644
--- a/sorting/insertion_sort.cpp
+++ b/sorting/insertion_sort.cpp
@@ -51,9 +51,9 @@
  *
  */
 
-#include 
 #include 
 #include 
+#include 
 
 /** \brief
  * Insertion Sort Function
@@ -76,37 +76,37 @@ void insertionSort(int *arr, int n) {
 
 /** Test Cases to test algorithm */
 void tests() {
-  int arr1[10] = { 78, 34, 35, 6, 34, 56, 3, 56, 2, 4};
-  insertionSort(arr1, 10);
-  assert(std::is_sorted(arr1, arr1 + 10));
-  std::cout << "Test 1 Passed" << std::endl;
+    int arr1[10] = {78, 34, 35, 6, 34, 56, 3, 56, 2, 4};
+    insertionSort(arr1, 10);
+    assert(std::is_sorted(arr1, arr1 + 10));
+    std::cout << "Test 1 Passed" << std::endl;
 
-  int arr2[5] = {5, -3, 7, -2, 1};
-  insertionSort(arr2, 5);
-  assert(std::is_sorted(arr2, arr2 + 5));
-  std::cout << "Test 2 Passed" << std::endl;
+    int arr2[5] = {5, -3, 7, -2, 1};
+    insertionSort(arr2, 5);
+    assert(std::is_sorted(arr2, arr2 + 5));
+    std::cout << "Test 2 Passed" << std::endl;
 }
 
 /** Main Function */
 int main() {
-  /// Running predefined tests to test algorithm
-  tests();
+    /// Running predefined tests to test algorithm
+    tests();
 
-  /// For user insteraction
-  int n;
-  std::cout << "Enter the length of your array : ";
-  std::cin >> n;
-  int *arr = new int[n];
-  std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
+    /// For user insteraction
+    int n;
+    std::cout << "Enter the length of your array : ";
+    std::cin >> n;
+    int *arr = new int[n];
+    std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
 
-  for (int i = 0; i < n; i++)  std::cin >> arr[i];
+    for (int i = 0; i < n; i++) std::cin >> arr[i];
 
-  insertionSort(arr, n);
+    insertionSort(arr, n);
 
-  std::cout << "\nSorted Array : ";
-  for (int i = 0; i < n; i++)  std::cout << arr[i] << " ";
+    std::cout << "\nSorted Array : ";
+    for (int i = 0; i < n; i++) std::cout << arr[i] << " ";
 
-  std::cout << std::endl;
-  delete[] arr;
-  return 0;
+    std::cout << std::endl;
+    delete[] arr;
+    return 0;
 }

From dd0a07f18ae5d2e5d78bb657861a131408a7c642 Mon Sep 17 00:00:00 2001
From: Ayaan Khan 
Date: Wed, 1 Jul 2020 15:38:55 +0530
Subject: [PATCH 179/261] loop formating fix

---
 sorting/insertion_sort.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp
index 5b20eef47..07cb7375f 100644
--- a/sorting/insertion_sort.cpp
+++ b/sorting/insertion_sort.cpp
@@ -99,12 +99,16 @@ int main() {
   int *arr = new int[n];
   std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
 
-  for (int i = 0; i < n; i++)  std::cin >> arr[i];
+  for (int i = 0; i < n; i++) {
+    std::cin >> arr[i];
+  }
 
   insertionSort(arr, n);
 
   std::cout << "\nSorted Array : ";
-  for (int i = 0; i < n; i++)  std::cout << arr[i] << " ";
+  for (int i = 0; i < n; i++) {
+    std::cout << arr[i] << " ";
+  }
 
   std::cout << std::endl;
   delete[] arr;

From e4c62d28fec2822c7f4857414e5bf76bdc5cf611 Mon Sep 17 00:00:00 2001
From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Date: Wed, 1 Jul 2020 10:10:51 +0000
Subject: [PATCH 180/261] formatting source-code for
 7af31e32a22952a70682a926866c1ff1bab72b99

---
 sorting/insertion_sort.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp
index ceac13903..39298eb45 100644
--- a/sorting/insertion_sort.cpp
+++ b/sorting/insertion_sort.cpp
@@ -99,16 +99,16 @@ int main() {
     int *arr = new int[n];
     std::cout << "Enter any " << n << " Numbers for Unsorted Array : ";
 
-  for (int i = 0; i < n; i++) {
-    std::cin >> arr[i];
-  }
+    for (int i = 0; i < n; i++) {
+        std::cin >> arr[i];
+    }
 
     insertionSort(arr, n);
 
-  std::cout << "\nSorted Array : ";
-  for (int i = 0; i < n; i++) {
-    std::cout << arr[i] << " ";
-  }
+    std::cout << "\nSorted Array : ";
+    for (int i = 0; i < n; i++) {
+        std::cout << arr[i] << " ";
+    }
 
     std::cout << std::endl;
     delete[] arr;

From f586ca1b6493fe5ace0d0bff7de8d7eb50fe5714 Mon Sep 17 00:00:00 2001
From: Tajmeet Singh 
Date: Wed, 1 Jul 2020 14:56:51 +0100
Subject: [PATCH 181/261] docs: fix

---
 math/complex_numbers.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp
index c75b06ac1..50fd684d5 100644
--- a/math/complex_numbers.cpp
+++ b/math/complex_numbers.cpp
@@ -73,7 +73,7 @@ class Complex {
      * \brief Member function to give the modulus of our complex number.
      * Member function to which gives the absolute value (modulus) of our
      * complex number
-     * @return \f$ \sqrt{z \dot \overline{z}} \f$ where \f$ z \f$ is our complex
+     * @return \f$ \sqrt{z \bar{z}} \f$ where \f$ z \f$ is our complex
      * number.
      */
     double abs() const {

From 957b57cf60267d0018a3901bbf9ae20b6054c57f Mon Sep 17 00:00:00 2001
From: Krishna Vedala <7001608+kvedala@users.noreply.github.com>
Date: Wed, 1 Jul 2020 10:10:51 -0400
Subject: [PATCH 182/261] fix issues from #929

---
 sorting/insertion_sort.cpp | 106 +++++++++++++++++++++++--------------
 1 file changed, 67 insertions(+), 39 deletions(-)

diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp
index 39298eb45..4bfce9ce6 100644
--- a/sorting/insertion_sort.cpp
+++ b/sorting/insertion_sort.cpp
@@ -4,22 +4,18 @@
  * \brief [Insertion Sort Algorithm
  * (Insertion Sort)](https://en.wikipedia.org/wiki/Insertion_sort)
  *
- * \author
- *
  * \details
  * Insertion sort is a simple sorting algorithm that builds the final
  * sorted array one at a time. It is much less efficient compared to
  * other sorting algorithms like heap sort, merge sort or quick sort.
  * However it has several advantages such as
- * 
- * 1 - easy to implement
- * 2 - For small set of data it is quite efficient
- * 3 - More efficient that other Quadratic complexity algorithms like
- *     Selection sort or bubble sort.
- * 4 - It's stable that is it does not change the relative order of
- *     elements with equal keys
- * 5 - Works on hand means it can sort the array or list as it receives.
- * 
+ * 1. easy to implement + * 2. For small set of data it is quite efficient + * 3. More efficient that other Quadratic complexity algorithms like + * Selection sort or bubble sort. + * 4. It's stable that is it does not change the relative order of + * elements with equal keys + * 5. Works on hand means it can sort the array or list as it receives. * * It is based on the same idea that people use to sort the playing cards in * their hands. @@ -27,44 +23,41 @@ * of elements as soon as we find a unsorted element that is a misplaced * element we place it at a sorted position. * - * Suppose initially we have - *
- * 4 3 2 5 1
- *
- * we start traversing from 4 till we reach 1
+ * Execution example steps:
+ * 1. Suppose initially we have
+ * 
4 3 2 5 1
+ * 2. We start traversing from 4 till we reach 1 * when we reach at 3 we find that it is misplaced so we take 3 and place * it at a correct position thus the array will become - * - * 3 4 2 5 1 - * - * in the next iteration we are at 2 we find that this is also misplaced so + *
3 4 2 5 1
+ * 3. In the next iteration we are at 2 we find that this is also misplaced so * we place it at the correct sorted position thus the array in this iteration * becomes - * - * 2 3 4 5 1 - * - * we does not do anything with 5 and move on to the next iteration and select - * 1 which is misplaced and place it at correct position. Thus, we have - * - * 1 2 3 4 5 - *
- * + *
2 3 4 5 1
+ * 4. we does not do anything with 5 and move on to the next iteration and + * select 1 which is misplaced and place it at correct position. Thus, we have + *
1 2 3 4 5
*/ #include #include #include +#include +/** \namespace sorting + * \brief Sorting algorithms + */ +namespace sorting { /** \brief * Insertion Sort Function * * @param arr Array to be sorted * @param n Size of Array - * */ -void insertionSort(int *arr, int n) { +template +void insertionSort(T *arr, int n) { for (int i = 1; i < n; i++) { - int temp = arr[i]; + T temp = arr[i]; int j = i - 1; while (j >= 0 && temp < arr[j]) { arr[j + 1] = arr[j]; @@ -74,17 +67,48 @@ void insertionSort(int *arr, int n) { } } +template +void insertionSort(std::vector *arr) { + size_t n = arr->size(); + + for (size_t i = 1; i < n; i++) { + T temp = arr[0][i]; + int32_t j = i - 1; + while (j >= 0 && temp < arr[0][j]) { + arr[0][j + 1] = arr[0][j]; + j--; + } + arr[0][j + 1] = temp; + } +} + +} // namespace sorting + /** Test Cases to test algorithm */ void tests() { int arr1[10] = {78, 34, 35, 6, 34, 56, 3, 56, 2, 4}; - insertionSort(arr1, 10); + std::cout << "Test 1... "; + sorting::insertionSort(arr1, 10); assert(std::is_sorted(arr1, arr1 + 10)); - std::cout << "Test 1 Passed" << std::endl; + std::cout << "passed" << std::endl; int arr2[5] = {5, -3, 7, -2, 1}; - insertionSort(arr2, 5); + std::cout << "Test 2... "; + sorting::insertionSort(arr2, 5); assert(std::is_sorted(arr2, arr2 + 5)); - std::cout << "Test 2 Passed" << std::endl; + std::cout << "passed" << std::endl; + + float arr3[5] = {5.6, -3.1, -3.0, -2.1, 1.8}; + std::cout << "Test 3... "; + sorting::insertionSort(arr3, 5); + assert(std::is_sorted(arr3, arr3 + 5)); + std::cout << "passed" << std::endl; + + std::vector arr4({5.6, -3.1, -3.0, -2.1, 1.8}); + std::cout << "Test 4... "; + sorting::insertionSort(&arr4); + assert(std::is_sorted(std::begin(arr4), std::end(arr4))); + std::cout << "passed" << std::endl; } /** Main Function */ @@ -93,9 +117,13 @@ int main() { tests(); /// For user insteraction - int n; - std::cout << "Enter the length of your array : "; + size_t n; + std::cout << "Enter the length of your array (0 to exit): "; std::cin >> n; + if (n == 0) { + return 0; + } + int *arr = new int[n]; std::cout << "Enter any " << n << " Numbers for Unsorted Array : "; @@ -103,7 +131,7 @@ int main() { std::cin >> arr[i]; } - insertionSort(arr, n); + sorting::insertionSort(arr, n); std::cout << "\nSorted Array : "; for (int i = 0; i < n; i++) { From 9b799c93cb9977c66363958b9f5157841d51a768 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:19:18 -0400 Subject: [PATCH 183/261] added documentation for new function --- sorting/insertion_sort.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index 4bfce9ce6..32315a87a 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -51,7 +51,7 @@ namespace sorting { /** \brief * Insertion Sort Function * - * @param arr Array to be sorted + * @param [in,out] arr Array to be sorted * @param n Size of Array */ template @@ -67,6 +67,10 @@ void insertionSort(T *arr, int n) { } } +/** Insertion Sort Function + * + * @param [in,out] arr pointer to array to be sorted + */ template void insertionSort(std::vector *arr) { size_t n = arr->size(); From 69b5c8395a1d392ba6d1011e8aed1be74cfcf54b Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 10:36:08 -0400 Subject: [PATCH 184/261] better rendering of example steps --- sorting/insertion_sort.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index 32315a87a..b6a8f72ac 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -23,20 +23,20 @@ * of elements as soon as we find a unsorted element that is a misplaced * element we place it at a sorted position. * - * Execution example steps: + * Example execution steps: * 1. Suppose initially we have - *
4 3 2 5 1
+ * \f{bmatrix}{4 &3 &2 &5 &1\f} * 2. We start traversing from 4 till we reach 1 * when we reach at 3 we find that it is misplaced so we take 3 and place * it at a correct position thus the array will become - *
3 4 2 5 1
+ * \f{bmatrix}{3 &4 &2 &5 &1\f} * 3. In the next iteration we are at 2 we find that this is also misplaced so * we place it at the correct sorted position thus the array in this iteration * becomes - *
2 3 4 5 1
+ * \f{bmatrix}{2 &3 &4 &5 &1\f} * 4. we does not do anything with 5 and move on to the next iteration and * select 1 which is misplaced and place it at correct position. Thus, we have - *
1 2 3 4 5
+ * \f{bmatrix}{1 &2 &3 &4 &5\f} */ #include From fed7dd1c13d75a736b90260a1d39355732b4e8e5 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 12:37:54 -0400 Subject: [PATCH 185/261] improved self-tests --- sorting/insertion_sort.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index b6a8f72ac..34a55d21a 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -51,6 +51,7 @@ namespace sorting { /** \brief * Insertion Sort Function * + * @tparam T type of array * @param [in,out] arr Array to be sorted * @param n Size of Array */ @@ -69,6 +70,7 @@ void insertionSort(T *arr, int n) { /** Insertion Sort Function * + * @tparam T type of array * @param [in,out] arr pointer to array to be sorted */ template @@ -88,6 +90,21 @@ void insertionSort(std::vector *arr) { } // namespace sorting +/** + * @brief Create a random array objecthelper function to create a random array + * + * @tparam T type of array + * @param arr array to fill (must be pre-allocated) + * @param N number of array elements + */ +template +static void create_random_array(T *arr, int N) { + while (N--) { + double r = (std::rand() % 10000 - 5000) / 100.f; + arr[N] = static_cast(r); + } +} + /** Test Cases to test algorithm */ void tests() { int arr1[10] = {78, 34, 35, 6, 34, 56, 3, 56, 2, 4}; @@ -113,6 +130,20 @@ void tests() { sorting::insertionSort(&arr4); assert(std::is_sorted(std::begin(arr4), std::end(arr4))); std::cout << "passed" << std::endl; + + int arr5[50]; + std::cout << "Test 5... "; + create_random_array(arr5, 50); + sorting::insertionSort(arr5, 50); + assert(std::is_sorted(arr5, arr5 + 50)); + std::cout << "passed" << std::endl; + + float arr6[50]; + std::cout << "Test 6... "; + create_random_array(arr6, 50); + sorting::insertionSort(arr6, 50); + assert(std::is_sorted(arr6, arr6 + 50)); + std::cout << "passed" << std::endl; } /** Main Function */ From 84fd1cb0d01f2d7a33f07adecf8fc4b6088a4fe6 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 13:04:54 -0400 Subject: [PATCH 186/261] small case 'e' Co-authored-by: Ayaan Khan --- sorting/insertion_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index 34a55d21a..efa60e584 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -9,7 +9,7 @@ * sorted array one at a time. It is much less efficient compared to * other sorting algorithms like heap sort, merge sort or quick sort. * However it has several advantages such as - * 1. easy to implement + * 1. Easy to implement * 2. For small set of data it is quite efficient * 3. More efficient that other Quadratic complexity algorithms like * Selection sort or bubble sort. From 4045bcddf3752d5b2d8efac6ce132c79ff53c7e7 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 13:05:52 -0400 Subject: [PATCH 187/261] verb correction --- sorting/insertion_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index efa60e584..beb828005 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -34,7 +34,7 @@ * we place it at the correct sorted position thus the array in this iteration * becomes * \f{bmatrix}{2 &3 &4 &5 &1\f} - * 4. we does not do anything with 5 and move on to the next iteration and + * 4. we do not do anything with 5 and move on to the next iteration and * select 1 which is misplaced and place it at correct position. Thus, we have * \f{bmatrix}{1 &2 &3 &4 &5\f} */ From 390ee8428e7f69a609f682c7ddede7279ae187e7 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 1 Jul 2020 13:08:41 -0400 Subject: [PATCH 188/261] fix to upper case --- sorting/insertion_sort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorting/insertion_sort.cpp b/sorting/insertion_sort.cpp index beb828005..c9bac4bf7 100644 --- a/sorting/insertion_sort.cpp +++ b/sorting/insertion_sort.cpp @@ -34,7 +34,7 @@ * we place it at the correct sorted position thus the array in this iteration * becomes * \f{bmatrix}{2 &3 &4 &5 &1\f} - * 4. we do not do anything with 5 and move on to the next iteration and + * 4. We do not do anything with 5 and move on to the next iteration and * select 1 which is misplaced and place it at correct position. Thus, we have * \f{bmatrix}{1 &2 &3 &4 &5\f} */ From 5baf1ad89fee29b5b394bcfe4eafc2327613eaff Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Thu, 2 Jul 2020 12:48:35 +0000 Subject: [PATCH 189/261] formatting source-code for 247301c5b5f1c61c015fd2f852832651dc443c2e --- math/complex_numbers.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 50fd684d5..f89238649 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -1,10 +1,10 @@ /** * @author tjgurwara99 * @file - * + * * \brief An implementation of Complex Number as Objects - * \details A basic implementation of Complex Number field as a class with operators - * overloaded to accommodate (mathematical) field operations. + * \details A basic implementation of Complex Number field as a class with + * operators overloaded to accommodate (mathematical) field operations. */ #include @@ -195,7 +195,8 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { } /** - * \brief Function to get random numbers to generate our complex numbers for test + * \brief Function to get random numbers to generate our complex numbers for + * test */ double get_rand() { return (std::rand() % 100 - 50) / 100.f; } From d11e8cb40a11415ac82888033977d23d52b3c8b5 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:30:42 +0400 Subject: [PATCH 190/261] added skip_list.cpp --- data_structures/skip_list.cpp | 185 ++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 data_structures/skip_list.cpp diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp new file mode 100644 index 000000000..8b6ec1f70 --- /dev/null +++ b/data_structures/skip_list.cpp @@ -0,0 +1,185 @@ +/** + * A skip list is a data structure that is used for storing a sorted list of items with a + * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items + * + * References used: GeeksForGeeks, https://iq.opengenus.org/skip-list/ Pseudo Code, https://ideone.com/XnXIFl from CodeForces. +*/ + +#include +#include +#include +#include +using namespace std; + +#define MAXLVL 2 +#define P 0.5 + + +/** + * Node structure [Key][Node*, Node*...] +*/ +class Node { +public: + int key; + void* value; + /*Forward Array*/ + vector forward; + Node(int key, int level, void* value); +}; + + +Node::Node(int key, int level, void* value) { + this->key = key; + + /*Initialization of forward vector*/ + for (int i = 0; i < sizeof(Node*)*(level+1); i++){ + forward.push_back(NULL); + } +}; + +// Class for Skip list +class SkipList { + int level; + Node *header; +public: + SkipList(); + int randomLevel(); + void insertElement(int, void*); + void deleteElement(int); + void* searchElement(int); + void displayList(); +}; + +SkipList::SkipList() { + level = 0; + /* Header initialization*/ + header = new Node(-1, MAXLVL, NULL); +}; + + +/** + * Returns random level for skip list; +*/ +int SkipList::randomLevel() { + int lvl = 0; + while(rand()%2 < P && lvl < MAXLVL) lvl++; + return lvl; +}; + + +// Insert given key in skip list +void SkipList::insertElement(int key, void* value) { + printf("Inserting %d key ... ", key); + Node *x = header; + Node *update[MAXLVL+1]; + memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + + + for(int i = level; i >= 0; i--) { + while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == NULL || x->key != key); + if (doesnt_exist) { + int rlevel = randomLevel(); + + if(rlevel > level) { + for(int i=level+1;iforward[i] = update[i]->forward[i]; + update[i]->forward[i] = n; + } + printf(" Inserted\n"); + } else { + printf("Exists\n"); + } +}; + +// Delete element from skip list +void SkipList::deleteElement(int key) +{ + Node *x = header; + + Node *update[MAXLVL+1]; + memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + + for(int i = level; i >= 0; i--) { + while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == NULL || x->key != key); + + if(!doesnt_exist) { + for(int i=0;i<=level;i++) { + if(update[i]->forward[i] != x) break; + update[i]->forward[i] = x->forward[i]; + } + /*Remove empty levels*/ + while(level>0 && header->forward[level] == 0) level--; + printf("Deleted\n"); + } else { + printf("Doesnt Exists\n"); + } +}; + + +/** + * Searching element in skip list structure +*/ +void* SkipList::searchElement(int key) { + Node *x = header; + printf("Searching for %d\n", key); + + for(int i = level; i >= 0; i--) { + while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; + } + + x = x->forward[0]; + if(x && x->key == key){ + printf("FOUND\n"); + return x->value; + } else { + printf("NOT FOUND\n"); + return NULL; + } +}; + +// Display skip list level wise +void SkipList::displayList() { + printf("----SKIP LIST STRUCTURE----\n"); + for(int i=0; i <= level; i++) { + Node *node = header->forward[i]; + printf("Level %d: ", i); + while(node != NULL) { + printf("%d ", node->key); + node = node->forward[i]; + } + printf("\n"); + } +}; + +int main() +{ + srand((unsigned)time(0)); + + SkipList lst; + + for (int j = 0; j < (1 << (MAXLVL+1)); j++){ + int k = (rand() % (1 << (MAXLVL+1) + 1)); + lst.insertElement(k, &j); + } + + lst.displayList(); +} \ No newline at end of file From ec04afc54fccb6ff4c2f5fe32833e0116ac174b3 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:34:13 +0400 Subject: [PATCH 191/261] added skip-list --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 8b6ec1f70..31e6d06f4 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -2,7 +2,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks, https://iq.opengenus.org/skip-list/ Pseudo Code, https://ideone.com/XnXIFl from CodeForces. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Pseudo Code. */ #include @@ -104,7 +104,7 @@ void SkipList::insertElement(int key, void* value) { } }; -// Delete element from skip list + void SkipList::deleteElement(int key) { Node *x = header; From 94338f527bcd26191ed9136722cb7fba985c4233 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:43:27 +0400 Subject: [PATCH 192/261] skip_list --- data_structures/skip_list.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 31e6d06f4..603d1f2c3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,10 +9,12 @@ #include #include #include -using namespace std; #define MAXLVL 2 #define P 0.5 + +using std::endl; +using std::vector; /** From 2c6b8c3bf74d2875def9d296e8bac7adcf45ecbe Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 13:46:52 +0400 Subject: [PATCH 193/261] skip_list --- data_structures/skip_list.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 603d1f2c3..bae1a7bbe 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -27,7 +27,7 @@ public: /*Forward Array*/ vector forward; Node(int key, int level, void* value); -}; +} Node::Node(int key, int level, void* value) { @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -}; +} // Class for Skip list class SkipList { @@ -50,14 +50,13 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -}; +} SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -}; - +} /** * Returns random level for skip list; @@ -66,7 +65,7 @@ int SkipList::randomLevel() { int lvl = 0; while(rand()%2 < P && lvl < MAXLVL) lvl++; return lvl; -}; +} // Insert given key in skip list @@ -104,8 +103,7 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -}; - +} void SkipList::deleteElement(int key) { @@ -134,7 +132,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -}; +} /** @@ -156,7 +154,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -}; +} // Display skip list level wise void SkipList::displayList() { @@ -170,10 +168,9 @@ void SkipList::displayList() { } printf("\n"); } -}; +} -int main() -{ +int main() { srand((unsigned)time(0)); SkipList lst; @@ -184,4 +181,5 @@ int main() } lst.displayList(); + return 0; } \ No newline at end of file From f13964cab2546754e08e61eda061a260473eb7e5 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:04:44 +0400 Subject: [PATCH 194/261] skip-list --- data_structures/skip_list.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index bae1a7bbe..19fdc6276 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,12 +9,12 @@ #include #include #include +// using namespace std; +using std::vector; +using std::endl; #define MAXLVL 2 #define P 0.5 - -using std::endl; -using std::vector; /** @@ -27,7 +27,7 @@ public: /*Forward Array*/ vector forward; Node(int key, int level, void* value); -} +}; Node::Node(int key, int level, void* value) { @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -} +}; // Class for Skip list class SkipList { @@ -50,13 +50,14 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -} +}; SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -} +}; + /** * Returns random level for skip list; @@ -65,7 +66,7 @@ int SkipList::randomLevel() { int lvl = 0; while(rand()%2 < P && lvl < MAXLVL) lvl++; return lvl; -} +}; // Insert given key in skip list @@ -103,7 +104,8 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -} +}; + void SkipList::deleteElement(int key) { @@ -132,7 +134,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -} +}; /** @@ -154,7 +156,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -} +}; // Display skip list level wise void SkipList::displayList() { @@ -168,9 +170,10 @@ void SkipList::displayList() { } printf("\n"); } -} +}; -int main() { +int main() +{ srand((unsigned)time(0)); SkipList lst; @@ -181,5 +184,5 @@ int main() { } lst.displayList(); - return 0; -} \ No newline at end of file + +} From 2fb95a2bf3ba4dd411dd1123a412e28e4ae9560a Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:29:08 +0400 Subject: [PATCH 195/261] skip_list --- data_structures/skip_list.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 19fdc6276..723958866 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -37,7 +37,7 @@ Node::Node(int key, int level, void* value) { for (int i = 0; i < sizeof(Node*)*(level+1); i++){ forward.push_back(NULL); } -}; +} // Class for Skip list class SkipList { @@ -50,13 +50,13 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); -}; +}; SkipList::SkipList() { level = 0; /* Header initialization*/ header = new Node(-1, MAXLVL, NULL); -}; +} /** @@ -64,9 +64,10 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while(rand()%2 < P && lvl < MAXLVL) lvl++; + thread_local unsigned int seed = time(NULL); + while(rand_r(&seed)%2 < P && lvl < MAXLVL) lvl++; return lvl; -}; +} // Insert given key in skip list @@ -104,7 +105,7 @@ void SkipList::insertElement(int key, void* value) { } else { printf("Exists\n"); } -}; +} void SkipList::deleteElement(int key) @@ -134,7 +135,7 @@ void SkipList::deleteElement(int key) } else { printf("Doesnt Exists\n"); } -}; +} /** @@ -156,7 +157,7 @@ void* SkipList::searchElement(int key) { printf("NOT FOUND\n"); return NULL; } -}; +} // Display skip list level wise void SkipList::displayList() { @@ -170,16 +171,17 @@ void SkipList::displayList() { } printf("\n"); } -}; +} int main() { - srand((unsigned)time(0)); + thread_local unsigned int seed = time(NULL); + SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand() % (1 << (MAXLVL+1) + 1)); + int k = (rand_r(&seed) % (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From 2c3d72b102c48b6c4329f5b89b45a546da11eeac Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 14:38:58 +0400 Subject: [PATCH 196/261] Added fibonacci search --- search/fibonacci_search.cpp | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 search/fibonacci_search.cpp diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp new file mode 100644 index 000000000..29f10c370 --- /dev/null +++ b/search/fibonacci_search.cpp @@ -0,0 +1,61 @@ +#include +#include + +/* +Input: a sorted array and a value +Output: if the array contains the value, returns its index (index of its first occurence) + else returns -1 +*/ + +int fibonacchi_search(std::vector arr, int value){ + int last = 0, current = 1, offset = -1, index; + int length = arr.size(); + int next = last + current; + + while(next < length){ + last = current; + current = next; + next = last + current; + } + + while(next > 1){ + index = std::min(offset + last, length-1); + if(arr[index] < value){ + next = current; + current = last; + last = next - current; + offset = index; + } else if(arr[index] > value){ + next = last; + current = current - last; + last = next - current; + } else { + return index; + } + } + if(current && !arr.empty() && arr[offset+1] == value){ + return offset+1; + } + return -1; +} + +int main() { + int size, value; + std::cout << "Enter size of a sorted array: " << std::endl; + std::cin >> size; + std::cout << "Enter array elements: " << std::endl; + + std::vector arr(size); + for(int i = 0; i < size; i++){ + std::cin >> arr[i]; + } + std::cout << "Enter the value you're looking for: " << std::endl; + std::cin >> value; + int index = fibonacchi_search(arr, value); + if(index != -1){ + std::cout << "Index of the given value is " << index << std::endl; + } else { + std::cout << "Array does not contain the value" << std::endl; + } + return 0; +} From 420915fa0ddff92b6be4922f540c651136f9f6a6 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:48:30 +0400 Subject: [PATCH 197/261] skip_list --- data_structures/skip_list.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 723958866..550a5c9d3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include // using namespace std; using std::vector; using std::endl; @@ -58,6 +60,8 @@ SkipList::SkipList() { header = new Node(-1, MAXLVL, NULL); } + + /** * Returns random level for skip list; @@ -187,4 +191,6 @@ int main() lst.displayList(); + + } From 910180ff214ae669eb0a9ec6a923a7d00755d746 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 14:54:44 +0400 Subject: [PATCH 198/261] skip_list --- data_structures/skip_list.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 550a5c9d3..3b4ba500f 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -11,6 +11,8 @@ #include #include #include +#include + // using namespace std; using std::vector; using std::endl; From 363f43c942879a2ee92253588896fb3c81c8780a Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 14:57:57 +0400 Subject: [PATCH 199/261] min function implemented --- search/fibonacci_search.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index 29f10c370..af3858e74 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -7,7 +7,15 @@ Output: if the array contains the value, returns its index (index of its first o else returns -1 */ -int fibonacchi_search(std::vector arr, int value){ +int min(int first, int second){ + if(first > second){ + return first; + } else { + return second; + } +} + +int fibonacci_search(std::vector arr, int value){ int last = 0, current = 1, offset = -1, index; int length = arr.size(); int next = last + current; @@ -19,7 +27,7 @@ int fibonacchi_search(std::vector arr, int value){ } while(next > 1){ - index = std::min(offset + last, length-1); + index = min(offset + last, length-1); if(arr[index] < value){ next = current; current = last; @@ -51,7 +59,7 @@ int main() { } std::cout << "Enter the value you're looking for: " << std::endl; std::cin >> value; - int index = fibonacchi_search(arr, value); + int index = fibonacci_search(arr, value); if(index != -1){ std::cout << "Index of the given value is " << index << std::endl; } else { From 1002126449a0599630df669397aa49a1586e3e90 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 15:05:07 +0400 Subject: [PATCH 200/261] min function corrected --- search/fibonacci_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index af3858e74..0bf33c494 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -8,7 +8,7 @@ Output: if the array contains the value, returns its index (index of its first o */ int min(int first, int second){ - if(first > second){ + if(first < second){ return first; } else { return second; From 8e99383dbf8f373fc7a99fd2db8187f3f88441f4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 15:13:01 +0400 Subject: [PATCH 201/261] skip_list --- data_structures/skip_list.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 3b4ba500f..fe5820b43 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,8 +70,7 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - thread_local unsigned int seed = time(NULL); - while(rand_r(&seed)%2 < P && lvl < MAXLVL) lvl++; + while((float)rand()/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } @@ -181,13 +180,12 @@ void SkipList::displayList() { int main() { - thread_local unsigned int seed = time(NULL); + srand((unsigned)time(0)); - SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand_r(&seed) % (1 << (MAXLVL+1) + 1)); + int k = (rand()% (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From 2fc0d5bffeaff3845fd8b3ca774b0f9f50cc2299 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:40:47 +0400 Subject: [PATCH 202/261] skip-list corrected --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index fe5820b43..69836e13a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -180,12 +180,12 @@ void SkipList::displayList() { int main() { - srand((unsigned)time(0)); + std::srand(time(nullptr)); SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (rand()% (1 << (MAXLVL+1) + 1)); + int k = (std::rand()% (1 << (MAXLVL+1) + 1)); lst.insertElement(k, &j); } From ba65d559c5912861bad589e7832becdf321bc01f Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:51:47 +0400 Subject: [PATCH 203/261] skip-list documentation-polish --- data_structures/skip_list.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 69836e13a..988165db3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,14 +70,14 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while((float)rand()/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } // Insert given key in skip list void SkipList::insertElement(int key, void* value) { - printf("Inserting %d key ... ", key); + std::cout << "Inserting" << key << "..."; Node *x = header; Node *update[MAXLVL+1]; memset(update, 0, sizeof(Node*)*(MAXLVL+1)); @@ -106,13 +106,14 @@ void SkipList::insertElement(int key, void* value) { n->forward[i] = update[i]->forward[i]; update[i]->forward[i] = n; } - printf(" Inserted\n"); + std::cout << "Inserted" << endl; + } else { - printf("Exists\n"); + std::cout << "Exists" << endl; } } - + /**Delete document by key*/ void SkipList::deleteElement(int key) { Node *x = header; @@ -136,9 +137,9 @@ void SkipList::deleteElement(int key) } /*Remove empty levels*/ while(level>0 && header->forward[level] == 0) level--; - printf("Deleted\n"); + std::cout << "Deleted" << endl; } else { - printf("Doesnt Exists\n"); + std::cout << "Doesn't exist" << endl; } } @@ -148,7 +149,7 @@ void SkipList::deleteElement(int key) */ void* SkipList::searchElement(int key) { Node *x = header; - printf("Searching for %d\n", key); + std::cout << "Searching for " + key << endl; for(int i = level; i >= 0; i--) { while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; @@ -156,25 +157,25 @@ void* SkipList::searchElement(int key) { x = x->forward[0]; if(x && x->key == key){ - printf("FOUND\n"); + std::cout << "Found" << endl; return x->value; } else { - printf("NOT FOUND\n"); + std::cout << "Not Found" << endl; return NULL; } } // Display skip list level wise void SkipList::displayList() { - printf("----SKIP LIST STRUCTURE----\n"); + std::cout << "Displaying list:\n" << endl; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; - printf("Level %d: ", i); + std::cout << "Level " << (i) << ": "; while(node != NULL) { - printf("%d ", node->key); + std::cout << node->key << " "; node = node->forward[i]; } - printf("\n"); + std::cout << endl; } } From 5068ddc14d093c2434edcb359fca0d3594dff86c Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 16:55:52 +0400 Subject: [PATCH 204/261] skip-list documentation-polish --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 988165db3..d2ba820f4 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -70,7 +70,7 @@ SkipList::SkipList() { */ int SkipList::randomLevel() { int lvl = 0; - while(static_cast(rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(std::rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; return lvl; } From dcdebae395ae9edbf40461b8a1cd31659ad20526 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 17:24:13 +0400 Subject: [PATCH 205/261] skip-list documentation-polish --- data_structures/skip_list.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index d2ba820f4..782486632 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -54,7 +54,10 @@ public: void deleteElement(int); void* searchElement(int); void displayList(); + ~SkipList(); }; + + SkipList::SkipList() { level = 0; @@ -63,6 +66,18 @@ SkipList::SkipList() { } +SkipList::~SkipList(){ + delete header; + for(int i=0; i <= level; i++) { + Node *node = header->forward[i]; + Node* temp; + while(node != NULL) { + temp = node; + node = node->forward[i]; + delete temp; + } + } +} /** From 86c6af46e865d78e9a41256414690ded7916efb3 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 17:27:45 +0400 Subject: [PATCH 206/261] doxygen documentation and tests added --- search/fibonacci_search.cpp | 140 +++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 24 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index 0bf33c494..2a3ba7207 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -1,12 +1,19 @@ +/** + * Copyright 2020 @author sprintyaf + * @file + * @brief [Fibonacci search + * algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique) + */ + #include -#include +#include // for std::vector class +#include // for assert -/* -Input: a sorted array and a value -Output: if the array contains the value, returns its index (index of its first occurence) - else returns -1 -*/ + +/** + * Returns minimum of the two numbers + */ int min(int first, int second){ if(first < second){ return first; @@ -15,7 +22,12 @@ int min(int first, int second){ } } -int fibonacci_search(std::vector arr, int value){ +/** + * Input: a sorted array and a value + * Output: if the array contains the value, returns its index + * else returns -1 + */ +int fibonacci_search(std::vector &arr, int value){ int last = 0, current = 1, offset = -1, index; int length = arr.size(); int next = last + current; @@ -47,23 +59,103 @@ int fibonacci_search(std::vector arr, int value){ return -1; } -int main() { - int size, value; - std::cout << "Enter size of a sorted array: " << std::endl; - std::cin >> size; - std::cout << "Enter array elements: " << std::endl; +/** + * Tests where given value occurs only once + */ +bool one_occurence_test(){ + // declarations + int value, index; + bool passed = true; + std::vector arr; + // last element + arr = {1, 2, 3}; + value = 3; + index = fibonacci_search(arr, value); + passed = passed && (index == 2); + // first element + value = 1; + index = fibonacci_search(arr, value); + passed = passed && (index == 0); + // somewhere in the middle element + arr = {1, 3, 5, 7}; + value = 3; + index = fibonacci_search(arr, value); + passed = passed && (index == 1); + // arr size is 1 + arr = {10}; + value = 10; + index = fibonacci_search(arr, value); + passed = passed && (index == 0); - std::vector arr(size); - for(int i = 0; i < size; i++){ - std::cin >> arr[i]; - } - std::cout << "Enter the value you're looking for: " << std::endl; - std::cin >> value; - int index = fibonacci_search(arr, value); - if(index != -1){ - std::cout << "Index of the given value is " << index << std::endl; - } else { - std::cout << "Array does not contain the value" << std::endl; - } + return passed; +} + +/** + * Tests where given value occurs more than once + */ +bool many_occurence_test(){ + // declarations + int value, index; + bool passed = true; + std::vector arr; + // last element + arr = {1, 1, 10, 10}; + value = 10; + index = fibonacci_search(arr, value); + passed = passed && (index == 2 || index == 3); + // first element + value = 1; + index = fibonacci_search(arr, value); + passed = passed && (index == 0 || index == 1); + // somewhere in the middle element + arr = {1, 3, 3, 7}; + value = 3; + index = fibonacci_search(arr, value); + passed = passed && (index == 1 || index == 2); + // all elements are the same + arr = {10, 10, 10}; + value = 10; + index = fibonacci_search(arr, value); + passed = passed && (index >= 0 && index <= 2); + + return passed; +} + +/** + * Tests where the array doesn't contain given value + */ +bool no_occurence_test(){ + // declarations + int value, index; + bool passed = true; + std::vector arr; + // many elements + arr = {1, 2, 4, 5}; + value = 3; + index = fibonacci_search(arr, value); + passed = passed && (index == -1); + // one element + arr = {1}; + value = 2; + index = fibonacci_search(arr, value); + passed = passed && (index == -1); + // empty array + arr.clear(); + value = 10; + index = fibonacci_search(arr, value); + passed = passed && (index == -1); + + return passed; +} + + +/** + * Main Function + * testing the algorithm + */ +int main() { + assert(one_occurence_test()); + assert(many_occurence_test()); + assert(no_occurence_test()); return 0; } From 8e53f4da833c4e5410a74e26dce8b15cb46b41a0 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 17:54:55 +0400 Subject: [PATCH 207/261] converted from vector to array --- search/fibonacci_search.cpp | 65 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index 2a3ba7207..5cdc93ae9 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -23,13 +23,12 @@ int min(int first, int second){ } /** - * Input: a sorted array and a value + * Input: a sorted array, a value we're looking for and size of the array * Output: if the array contains the value, returns its index * else returns -1 */ -int fibonacci_search(std::vector &arr, int value){ +int fibonacci_search(int *arr, int value, int length){ int last = 0, current = 1, offset = -1, index; - int length = arr.size(); int next = last + current; while(next < length){ @@ -53,7 +52,7 @@ int fibonacci_search(std::vector &arr, int value){ return index; } } - if(current && !arr.empty() && arr[offset+1] == value){ + if(current && (length > 0) && arr[offset+1] == value){ return offset+1; } return -1; @@ -64,27 +63,29 @@ int fibonacci_search(std::vector &arr, int value){ */ bool one_occurence_test(){ // declarations - int value, index; + int value, index, length; bool passed = true; - std::vector arr; // last element - arr = {1, 2, 3}; + length = 3; + int arr1[length] = {1, 2, 3}; value = 3; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr1, value, length); passed = passed && (index == 2); // first element value = 1; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr1, value, length); passed = passed && (index == 0); // somewhere in the middle element - arr = {1, 3, 5, 7}; + length = 4; + int arr2[length] = {1, 3, 5, 7}; value = 3; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr2, value, length); passed = passed && (index == 1); // arr size is 1 - arr = {10}; + length = 1; + int arr3[length] = {10}; value = 10; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr3, value, length); passed = passed && (index == 0); return passed; @@ -95,27 +96,29 @@ bool one_occurence_test(){ */ bool many_occurence_test(){ // declarations - int value, index; + int value, index, length; bool passed = true; - std::vector arr; // last element - arr = {1, 1, 10, 10}; + length = 4; + int arr1[length] = {1, 1, 10, 10}; value = 10; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr1, value, length); passed = passed && (index == 2 || index == 3); // first element value = 1; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr1, value, length); passed = passed && (index == 0 || index == 1); // somewhere in the middle element - arr = {1, 3, 3, 7}; + length = 4; + int arr2[length] = {1, 3, 3, 7}; value = 3; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr2, value, length); passed = passed && (index == 1 || index == 2); // all elements are the same - arr = {10, 10, 10}; + length = 3; + int arr3[length] = {10, 10, 10}; value = 10; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr3, value, length); passed = passed && (index >= 0 && index <= 2); return passed; @@ -126,23 +129,25 @@ bool many_occurence_test(){ */ bool no_occurence_test(){ // declarations - int value, index; + int value, index, length; bool passed = true; - std::vector arr; // many elements - arr = {1, 2, 4, 5}; + length = 4; + int arr1[length] = {1, 2, 4, 5}; value = 3; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr1, value, length); passed = passed && (index == -1); // one element - arr = {1}; + length = 1; + int arr2[length] = {1}; value = 2; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr2, value, length); passed = passed && (index == -1); // empty array - arr.clear(); + length = 0; + int arr3[length]; value = 10; - index = fibonacci_search(arr, value); + index = fibonacci_search(arr3, value, length); passed = passed && (index == -1); return passed; From 4b3749ed49d863bbfd2090c56151586962c7b78d Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 17:59:49 +0400 Subject: [PATCH 208/261] variable-length arrays fixed --- search/fibonacci_search.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index 5cdc93ae9..f8525a6b4 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -67,7 +67,7 @@ bool one_occurence_test(){ bool passed = true; // last element length = 3; - int arr1[length] = {1, 2, 3}; + int arr1[3] = {1, 2, 3}; value = 3; index = fibonacci_search(arr1, value, length); passed = passed && (index == 2); @@ -77,13 +77,13 @@ bool one_occurence_test(){ passed = passed && (index == 0); // somewhere in the middle element length = 4; - int arr2[length] = {1, 3, 5, 7}; + int arr2[4] = {1, 3, 5, 7}; value = 3; index = fibonacci_search(arr2, value, length); passed = passed && (index == 1); // arr size is 1 length = 1; - int arr3[length] = {10}; + int arr3[1] = {10}; value = 10; index = fibonacci_search(arr3, value, length); passed = passed && (index == 0); @@ -100,7 +100,7 @@ bool many_occurence_test(){ bool passed = true; // last element length = 4; - int arr1[length] = {1, 1, 10, 10}; + int arr1[4] = {1, 1, 10, 10}; value = 10; index = fibonacci_search(arr1, value, length); passed = passed && (index == 2 || index == 3); @@ -110,13 +110,13 @@ bool many_occurence_test(){ passed = passed && (index == 0 || index == 1); // somewhere in the middle element length = 4; - int arr2[length] = {1, 3, 3, 7}; + int arr2[4] = {1, 3, 3, 7}; value = 3; index = fibonacci_search(arr2, value, length); passed = passed && (index == 1 || index == 2); // all elements are the same length = 3; - int arr3[length] = {10, 10, 10}; + int arr3[3] = {10, 10, 10}; value = 10; index = fibonacci_search(arr3, value, length); passed = passed && (index >= 0 && index <= 2); @@ -133,19 +133,19 @@ bool no_occurence_test(){ bool passed = true; // many elements length = 4; - int arr1[length] = {1, 2, 4, 5}; + int arr1[4] = {1, 2, 4, 5}; value = 3; index = fibonacci_search(arr1, value, length); passed = passed && (index == -1); // one element length = 1; - int arr2[length] = {1}; + int arr2[1] = {1}; value = 2; index = fibonacci_search(arr2, value, length); passed = passed && (index == -1); // empty array length = 0; - int arr3[length]; + int arr3[10] = {}; value = 10; index = fibonacci_search(arr3, value, length); passed = passed && (index == -1); From f7ab869d90db9666592980e87ce3465f76de2aaf Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:16:38 +0400 Subject: [PATCH 209/261] skip list update --- data_structures/skip_list.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 782486632..480e9dedf 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -7,25 +7,22 @@ #include #include -#include #include #include #include -#include // using namespace std; using std::vector; using std::endl; -#define MAXLVL 2 -#define P 0.5 +#define MAXLVL 2 ///< maximum level of skip list +#define P 0.5 ///< current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] */ -class Node { -public: +struct Node { int key; void* value; /*Forward Array*/ @@ -38,7 +35,7 @@ Node::Node(int key, int level, void* value) { this->key = key; /*Initialization of forward vector*/ - for (int i = 0; i < sizeof(Node*)*(level+1); i++){ + for (int i = 0; i < (level+1); i++){ forward.push_back(NULL); } } @@ -67,7 +64,6 @@ SkipList::SkipList() { SkipList::~SkipList(){ - delete header; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; Node* temp; @@ -77,6 +73,7 @@ SkipList::~SkipList(){ delete temp; } } + delete header; } @@ -201,12 +198,10 @@ int main() SkipList lst; for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (std::rand()% (1 << (MAXLVL+1) + 1)); + int k = (std::rand()%( 1 << (MAXLVL+2)) + 1); lst.insertElement(k, &j); } lst.displayList(); - - } From fd8affb59d86b90f244adcd3ccb49dc2b1acf09a Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:20:21 +0400 Subject: [PATCH 210/261] skip_list --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 480e9dedf..9d829349e 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include // using namespace std; using std::vector; From 4cebe7c68270e5474e1b0a3c65355157a741b23b Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 18:21:12 +0400 Subject: [PATCH 211/261] skip_list --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 9d829349e..180d9c32d 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -193,7 +193,7 @@ void SkipList::displayList() { int main() { - std::srand(time(nullptr)); + std::srand(std::time(nullptr)); SkipList lst; From ac0d11977d0b8fcc3396855bed490bfc690b2ad4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:17:37 +0400 Subject: [PATCH 212/261] skip_list --- data_structures/skip_list.cpp | 66 ++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 180d9c32d..c41d3c2e1 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -2,7 +2,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Pseudo Code. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Code and PseudoCode. */ #include @@ -15,28 +15,31 @@ using std::vector; using std::endl; -#define MAXLVL 2 ///< maximum level of skip list -#define P 0.5 ///< current probability for "coin toss" +#define MAX_LEVEL 2 ///< maximum level of skip list +#define PROBABILITY 0.5 ///< current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] */ struct Node { - int key; + int key; + /* pointer of value */ void* value; /*Forward Array*/ vector forward; Node(int key, int level, void* value); }; - +/** + * Creates node with provided key, level and value; +*/ Node::Node(int key, int level, void* value) { this->key = key; /*Initialization of forward vector*/ for (int i = 0; i < (level+1); i++){ - forward.push_back(NULL); + forward.push_back(nullptr); } } @@ -55,11 +58,13 @@ public: }; - +/**\ + * Skeep List constructor; +*/ SkipList::SkipList() { level = 0; /* Header initialization*/ - header = new Node(-1, MAXLVL, NULL); + header = new Node(-1, MAX_LEVEL, nullptr); } @@ -67,7 +72,7 @@ SkipList::~SkipList(){ for(int i=0; i <= level; i++) { Node *node = header->forward[i]; Node* temp; - while(node != NULL) { + while(node != nullptr) { temp = node; node = node->forward[i]; delete temp; @@ -82,27 +87,31 @@ SkipList::~SkipList(){ */ int SkipList::randomLevel() { int lvl = 0; - while(static_cast(std::rand())/RAND_MAX < P && lvl < MAXLVL) lvl++; + while(static_cast(std::rand())/RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; return lvl; } -// Insert given key in skip list + +/** + * Inserts elements with given key and value; + * It's level is computed by randomLevel() function. +*/ void SkipList::insertElement(int key, void* value) { std::cout << "Inserting" << key << "..."; Node *x = header; - Node *update[MAXLVL+1]; - memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + Node *update[MAX_LEVEL+1]; + memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); for(int i = level; i >= 0; i--) { - while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; update[i] = x; } x = x->forward[0]; - bool doesnt_exist = (x == NULL || x->key != key); + bool doesnt_exist = (x == nullptr || x->key != key); if (doesnt_exist) { int rlevel = randomLevel(); @@ -130,17 +139,17 @@ void SkipList::deleteElement(int key) { Node *x = header; - Node *update[MAXLVL+1]; - memset(update, 0, sizeof(Node*)*(MAXLVL+1)); + Node *update[MAX_LEVEL+1]; + memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); for(int i = level; i >= 0; i--) { - while(x->forward[i] != NULL && x->forward[i]->key < key) x = x->forward[i]; + while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; update[i] = x; } x = x->forward[0]; - bool doesnt_exist = (x == NULL || x->key != key); + bool doesnt_exist = (x == nullptr || x->key != key); if(!doesnt_exist) { for(int i=0;i<=level;i++) { @@ -173,32 +182,39 @@ void* SkipList::searchElement(int key) { return x->value; } else { std::cout << "Not Found" << endl; - return NULL; + return nullptr; } } -// Display skip list level wise +/** + * Display skip list level wise + */ void SkipList::displayList() { std::cout << "Displaying list:\n" << endl; for(int i=0; i <= level; i++) { Node *node = header->forward[i]; std::cout << "Level " << (i) << ": "; - while(node != NULL) { + while(node != nullptr) { std::cout << node->key << " "; node = node->forward[i]; } std::cout << endl; } } - + + +/** + * Main function: + * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it + */ int main() { std::srand(std::time(nullptr)); SkipList lst; - for (int j = 0; j < (1 << (MAXLVL+1)); j++){ - int k = (std::rand()%( 1 << (MAXLVL+2)) + 1); + for (int j = 0; j < (1 << (MAX_LEVEL+1)); j++){ + int k = (std::rand()%( 1 << (MAX_LEVEL+2)) + 1); lst.insertElement(k, &j); } From d5b897d40e3354e64c6c1bb1bf91435a2bb769b4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:22:32 +0400 Subject: [PATCH 213/261] improve --- data_structures/skip_list.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index c41d3c2e1..5881f5d27 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -7,8 +7,7 @@ #include #include -#include -#include +#include #include // using namespace std; From ea57ad29cd350a265be297a49bc8c65c8dfcc825 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:55:47 +0400 Subject: [PATCH 214/261] improve --- data_structures/skip_list.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 5881f5d27..eb8e5cd87 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -23,26 +23,28 @@ using std::endl; */ struct Node { int key; - /* pointer of value */ + //pointer of value void* value; - /*Forward Array*/ + //Forward Array vector forward; Node(int key, int level, void* value); }; /** - * Creates node with provided key, level and value; + * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { this->key = key; - /*Initialization of forward vector*/ + //Initialization of forward vector for (int i = 0; i < (level+1); i++){ forward.push_back(nullptr); } } -// Class for Skip list +/** + * SkipList class +*/ class SkipList { int level; Node *header; @@ -57,12 +59,12 @@ public: }; -/**\ - * Skeep List constructor; +/** + * Skeep List constructor */ SkipList::SkipList() { level = 0; - /* Header initialization*/ + // Header initialization header = new Node(-1, MAX_LEVEL, nullptr); } @@ -117,7 +119,7 @@ void SkipList::insertElement(int key, void* value) { if(rlevel > level) { for(int i=level+1;i Date: Tue, 7 Jul 2020 19:58:10 +0400 Subject: [PATCH 215/261] improve --- data_structures/skip_list.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index eb8e5cd87..25a9aae2a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,4 +1,4 @@ -/** +/* * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * @@ -18,7 +18,7 @@ using std::endl; #define PROBABILITY 0.5 ///< current probability for "coin toss" -/** +/* * Node structure [Key][Node*, Node*...] */ struct Node { @@ -30,7 +30,7 @@ struct Node { Node(int key, int level, void* value); }; -/** +/* * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { @@ -42,7 +42,7 @@ Node::Node(int key, int level, void* value) { } } -/** +/* * SkipList class */ class SkipList { @@ -59,7 +59,7 @@ public: }; -/** +/* * Skeep List constructor */ SkipList::SkipList() { @@ -83,7 +83,7 @@ SkipList::~SkipList(){ } -/** +/* * Returns random level for skip list; */ int SkipList::randomLevel() { @@ -94,7 +94,7 @@ int SkipList::randomLevel() { -/** +/* * Inserts elements with given key and value; * It's level is computed by randomLevel() function. */ @@ -135,7 +135,9 @@ void SkipList::insertElement(int key, void* value) { } } - /**Delete document by key*/ +/* + * Delete document by key +*/ void SkipList::deleteElement(int key) { Node *x = header; @@ -166,7 +168,7 @@ void SkipList::deleteElement(int key) } -/** +/* * Searching element in skip list structure */ void* SkipList::searchElement(int key) { @@ -187,7 +189,7 @@ void* SkipList::searchElement(int key) { } } -/** +/* * Display skip list level wise */ void SkipList::displayList() { @@ -204,7 +206,7 @@ void SkipList::displayList() { } -/** +/* * Main function: * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it */ From 662841bac7e69b6414ab09ed9871b63de7b6b65d Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 19:59:54 +0400 Subject: [PATCH 216/261] improve --- data_structures/skip_list.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 25a9aae2a..729ce1d80 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -18,7 +18,7 @@ using std::endl; #define PROBABILITY 0.5 ///< current probability for "coin toss" -/* +/** * Node structure [Key][Node*, Node*...] */ struct Node { @@ -30,7 +30,7 @@ struct Node { Node(int key, int level, void* value); }; -/* +/** * Creates node with provided key, level and value */ Node::Node(int key, int level, void* value) { @@ -42,7 +42,7 @@ Node::Node(int key, int level, void* value) { } } -/* +/** * SkipList class */ class SkipList { @@ -59,7 +59,7 @@ public: }; -/* +/** * Skeep List constructor */ SkipList::SkipList() { @@ -68,7 +68,9 @@ SkipList::SkipList() { header = new Node(-1, MAX_LEVEL, nullptr); } - +/** + * Destructor for skiplist class +*/ SkipList::~SkipList(){ for(int i=0; i <= level; i++) { Node *node = header->forward[i]; @@ -83,7 +85,7 @@ SkipList::~SkipList(){ } -/* +/** * Returns random level for skip list; */ int SkipList::randomLevel() { @@ -94,7 +96,7 @@ int SkipList::randomLevel() { -/* +/** * Inserts elements with given key and value; * It's level is computed by randomLevel() function. */ @@ -135,7 +137,7 @@ void SkipList::insertElement(int key, void* value) { } } -/* +/** * Delete document by key */ void SkipList::deleteElement(int key) @@ -168,7 +170,7 @@ void SkipList::deleteElement(int key) } -/* +/** * Searching element in skip list structure */ void* SkipList::searchElement(int key) { @@ -206,7 +208,7 @@ void SkipList::displayList() { } -/* +/** * Main function: * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it */ From 45b21f287116aaffd52fe8b40a9d5104a5ab31e7 Mon Sep 17 00:00:00 2001 From: enqidu Date: Tue, 7 Jul 2020 20:29:37 +0400 Subject: [PATCH 217/261] improve --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 729ce1d80..1fc9f3e0e 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,4 +1,4 @@ -/* +/** * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * From 8216a3267fb35d471b38b657c9e4aca7a819f5e6 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 20:38:40 +0400 Subject: [PATCH 218/261] randomized tests, documentation, back to vector --- search/fibonacci_search.cpp | 161 ++++++++++++------------------------ 1 file changed, 54 insertions(+), 107 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index f8525a6b4..e2796b0ba 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -1,6 +1,6 @@ /** * Copyright 2020 @author sprintyaf - * @file + * @file fibonacci_search.cpp * @brief [Fibonacci search * algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique) */ @@ -8,27 +8,21 @@ #include #include // for std::vector class #include // for assert +#include // for random numbers +#include // for sorting /** - * Returns minimum of the two numbers + * @brief using fibonacci search algorithm finds an index of a given element in a sorted array + * + * @param arr sorted array + * @param value value that we're looking for + * @returns if the array contains the value, returns an index of the element. otherwise -1. */ -int min(int first, int second){ - if(first < second){ - return first; - } else { - return second; - } -} - -/** - * Input: a sorted array, a value we're looking for and size of the array - * Output: if the array contains the value, returns its index - * else returns -1 - */ -int fibonacci_search(int *arr, int value, int length){ +int fibonacci_search(const std::vector &arr, int value){ int last = 0, current = 1, offset = -1, index; + int length = arr.size(); int next = last + current; while(next < length){ @@ -38,7 +32,7 @@ int fibonacci_search(int *arr, int value, int length){ } while(next > 1){ - index = min(offset + last, length-1); + index = std::min(offset + last, length-1); if(arr[index] < value){ next = current; current = last; @@ -52,115 +46,68 @@ int fibonacci_search(int *arr, int value, int length){ return index; } } - if(current && (length > 0) && arr[offset+1] == value){ + if(current && !arr.empty() && arr[offset+1] == value){ return offset+1; } return -1; } /** - * Tests where given value occurs only once - */ -bool one_occurence_test(){ - // declarations - int value, index, length; + * @brief random tests for checking performance when an array doesn't contain an element +*/ +bool no_occurence_tests(){ bool passed = true; - // last element - length = 3; - int arr1[3] = {1, 2, 3}; - value = 3; - index = fibonacci_search(arr1, value, length); - passed = passed && (index == 2); - // first element - value = 1; - index = fibonacci_search(arr1, value, length); - passed = passed && (index == 0); - // somewhere in the middle element - length = 4; - int arr2[4] = {1, 3, 5, 7}; - value = 3; - index = fibonacci_search(arr2, value, length); - passed = passed && (index == 1); - // arr size is 1 - length = 1; - int arr3[1] = {10}; - value = 10; - index = fibonacci_search(arr3, value, length); - passed = passed && (index == 0); - + int rand_num, rand_value, index, num_tests = 1000; + std::vector arr; + while(num_tests--){ + arr.clear(); + for(int i = 0; i < 100; i++){ + rand_num = rand() % 1000; + arr.push_back(rand_num); + } + rand_value = rand() % 1000; + while(std::find(arr.begin(), arr.end(), rand_value) != arr.end()){ + std::remove(arr.begin(), arr.end(), rand_value); + } + sort(arr.begin(), arr.end()); + index = fibonacci_search(arr, rand_value); + passed = passed && (index == -1); + } return passed; } /** - * Tests where given value occurs more than once - */ -bool many_occurence_test(){ - // declarations - int value, index, length; + * @brief random tests which cover cases when we have one, multiple or zero occurences of the value we're looking for +*/ +bool random_tests(){ bool passed = true; - // last element - length = 4; - int arr1[4] = {1, 1, 10, 10}; - value = 10; - index = fibonacci_search(arr1, value, length); - passed = passed && (index == 2 || index == 3); - // first element - value = 1; - index = fibonacci_search(arr1, value, length); - passed = passed && (index == 0 || index == 1); - // somewhere in the middle element - length = 4; - int arr2[4] = {1, 3, 3, 7}; - value = 3; - index = fibonacci_search(arr2, value, length); - passed = passed && (index == 1 || index == 2); - // all elements are the same - length = 3; - int arr3[3] = {10, 10, 10}; - value = 10; - index = fibonacci_search(arr3, value, length); - passed = passed && (index >= 0 && index <= 2); - + int rand_num, rand_value, index, real_value, num_tests = 10000; + std::vector arr; + while(num_tests--){ + arr.clear(); + for(int i = 0; i < 100; i++){ + rand_num = rand() % 1000; + arr.push_back(rand_num); + } + rand_value = rand() % 1000; + sort(arr.begin(), arr.end()); + index = fibonacci_search(arr, rand_value); + if(index != -1){ + real_value = arr[index]; + passed = passed && (real_value == rand_value); + } else { + passed = passed && (std::find(arr.begin(), arr.end(), rand_value) == arr.end()); + } + } return passed; } -/** - * Tests where the array doesn't contain given value - */ -bool no_occurence_test(){ - // declarations - int value, index, length; - bool passed = true; - // many elements - length = 4; - int arr1[4] = {1, 2, 4, 5}; - value = 3; - index = fibonacci_search(arr1, value, length); - passed = passed && (index == -1); - // one element - length = 1; - int arr2[1] = {1}; - value = 2; - index = fibonacci_search(arr2, value, length); - passed = passed && (index == -1); - // empty array - length = 0; - int arr3[10] = {}; - value = 10; - index = fibonacci_search(arr3, value, length); - passed = passed && (index == -1); - - return passed; -} - - /** * Main Function * testing the algorithm */ int main() { - assert(one_occurence_test()); - assert(many_occurence_test()); - assert(no_occurence_test()); + assert(no_occurence_tests()); + assert(random_tests()); return 0; } From cf6b77a7dce59afb35cb62a8bb6bc780ad958ec5 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 20:45:03 +0400 Subject: [PATCH 219/261] rand fixed --- search/fibonacci_search.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index e2796b0ba..067d8e636 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -62,10 +62,10 @@ bool no_occurence_tests(){ while(num_tests--){ arr.clear(); for(int i = 0; i < 100; i++){ - rand_num = rand() % 1000; + rand_num = std::rand() % 1000; arr.push_back(rand_num); } - rand_value = rand() % 1000; + rand_value = std::rand() % 1000; while(std::find(arr.begin(), arr.end(), rand_value) != arr.end()){ std::remove(arr.begin(), arr.end(), rand_value); } @@ -86,11 +86,11 @@ bool random_tests(){ while(num_tests--){ arr.clear(); for(int i = 0; i < 100; i++){ - rand_num = rand() % 1000; + rand_num = std::rand() % 1000; arr.push_back(rand_num); } - rand_value = rand() % 1000; - sort(arr.begin(), arr.end()); + rand_value = std::rand() % 1000; + std::sort(arr.begin(), arr.end()); index = fibonacci_search(arr, rand_value); if(index != -1){ real_value = arr[index]; From 644524337a9112491b59d87df3890d276078007d Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Tue, 7 Jul 2020 22:53:12 +0400 Subject: [PATCH 220/261] copyright removed --- search/fibonacci_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index 067d8e636..dd1b06f11 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2020 @author sprintyaf + * @author sprintyaf * @file fibonacci_search.cpp * @brief [Fibonacci search * algorithm](https://en.wikipedia.org/wiki/Fibonacci_search_technique) From 0e9585d080b8789ead0886adcac318671175543f Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Wed, 8 Jul 2020 12:30:13 -0400 Subject: [PATCH 221/261] remove Copyright from docs --- data_structures/trie_modern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/trie_modern.cpp b/data_structures/trie_modern.cpp index c2eba30e0..470af07a4 100644 --- a/data_structures/trie_modern.cpp +++ b/data_structures/trie_modern.cpp @@ -1,7 +1,7 @@ /** * @file * - * Copyright 2020 @author Anmol3299 + * @author Anmol3299 * \brief A basic implementation of trie class to store only lower-case strings. */ #include // for io operations From 59a8b3d4a295e7af34437151e0f50c973eb7e77d Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:43:52 +0400 Subject: [PATCH 222/261] Update data_structures/skip_list.cpp Co-authored-by: David Leal --- data_structures/skip_list.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 1fc9f3e0e..62ae51ea9 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -210,7 +210,8 @@ void SkipList::displayList() { /** * Main function: - * Creates and inserts random 2^[number of levels] elements into the skip lists and than displays it + * Creates and inserts random 2^[number of levels] + * elements into the skip lists and than displays it */ int main() { From a5ca794aa4e27e6fb5d9c6e591449458ee5b8fe4 Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:46:50 +0400 Subject: [PATCH 223/261] sk --- data_structures/skip_list.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 1fc9f3e0e..b7aab7882 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -10,7 +10,6 @@ #include #include -// using namespace std; using std::vector; using std::endl; @@ -23,9 +22,9 @@ using std::endl; */ struct Node { int key; - //pointer of value + // pointer of value void* value; - //Forward Array + // Forward Array vector forward; Node(int key, int level, void* value); }; From bba0db36ec5aa125fa4acdb35191e8348aaa670b Mon Sep 17 00:00:00 2001 From: enqidu Date: Wed, 8 Jul 2020 20:47:43 +0400 Subject: [PATCH 224/261] sk --- data_structures/skip_list.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 3e13ee696..922c5a1e3 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -120,7 +120,7 @@ void SkipList::insertElement(int key, void* value) { if(rlevel > level) { for(int i=level+1;iforward[i] != x) break; update[i]->forward[i] = x->forward[i]; } - /*Remove empty levels*/ + /* Remove empty levels*/ while(level>0 && header->forward[level] == 0) level--; std::cout << "Deleted" << endl; } else { From 497d627ebde140b14dde08e25d98b7049886601d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Thu, 9 Jul 2020 18:15:05 -0400 Subject: [PATCH 225/261] [improvement] updated contribution guidelines (#945) * updated contribution guidelines * fix case --- CONTRIBUTING.md | 87 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f0205bfd..35d875d43 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,8 +28,85 @@ We are very happy that you consider implementing algorithms and data structures - Strictly use snake_case (underscore_separated) in filenames. - If you have added or modified code, please make sure the code compiles before submitting. - Our automated testing runs [__cpplint__](https://github.com/cpplint/cpplint) on all pull requests so please be sure that your code passes before submitting. +- Please conform to [doxygen](https://www.doxygen.nl/manual/docblocks.html) standard and document the code as much as possible. This not only facilitates the readers but also generates the correct info on website. - **Be consistent in use of these guidelines.** +#### Documentation +- Make sure you put useful comments in your code. Do not comment things that are obvious. +- Please avoid creating new directories if at all possible. Try to fit your work into the existing directory structure. If you want to create a new directory, then please check if a similar category has been recently suggested or created by other pull requests. +- If you have modified/added documentation, please ensure that your language is concise and contains no grammar errors. +- Do not update README.md along with other changes, first create an issue and then link to that issue in your pull request to suggest specific changes required to README.md +- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repo website](https://thealgorithms.github.io/C-Plus-Plus). Please ensure the code is documented in this structure. Sample implementation is given below. + +#### Test +- Make sure to add examples and test cases in your main() function. +- If you find any algorithm or document without tests, please feel free to create a pull request or issue describing suggested changes. +- Please try to add one or more `test()` functions that will invoke the algorithm implementation on random test data with expected output. Use `assert()` function to confirm that the tests will pass. + +#### Typical structure of a program: +```cpp +/** + * @file + * @brief Add one line description here + * @details + * This is a multi line + * description containing links, references, + * math equations, etc + * @author [Name](https://github.com/handle) + * @see related_file.cpp, another_file.cpp + */ + +#include + +/** + * @namespace + */ +namespace name { + +/** + * Class documentation + */ +class cls_name{ + private: + int var1; ///< short info of this variable + char *msg; ///< short info + + public: + // other members also documented as below +} + +/** + * Function documentation + * @tparam T this is a one-line info about T + * @param param1 on-line info about param1 + * @param param2 on-line info about param2 + * @returns `true` if ... + * @returns `false` if ... + */ +template +bool func(int param1, T param2) { + // function statements here + if(/*something bad*/) + return false; + + return true; +} + +/** Test function */ +void test() { + /* some statements */ + assert(func(...) == ...); // this ensures that the algorithm works as expected + + // can have multiple checks +} + +/** Main function */ +int main(int argc, char *argv[]) { + // code here + return 0; +} +``` + #### New File Name guidelines - Use lowercase words with ``"_"`` as separator - For instance @@ -70,16 +147,6 @@ Common prefixes: - docs: Documentation changes - test: Correct existing tests or add new ones -#### Documentation -- Make sure you put useful comments in your code. Do not comment things that are obvious. -- Please avoid creating new directories if at all possible. Try to fit your work into the existing directory structure. If you want to create a new directory, then please check if a similar category has been recently suggested or created by other pull requests. -- If you have modified/added documentation, please ensure that your language is concise and contains no grammar errors. -- Do not update README.md along with other changes, first create an issue and then link to that issue in your pull request to suggest specific changes required to README.md - -#### Test -- Make sure to add examples and test cases in your main() function. -- If you find any algorithm or document without tests, please feel free to create a pull request or issue describing suggested changes. - ### Pull Requests - Checkout our [pull request template](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/.github/pull_request_template.md) From bf2dac6de238cabf81092ca76176c91596771543 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 10:43:05 -0400 Subject: [PATCH 226/261] enable gitpod for all branches --- .gitpod.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitpod.yml b/.gitpod.yml index 40750258c..ece107997 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -7,6 +7,7 @@ github: addComment: false addCheck: false master: true + branches: true pullRequestsFromForks: true vscode: From ebd13a7e241df3a3963f6fc728bd37c826291927 Mon Sep 17 00:00:00 2001 From: Rajiv Ranjan Singh Date: Fri, 10 Jul 2020 20:32:59 +0530 Subject: [PATCH 227/261] Improved sieve_of_eratosthenes.cpp (#933) * Update sieve_of_eratosthenes.cpp * removed unwanted spaces * removed init function Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/sieve_of_eratosthenes.cpp | 49 +++++++++++++++------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/math/sieve_of_eratosthenes.cpp b/math/sieve_of_eratosthenes.cpp index d8fa70531..e30bc1891 100644 --- a/math/sieve_of_eratosthenes.cpp +++ b/math/sieve_of_eratosthenes.cpp @@ -10,25 +10,21 @@ * @see primes_up_to_billion.cpp prime_numbers.cpp */ -#include - -/** Maximum number of primes */ -#define MAX 10000000 - -/** array to store the primes */ -bool isprime[MAX]; +#include // for io operations /** * This is the function that finds the primes and eliminates * the multiples. + * @param N number of primes to check + * @param [out] isprime a boolean array of size `N` identifying if `i`^th number is prime or not */ -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; +void sieve(uint32_t N, bool *isprime) { + isprime[0] = true; + isprime[1] = true; + for (uint32_t i = 2; i * i <= N; i++) { + if (!isprime[i]) { + for (uint32_t j = (i << 1); j <= N; j = j + i) { + isprime[j] = true; } } } @@ -36,10 +32,12 @@ void sieve(uint32_t N) { /** * This function prints out the primes to STDOUT + * @param N number of primes to check + * @param [in] isprime a boolean array of size `N` identifying if `i`^th number is prime or not */ -void print(uint32_t N) { - for (uint32_t i = 1; i <= N; i++) { - if (isprime[i]) { +void print(uint32_t N, const bool *isprime) { + for (uint32_t i = 2; i <= N; i++) { + if (!isprime[i]) { std::cout << i << ' '; } } @@ -47,19 +45,14 @@ void print(uint32_t N) { } /** - * Initialize the array + * Main function */ -void init() { - for (uint32_t i = 1; i < MAX; i++) { - isprime[i] = true; - } -} - -/** main function */ int main() { uint32_t N = 100; - init(); - sieve(N); - print(N); + bool *isprime = new bool[N]; + sieve(N, isprime); + print(N, isprime); + delete[] isprime; + return 0; } From 58099884dd626ba94602fa00351d8e6c5f49c9e9 Mon Sep 17 00:00:00 2001 From: sprintyaf Date: Fri, 10 Jul 2020 19:13:16 +0400 Subject: [PATCH 228/261] comments added --- search/fibonacci_search.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/search/fibonacci_search.cpp b/search/fibonacci_search.cpp index dd1b06f11..be181a47d 100644 --- a/search/fibonacci_search.cpp +++ b/search/fibonacci_search.cpp @@ -21,34 +21,48 @@ * @returns if the array contains the value, returns an index of the element. otherwise -1. */ int fibonacci_search(const std::vector &arr, int value){ - int last = 0, current = 1, offset = -1, index; - int length = arr.size(); - int next = last + current; + // initialize last and current members of Fibonacci sequence + int last = 0, current = 1; + int length = arr.size(); // array size + // next member of Fibonacci sequence which is "last" + "current" + int next = last + current; + // "next" will store the smallest Fibonacci number greater or equal to "length" while(next < length){ last = current; current = next; next = last + current; } + // "offset" is the end of eliminated range from front + int offset = -1, index; + // while loop until there are elements left to consider. + // when "next" becomes 1, last is equal to 0, so search is done, + // because arr[offset] will already be eliminated while(next > 1){ + // check if "last" is valid location index = std::min(offset + last, length-1); + // if value is greater than the value at "index", eliminate the subarray from offset to index if(arr[index] < value){ next = current; current = last; last = next - current; offset = index; + // if value is less than the value at "index", eliminate the subarray after index+1 } else if(arr[index] > value){ next = last; current = current - last; last = next - current; + // element is found } else { return index; } } + // comparing the last element if(current && !arr.empty() && arr[offset+1] == value){ return offset+1; } + // value was not found, return -1 return -1; } From 02d947777befbf0ed7a3d3f85e7474579cf01cf0 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 11:32:37 -0400 Subject: [PATCH 229/261] [enhancement] Replace cpplint with clang-tidy (#943) * test commit for using clang-tidy instead of cpplint * add suffix -- to clang-tidy & commit * fixes to git commit * commenting redundant clang-format as clang-tidy will take care of that * add clang-tidy config file * use clang-tidy config file * test dump config to ensure config is read correctly * move test to top * test passed, removing test code Test link: https://github.com/TheAlgorithms/C-Plus-Plus/pull/943/checks?check_run_id=851231578 * fix clang-tidy config * set clang-tidy standard to c++11 * provide clang-tidy with compilation details * fix build path argument & Use clang-9 (cherry picked from commit 5eddf0cd9536f328a6a3485b5ed59705618a1433) * Merge commit '433568f9fa7c3e7f1b2e0c86c1864e92ad2668c8' * Use clang-9 * fix subprocess.STDOUT * remove pipe for stdout * bumot o clang-tidy-10 * Revert "Merge commit '433568f9fa7c3e7f1b2e0c86c1864e92ad2668c8'" This reverts commit 2a7462056a58fc9f5eda1ab8e723df2f28f34c2c. * add docs --- .clang-tidy | 6 ++++ .github/workflows/awesome_workflow.yml | 46 +++++++++++--------------- 2 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..02bb3916f --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,6 @@ +--- +Checks: '-*,google-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index f8feb1d3e..2e0792e17 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -16,7 +16,9 @@ jobs: - name: requirements run: | sudo apt -qq -y update - sudo apt -qq install clang-format + sudo apt -qq install clang-tidy-10 + # checks are passing with less errors when used with this version. + # The default installs v6.0 which did not work out well in my tests - name: Setup Git Specs run: | git config --global user.name github-actions @@ -43,18 +45,6 @@ jobs: fi done git commit -am "formatting filenames $GITHUB_SHA" || true - - name: Clang Formatter - run: | - for fname in $(find . -name '*.cpp' -o -name '*.h') - do - clang-format --verbose -i --style="$line1 $line2 $line3 $line4" "$fname" - done - git commit -am "formatting source-code for $GITHUB_SHA" || true - env: - line1: "{ BasedOnStyle: Google, UseTab: Never," - line2: "IndentWidth: 4, TabWidth: 4, " - line3: "AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false," - line4: "ColumnLimit: 80, AccessModifierOffset: -3 }" - name: Update DIRECTORY.md shell: python @@ -100,24 +90,21 @@ jobs: with open("DIRECTORY.md", "w") as out_file: out_file.write(build_directory_md(".") + "\n") - - name: Update DIRECTORY.md + - name: Commit DIRECTORY.md + run: git commit -m "updating DIRECTORY.md" DIRECTORY.md || true + - name: Get file changes run: | - cat DIRECTORY.md - git config --global user.name github-actions - git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY - git add DIRECTORY.md - git commit -am "updating DIRECTORY.md" || true - git push --force origin HEAD:$GITHUB_REF || true - - name: Install CPPLINT - run: | - python -m pip install cpplint git remote -v git branch git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY git diff --diff-filter=dr --name-only origin/master > git_diff.txt echo "Files changed-- `cat git_diff.txt`" - - name: cpplint_modified_files + - name: Configure for static lint checks + # compiling first gives clang-tidy access to all the header files and settings used to compile the programs. + # This will check for macros, if any, on linux and not for Windows. But the use of portability checks should + # be able to catch any errors for other platforms. + run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + - name: Lint modified files shell: python run: | import os @@ -135,9 +122,9 @@ jobs: if not cpp_files: sys.exit(0) - print("cpplint:") for cpp_file in cpp_files: - subprocess.run(["cpplint", "--filter=-legal/copyright,-build/include", cpp_file], check=True, text=True) + subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], + check=True, text=True, stderr=subprocess.STDOUT) # print("g++:") # compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split()) @@ -163,6 +150,11 @@ jobs: bad_files = len(upper_files + space_files + nodir_files) if bad_files: sys.exit(bad_files) + - name: Commit and push changes + run: | + git diff DIRECTORY.md + git commit -am "clang-tidy fixes for $GITHUB_SHA" || true + git push --force origin HEAD:$GITHUB_REF || true build: name: Compile checks From ab1ddb364f3116e08bd52f6424f5cfbaca484157 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 20:39:33 +0400 Subject: [PATCH 230/261] documentation --- data_structures/skip_list.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 922c5a1e3..dc9b06776 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -13,8 +13,8 @@ using std::vector; using std::endl; -#define MAX_LEVEL 2 ///< maximum level of skip list -#define PROBABILITY 0.5 ///< current probability for "coin toss" +#define MAX_LEVEL 2 ///< Maximum level of skip list +#define PROBABILITY 0.5 ///< Current probability for "coin toss" /** @@ -24,13 +24,18 @@ struct Node { int key; // pointer of value void* value; - // Forward Array + // Forward Array points to the neighbour (right) + // nodes of the given one in all levels vector forward; + // Constructor of the node Node(int key, int level, void* value); }; /** * Creates node with provided key, level and value + * @param key is number that is used for comparision + * @param level is the maximum level node's going to added + * */ Node::Node(int key, int level, void* value) { this->key = key; @@ -42,10 +47,12 @@ Node::Node(int key, int level, void* value) { } /** - * SkipList class + * SkipList class implementation with basic methods */ class SkipList { + // Maximum level of the skiplist int level; + // Pointer to the header node Node *header; public: SkipList(); @@ -59,7 +66,8 @@ public: /** - * Skeep List constructor + * Skeep List constructor. Initializes header, start + * Node for searching in the list */ SkipList::SkipList() { level = 0; @@ -85,7 +93,9 @@ SkipList::~SkipList(){ /** - * Returns random level for skip list; + * Returns random level of the skip list. + * Every higher level is 2 times less likely. + * @return lvl: random level for skip list; */ int SkipList::randomLevel() { int lvl = 0; @@ -98,6 +108,8 @@ int SkipList::randomLevel() { /** * Inserts elements with given key and value; * It's level is computed by randomLevel() function. + * @param key is number that is used for comparision + * @param value pointer to a value, that can be any type */ void SkipList::insertElement(int key, void* value) { std::cout << "Inserting" << key << "..."; @@ -137,10 +149,10 @@ void SkipList::insertElement(int key, void* value) { } /** - * Delete document by key + * Deletes an element by key and prints if has been removed successfully + * @param key is number that is used for comparision. */ -void SkipList::deleteElement(int key) -{ +void SkipList::deleteElement(int key) { Node *x = header; Node *update[MAX_LEVEL+1]; @@ -171,6 +183,8 @@ void SkipList::deleteElement(int key) /** * Searching element in skip list structure + * @param key is number that is used for comparision + * @return pointer to the value of the node */ void* SkipList::searchElement(int key) { Node *x = header; @@ -191,7 +205,7 @@ void* SkipList::searchElement(int key) { } /* - * Display skip list level wise + * Display skip list level */ void SkipList::displayList() { std::cout << "Displaying list:\n" << endl; From d59005678d7b2f294df26c088842ab3e44f85f31 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 20:40:00 +0400 Subject: [PATCH 231/261] documentation --- data_structures/skip_list.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index dc9b06776..80717050a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -35,7 +35,6 @@ struct Node { * Creates node with provided key, level and value * @param key is number that is used for comparision * @param level is the maximum level node's going to added - * */ Node::Node(int key, int level, void* value) { this->key = key; From 05bb23ca27046c7bb4954d1317ea8108b4c2cd9d Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 12:47:37 -0400 Subject: [PATCH 232/261] [enhancement] New Graphics implementation with algorithm for spirograph (#936) * added spirograph program * add graphics forlder to cmake * updating DIRECTORY.md * enable VNC for GUI programs on gitpod * fix cpplint error * fix macro definitions for correct documentation * fix filename in docs * move include from namespace to global * download and build freeglut if not available * install opengl libraries for build check * fix syntax error * fix quotes * install mesa-utils instead * use markepplace tool instead of installing * fix syntax * undo changes to github actions * OpenGL not mandatory * add private option to compile definition * fix: corrected to compile definitions instead of options * use the macro USE_GLUT * compile FREEGLUT as a subdirectory. this maintains a consistency * build freeglut_static when GLUT library not available * provide keyboard control * clang-tidy fixes for cb284bddb2a361370d08fe6926036947236bd4c5 Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- .gitpod.dockerfile | 14 +- CMakeLists.txt | 51 ++++---- DIRECTORY.md | 3 + graphics/CMakeLists.txt | 83 ++++++++++++ graphics/spirograph.cpp | 284 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 406 insertions(+), 29 deletions(-) create mode 100644 graphics/CMakeLists.txt create mode 100644 graphics/spirograph.cpp diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index 6d6a4e895..53d336f81 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,9 +1,9 @@ -FROM gitpod/workspace-full +FROM gitpod/workspace-full-vnc RUN sudo apt-get update \ - && sudo apt-get install -y \ - doxygen \ - graphviz \ - ninja-build \ - && pip install cpplint \ - && sudo rm -rf /var/lib/apt/lists/* + && sudo apt-get install -y \ + doxygen \ + graphviz \ + ninja-build \ + && pip install cpplint \ + && sudo rm -rf /var/lib/apt/lists/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 712c3db42..d7fa88559 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,28 @@ if(MSVC) endif(MSVC) option(USE_OPENMP "flag to use OpenMP for multithreading" ON) - +if(USE_OPENMP) + find_package(OpenMP) + if (OpenMP_CXX_FOUND) + message(STATUS "Building with OpenMP Multithreading.") + else() + message(STATUS "No OpenMP found, no multithreading.") + endif() +endif() + +add_subdirectory(math) +add_subdirectory(others) +add_subdirectory(search) +add_subdirectory(ciphers) +add_subdirectory(strings) +add_subdirectory(sorting) +add_subdirectory(geometry) +add_subdirectory(graphics) +add_subdirectory(probability) +add_subdirectory(data_structures) +add_subdirectory(machine_learning) +add_subdirectory(numerical_methods) + cmake_policy(SET CMP0054 NEW) cmake_policy(SET CMP0057 NEW) find_package(Doxygen OPTIONAL_COMPONENTS dot dia) @@ -34,6 +55,7 @@ if(DOXYGEN_FOUND) set(DOXYGEN_STRIP_CODE_COMMENTS NO) set(DOXYGEN_EXT_LINKS_IN_WINDOW YES) set(DOXYGEN_BUILTIN_STL_SUPPORT YES) + set(DOXYGEN_ENABLE_PREPROCESSING YES) set(DOXYGEN_CLANG_ASSISTED_PARSING YES) set(DOXYGEN_FILE_PATTERNS *.cpp *.h *.hpp *.md) set(DOXYGEN_MATHJAX_EXTENSIONS TeX/AMSmath TeX/AMSsymbols) @@ -48,6 +70,12 @@ if(DOXYGEN_FOUND) set(DOXYGEN_INTERACTIVE_SVG YES) set(DOXYGEN_DOT_IMAGE_FORMAT "svg") endif() + if(OPENMP_FOUND) + set(DOXYGEN_PREDEFINED "_OPENMP=1") + endif() + if(GLUT_FOUND) + set(DOXYGEN_PREDEFINED ${DOXYGEN_PREDEFINED} "GLUT_FOUND=1") + endif() doxygen_add_docs( doc @@ -56,27 +84,6 @@ if(DOXYGEN_FOUND) ) endif() -if(USE_OPENMP) - find_package(OpenMP) - if (OpenMP_CXX_FOUND) - message(STATUS "Building with OpenMP Multithreading.") - else() - message(STATUS "No OpenMP found, no multithreading.") - endif() -endif() - -add_subdirectory(math) -add_subdirectory(others) -add_subdirectory(search) -add_subdirectory(ciphers) -add_subdirectory(strings) -add_subdirectory(sorting) -add_subdirectory(geometry) -add_subdirectory(probability) -add_subdirectory(data_structures) -add_subdirectory(machine_learning) -add_subdirectory(numerical_methods) - set(CPACK_PROJECT_NAME ${PROJECT_NAME}) set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) include(CPack) diff --git a/DIRECTORY.md b/DIRECTORY.md index f53d2f7ab..0f7e9a053 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -84,6 +84,9 @@ * [Topological Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/topological_sort.cpp) * [Topological Sort By Kahns Algo](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graph/topological_sort_by_kahns_algo.cpp) +## Graphics + * [Spirograph](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/graphics/spirograph.cpp) + ## Greedy Algorithms * [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/dijkstra.cpp) * [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/greedy_algorithms/huffman.cpp) diff --git a/graphics/CMakeLists.txt b/graphics/CMakeLists.txt new file mode 100644 index 000000000..2ea6ca230 --- /dev/null +++ b/graphics/CMakeLists.txt @@ -0,0 +1,83 @@ +find_package(OpenGL) +if(OpenGL_FOUND) + find_package(GLUT) + if(NOT GLUT_FOUND) + message("FreeGLUT library will be downloaded and built.") + include(ExternalProject) + ExternalProject_Add ( + FREEGLUT-PRJ + URL https://sourceforge.net/projects/freeglut/files/freeglut/3.2.1/freeglut-3.2.1.tar.gz + URL_MD5 cd5c670c1086358598a6d4a9d166949d + CMAKE_GENERATOR ${CMAKE_GENERATOR} + CMAKE_GENERATOR_TOOLSET ${CMAKE_GENERATOR_TOOLSET} + CMAKE_GENERATOR_PLATFORM ${CMAKE_GENERATOR_PLATFORM} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release + -DFREEGLUT_BUILD_SHARED_LIBS=OFF + -DFREEGLUT_BUILD_STATIC_LIBS=ON + -DFREEGLUT_BUILD_DEMOS=OFF + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/freeglut + # BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/freeglut-build + # BUILD_IN_SOURCE ON + # UPDATE_COMMAND "" + INSTALL_COMMAND "" + # CONFIGURE_COMMAND "" + # BUILD_COMMAND "" + ) + ExternalProject_Get_Property(FREEGLUT-PRJ SOURCE_DIR) + ExternalProject_Get_Property(FREEGLUT-PRJ BINARY_DIR) + set(FREEGLUT_BIN_DIR ${BINARY_DIR}) + set(FREEGLUT_SRC_DIR ${SOURCE_DIR}) + # add_library(libfreeglut STATIC IMPORTED) + # set_target_properties(libfreeglut PROPERTIES IMPORTED_LOCATION ${FREEGLUT_BIN_DIR}) + + # set(FREEGLUT_BUILD_DEMOS OFF CACHE BOOL "") + # set(FREEGLUT_BUILD_SHARED_LIBS OFF CACHE BOOL "") + # set(FREEGLUT_BUILD_STATIC_LIBS ON CACHE BOOL "") + # add_subdirectory(${FREEGLUT_SRC_DIR} ${FREEGLUT_BIN_DIR} EXCLUDE_FROM_ALL) + # add_subdirectory(${BINARY_DIR}) + # find_package(FreeGLUT) + endif(NOT GLUT_FOUND) +else(OpenGL_FOUND) + message(WARNING "OPENGL not found. Will not build graphical outputs.") +endif(OpenGL_FOUND) + +# If necessary, use the RELATIVE flag, otherwise each source file may be listed +# with full pathname. RELATIVE may makes it easier to extract an executable name +# automatically. +file( GLOB APP_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp ) +# file( GLOB APP_SOURCES ${CMAKE_SOURCE_DIR}/*.c ) +# AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} APP_SOURCES) +foreach( testsourcefile ${APP_SOURCES} ) + # I used a simple string replace, to cut off .cpp. + string( REPLACE ".cpp" "" testname ${testsourcefile} ) + add_executable( ${testname} ${testsourcefile} ) + + set_target_properties(${testname} PROPERTIES LINKER_LANGUAGE CXX) + if(OpenMP_CXX_FOUND) + target_link_libraries(${testname} PRIVATE OpenMP::OpenMP_CXX) + endif() + + if(OpenGL_FOUND) + if(NOT GLUT_FOUND) + add_dependencies(${testname} FREEGLUT-PRJ) + target_compile_definitions(${testname} PRIVATE FREEGLUT_STATIC) + target_include_directories(${testname} PRIVATE ${FREEGLUT_SRC_DIR}/include) + target_link_directories(${testname} PRIVATE ${FREEGLUT_BIN_DIR}/lib) + target_link_libraries(${testname} PRIVATE OpenGL::GL) + target_link_libraries(${testname} INTERFACE FREEGLUT-PRJ) + # target_include_directories(${testname} PRIVATE ${FREEGLUT_INCLUDE_DIRS}) + # target_link_libraries(${testname} INTERFACE freeglut_static) + else() + target_include_directories(${testname} PRIVATE ${GLUT_INCLUDE_DIRS}) + target_link_libraries(${testname} PRIVATE OpenGL::GL ${GLUT_LIBRARIES}) + endif() + target_compile_definitions(${testname} PRIVATE USE_GLUT) + endif(OpenGL_FOUND) + + if(APPLE) + target_compile_options(${testname} PRIVATE -Wno-deprecated) + endif(APPLE) + + install(TARGETS ${testname} DESTINATION "bin/graphics") + +endforeach( testsourcefile ${APP_SOURCES} ) diff --git a/graphics/spirograph.cpp b/graphics/spirograph.cpp new file mode 100644 index 000000000..84c17c4db --- /dev/null +++ b/graphics/spirograph.cpp @@ -0,0 +1,284 @@ +/** + * @file + * @author [Krishna Vedala](https://github.com/kvedala) + * @brief Implementation of + * [Spirograph](https://en.wikipedia.org/wiki/Spirograph) + * + * @details + * Implementation of the program is based on the geometry shown in the figure + * below: + * + * Spirograph geometry from Wikipedia + */ +#ifdef USE_GLUT +#ifdef __APPLE__ +#include // include path on Macs is different +#else +#include +#endif // __APPLE__ +#endif +#define _USE_MATH_DEFINES /**< required for MSVC compiler */ +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _OPENMP +#include +#endif + +/** + * @namespace spirograph Functions related to spirograph.cpp + */ +namespace spirograph { +/** Generate spirograph curve into arrays `x` and `y` such that the i^th point + * in 2D is represented by `(x[i],y[i])`. The generating function is given by: + * \f{eqnarray*}{ + * x &=& R\left[ (1-k) \cos (t) + l\cdot k\cdot\cos \left(\frac{1-k}{k}t\right) + * \right]\\ + * y &=& R\left[ (1-k) \sin (t) - l\cdot k\cdot\sin \left(\frac{1-k}{k}t\right) + * \right] \f} + * where + * * \f$R\f$ is the scaling parameter that we will consider \f$=1\f$ + * * \f$l=\frac{\rho}{r}\f$ is the relative distance of marker from the centre + * of inner circle and \f$0\le l\le1\f$ + * * \f$\rho\f$ is physical distance of marker from centre of inner circle + * * \f$r\f$ is the radius of inner circle + * * \f$k=\frac{r}{R}\f$ is the ratio of radius of inner circle to outer circle + * and \f$0 +void spirograph(std::array, N> *points, double l, + double k, double rot) { + double dt = rot * 2.f * M_PI / N; + double R = 1.f; + const double k1 = 1.f - k; + int32_t step = 0; + +#ifdef _OPENMP +#pragma omp for +#endif + for (step = 0; step < N; step++) { + double t = dt * step; + double first = R * (k1 * std::cos(t) + l * k * std::cos(k1 * t / k)); + double second = R * (k1 * std::sin(t) - l * k * std::sin(k1 * t / k)); + points[0][step].first = first; + points[0][step].second = second; + } +} + +/** + * @brief Test function to save resulting points to a CSV file. + * + */ +void test() { + const size_t N = 500; + double l = 0.3, k = 0.75, rot = 10.; + std::stringstream fname; + fname << std::setw(3) << "spirograph_" << l << "_" << k << "_" << rot + << ".csv"; + std::ofstream fp(fname.str()); + if (!fp.is_open()) { + perror(fname.str().c_str()); + exit(EXIT_FAILURE); + } + + std::array, N> points; + + spirograph(&points, l, k, rot); + + for (size_t i = 0; i < N; i++) { + fp << points[i].first << "," << points[i].first; + if (i < N - 1) { + fp << '\n'; + } + } + + fp.close(); +} + +#ifdef USE_GLUT +static bool paused = 0; /**< flag to set pause/unpause animation */ +static const int animation_speed = 25; /**< animation delate in ms */ + +static const double step = 0.01; /**< animation step size */ +static double l_ratio = step * 10; /**< the l-ratio defined in docs */ +static double k_ratio = step; /**< the k-ratio defined in docs */ +static const double num_rot = 20.; /**< number of rotations to simulate */ + +/** A wrapper that is not available in all GLUT implementations. + */ +static inline void glutBitmapString(void *font, char *message) { + for (char *ch = message; *ch != '\0'; ch++) glutBitmapCharacter(font, *ch); +} + +/** + * @brief Function to graph (x,y) points on the OpenGL graphics window. + * + * @tparam N number of points = size of array + * @param [in] points Array of 2D points represented as std::pair + * @param l the relative distance of marker from the centre of + * inner circle and \f$0\le l\le1\f$ to display info + * @param k the ratio of radius of inner circle to outer circle and \f$0 +void display_graph(const std::array, N> &points, + double l, double k) { + glClearColor(1.0f, 1.0f, 1.0f, + 0.0f); // Set background color to white and opaque + glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer (background) + + glBegin(GL_LINES); // draw line segments + glColor3f(0.f, 0.f, 1.f); // blue + glPointSize(2.f); // point size in pixels + + for (size_t i = 1; i < N; i++) { + glVertex2f(points[i - 1].first, points[i - 1].second); // line from + glVertex2f(points[i].first, points[i].second); // line to + } + glEnd(); + + glColor3f(0.f, 0.f, 0.f); + std::stringstream buffer; + buffer << std::setw(3) << "l = " << l; + glRasterPos2f(-.85, .85); + glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, + const_cast(buffer.str().c_str())); + buffer.str(""); + buffer.clear(); + buffer << std::setw(3) << "k = " << k; + glRasterPos2f(-.85, .70); + glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, + const_cast(buffer.str().c_str())); + + glutSwapBuffers(); +} + +/** + * @brief Test function with animation + * + */ +void test2() { + const size_t N = 5000; // number of samples + + static bool direction1 = true; // increment if true, otherwise decrement + static bool direction2 = true; // increment if true, otherwise decrement + + std::array, N> points; + + spirograph(&points, l_ratio, k_ratio, num_rot); + display_graph(points, l_ratio, k_ratio); + + if (paused) + // if paused, do not update l_ratio and k_ratio + return; + + if (direction1) { // increment k_ratio + if (k_ratio >= (1.f - step)) // maximum limit + direction1 = false; // reverse direction of k_ratio + else + k_ratio += step; + } else { // decrement k_ratio + if (k_ratio <= step) { // minimum limit + direction1 = true; // reverse direction of k_ratio + + if (direction2) { // increment l_ratio + if (l_ratio >= (1.f - step)) // max limit of l_ratio + direction2 = false; // reverse direction of l_ratio + else + l_ratio += step; + } else { // decrement l_ratio + if (l_ratio <= step) // minimum limit of l_ratio + direction2 = true; // reverse direction of l_ratio + else + l_ratio -= step; + } + } else { // no min limit of k_ratio + k_ratio -= step; + } + } +} + +/** + * @brief GLUT timer callback function to add animation delay. + */ +void timer_cb(int t) { + glutTimerFunc(animation_speed, timer_cb, 0); + glutPostRedisplay(); +} + +/** + * @brief Keypress event call back function. + * + * @param key ID of the key pressed + * @param x mouse pointer position at event + * @param y mouse pointer position at event + */ +void keyboard_cb(unsigned char key, int x, int y) { + switch (key) { + case ' ': // spacebar toggles pause + paused = !paused; // toggle + break; + case GLUT_KEY_UP: + case '+': // up arrow key + k_ratio += step; + break; + case GLUT_KEY_DOWN: + case '_': // down arrow key + k_ratio -= step; + break; + case GLUT_KEY_RIGHT: + case '=': // left arrow key + l_ratio += step; + break; + case GLUT_KEY_LEFT: + case '-': // right arrow key + l_ratio -= step; + break; + case 0x1B: // escape key exits + exit(EXIT_SUCCESS); + default: + return; + } +} +#endif +} // namespace spirograph + +/** Main function */ +int main(int argc, char **argv) { + spirograph::test(); + +#ifdef USE_GLUT + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutCreateWindow("Spirograph"); + glutInitWindowSize(400, 400); + // glutIdleFunc(glutPostRedisplay); + glutTimerFunc(spirograph::animation_speed, spirograph::timer_cb, 0); + glutKeyboardFunc(spirograph::keyboard_cb); + glutDisplayFunc(spirograph::test2); + glutMainLoop(); +#endif + + return 0; +} From a90dcc5f66126049e91e0fa3835a55f6afb7d9fe Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:10:21 +0400 Subject: [PATCH 233/261] parameters --- data_structures/skip_list.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 80717050a..37839dfdb 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,8 +1,12 @@ /** + * @file skip_list.cpp + * @brief data struccture for fast searching and insertion (O(log(n))) + * @details * A skip list is a data structure that is used for storing a sorted list of items with a - * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items + * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ Code and PseudoCode. + * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * . */ #include From 2fecf67a365b9329036d623467dde998903ead98 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:11:20 +0400 Subject: [PATCH 234/261] parameters --- data_structures/skip_list.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 37839dfdb..6159506a0 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -6,6 +6,7 @@ * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * @author enqidu * . */ From b1b3b310a403398d279cbe6c619d109068fe11e1 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:22 +0400 Subject: [PATCH 235/261] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 6159506a0..515c6d138 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -5,7 +5,7 @@ * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * - * References used: GeeksForGeeks skip list code, https://iq.opengenus.org/skip-list/ PseudoCode and Code + * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code * @author enqidu * . */ From 5d225aba874d4b74021c1865f62148517a869f30 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:35 +0400 Subject: [PATCH 236/261] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 515c6d138..cefd23403 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -6,7 +6,7 @@ * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items * * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code - * @author enqidu + * @author [enqidu](https://github.com/enqidu) * . */ From af49a02ed85b944d88c13393c0ecd2cd30f5a0d7 Mon Sep 17 00:00:00 2001 From: enqidu Date: Fri, 10 Jul 2020 21:27:51 +0400 Subject: [PATCH 237/261] Update data_structures/skip_list.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index cefd23403..6e6d78e13 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,6 +1,6 @@ /** * @file skip_list.cpp - * @brief data struccture for fast searching and insertion (O(log(n))) + * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ time * @details * A skip list is a data structure that is used for storing a sorted list of items with a * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items From 5fcf15019e3873bf11386193748388e28c30b684 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 16:41:13 -0400 Subject: [PATCH 238/261] added clang-analyzer checks --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 02bb3916f..1412b563a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: '-*,google-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' +Checks: '-*,google-*,clang-analyzer-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false From 1fbd0d59ac276e8ca1e6c8f93995b3470c92cbb4 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Fri, 10 Jul 2020 21:38:04 +0000 Subject: [PATCH 239/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 0f7e9a053..bc007bc5f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -201,6 +201,7 @@ ## Search * [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/binary_search.cpp) * [Exponential Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/exponential_search.cpp) + * [Fibonacci Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/fibonacci_search.cpp) * [Hash Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/hash_search.cpp) * [Interpolation Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/interpolation_search.cpp) * [Interpolation Search2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/interpolation_search2.cpp) From bade26eccaf25c0c0b854c6b76e0588835ccc686 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 18:25:13 -0400 Subject: [PATCH 240/261] disable rand error --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 1412b563a..d7dc7996d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: '-*,google-*,clang-analyzer-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' +Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.rand,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false From 229334cce6028ad80e30f269ef2220f508f68f54 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 18:37:35 -0400 Subject: [PATCH 241/261] treat clang-tidy warnings as errors --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index d7dc7996d..610c6b28f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.rand,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' -WarningsAsErrors: '' +WarningsAsErrors: '*' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' From 389d50ea1421b6a15dd0b47476a2bd5dfb392425 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 19:05:42 -0400 Subject: [PATCH 242/261] disable all insecureAPI errors --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 610c6b28f..95431d6da 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.rand,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' +Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' WarningsAsErrors: '*' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false From 9a5a62cf127444de0372d275f7c8810501784b65 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 21:47:39 -0400 Subject: [PATCH 243/261] pass multiple files --- .github/workflows/awesome_workflow.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index 2e0792e17..97f705877 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -122,9 +122,11 @@ jobs: if not cpp_files: sys.exit(0) - for cpp_file in cpp_files: - subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], + subprocess.run(["clang-tidy-10", "--fix", "-p=build", *cpp_files, "--"], check=True, text=True, stderr=subprocess.STDOUT) + # for cpp_file in cpp_files: + # subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], + # check=True, text=True, stderr=subprocess.STDOUT) # print("g++:") # compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split()) From 523475b18367d573ae21bd8ae8b45ce8fb565e6b Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 21:58:22 -0400 Subject: [PATCH 244/261] mark all warnings as errors except those that are fixable by clang-tidy --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 95431d6da..272502837 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' -WarningsAsErrors: '*' +WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' From dc6f32297567a9888eeb8ed24d26ded0ce5d1f43 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 22:00:57 -0400 Subject: [PATCH 245/261] test commit --- numerical_methods/brent_method_extrema.cpp | 5 ++--- numerical_methods/durand_kerner_roots.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/numerical_methods/brent_method_extrema.cpp b/numerical_methods/brent_method_extrema.cpp index 654a69451..399be5b38 100644 --- a/numerical_methods/brent_method_extrema.cpp +++ b/numerical_methods/brent_method_extrema.cpp @@ -180,14 +180,13 @@ void test2() { } /** - * @brief Test function to find *maxima* for the function + * @brief Test function to find *minima* for the function * \f$f(x)= \cos x\f$ * in the interval \f$[0,12]\f$ * \n Expected result: \f$\pi\approx 3.14159265358979312\f$ */ void test3() { - // define the function to maximize as a lambda function - // since we are maximixing, we negated the function return value + // define the function to minimize as a lambda function std::function func = [](double x) { return std::cos(x); }; std::cout << "Test 3.... "; diff --git a/numerical_methods/durand_kerner_roots.cpp b/numerical_methods/durand_kerner_roots.cpp index 9bf0619b8..23419d1ed 100644 --- a/numerical_methods/durand_kerner_roots.cpp +++ b/numerical_methods/durand_kerner_roots.cpp @@ -212,7 +212,7 @@ void test1() { std::complex(0., -2.) // known expected roots }; - /* initialize root approximations with random values */ + /* Initialize root approximations with random values */ for (int n = 0; n < roots.size(); n++) { roots[n] = std::complex(std::rand() % 100, std::rand() % 100); roots[n] -= 50.f; From 2ca13dd45a5a99e6677149ad4020c03e0e63d646 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Fri, 10 Jul 2020 22:16:14 -0400 Subject: [PATCH 246/261] Revert "test commit" This reverts commit dc6f32297567a9888eeb8ed24d26ded0ce5d1f43. --- numerical_methods/brent_method_extrema.cpp | 5 +++-- numerical_methods/durand_kerner_roots.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/numerical_methods/brent_method_extrema.cpp b/numerical_methods/brent_method_extrema.cpp index 399be5b38..654a69451 100644 --- a/numerical_methods/brent_method_extrema.cpp +++ b/numerical_methods/brent_method_extrema.cpp @@ -180,13 +180,14 @@ void test2() { } /** - * @brief Test function to find *minima* for the function + * @brief Test function to find *maxima* for the function * \f$f(x)= \cos x\f$ * in the interval \f$[0,12]\f$ * \n Expected result: \f$\pi\approx 3.14159265358979312\f$ */ void test3() { - // define the function to minimize as a lambda function + // define the function to maximize as a lambda function + // since we are maximixing, we negated the function return value std::function func = [](double x) { return std::cos(x); }; std::cout << "Test 3.... "; diff --git a/numerical_methods/durand_kerner_roots.cpp b/numerical_methods/durand_kerner_roots.cpp index 23419d1ed..9bf0619b8 100644 --- a/numerical_methods/durand_kerner_roots.cpp +++ b/numerical_methods/durand_kerner_roots.cpp @@ -212,7 +212,7 @@ void test1() { std::complex(0., -2.) // known expected roots }; - /* Initialize root approximations with random values */ + /* initialize root approximations with random values */ for (int n = 0; n < roots.size(); n++) { roots[n] = std::complex(std::rand() % 100, std::rand() % 100); roots[n] -= 50.f; From d34bede6f4e2d94e5b7d2073d26cd11ac7f1352a Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 11 Jul 2020 09:11:31 -0400 Subject: [PATCH 247/261] disable error on cppcoreguidelines-owning-memory see https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-owning-memory.html for details --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 272502837..381337977 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' -WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*' +WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*,-cppcoreguidelines-owning-memory' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' From 4e12f03c6cbfa42d7f77d06edd08e39cfb901f4b Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 11 Jul 2020 15:09:00 -0400 Subject: [PATCH 248/261] disable move error + enforce c++11 for clang-tidy --- .clang-tidy | 2 +- .github/workflows/awesome_workflow.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 381337977..113d688e7 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ --- Checks: '-*,google-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-*,openmp-*,performance-*,portability-*,modernize-*,-modernize-use-trailing-*' -WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*,-cppcoreguidelines-owning-memory' +WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-performance-move-const-arg,-performance-noexcept-move-constructor,-cppcoreguidelines-init-variables,-cppcoreguidelines-pro-*,-cppcoreguidelines-owning-memory,-clang-analyzer-cplusplus.Move' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 80, AccessModifierOffset: -3, AlignConsecutiveMacros: true }' diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index 97f705877..4906a60d8 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -122,7 +122,7 @@ jobs: if not cpp_files: sys.exit(0) - subprocess.run(["clang-tidy-10", "--fix", "-p=build", *cpp_files, "--"], + subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-args=-std=c++11", *cpp_files, "--"], check=True, text=True, stderr=subprocess.STDOUT) # for cpp_file in cpp_files: # subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], From 1f32b4e412862d65c819efac7716625915160fc7 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 07:24:57 -0400 Subject: [PATCH 249/261] Fix command syntax (#949) --- .github/workflows/awesome_workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index 4906a60d8..9cff1c48d 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -122,7 +122,7 @@ jobs: if not cpp_files: sys.exit(0) - subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-args=-std=c++11", *cpp_files, "--"], + subprocess.run(["clang-tidy-10", "--fix", "-p=build", "--extra-arg=-std=c++11", *cpp_files, "--"], check=True, text=True, stderr=subprocess.STDOUT) # for cpp_file in cpp_files: # subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], From a707d710b58e5921d7f7131932f48f7e7860e7bd Mon Sep 17 00:00:00 2001 From: enqidu Date: Sun, 12 Jul 2020 19:24:46 +0400 Subject: [PATCH 250/261] update --- data_structures/skip_list.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 6159506a0..f0a17815a 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -26,12 +26,9 @@ using std::endl; * Node structure [Key][Node*, Node*...] */ struct Node { - int key; - // pointer of value - void* value; - // Forward Array points to the neighbour (right) - // nodes of the given one in all levels - vector forward; + int key; ///< key integer + void* value; ///< pointer of value + vector forward; ///< nodes of the given one in all levels // Constructor of the node Node(int key, int level, void* value); }; @@ -54,10 +51,8 @@ Node::Node(int key, int level, void* value) { * SkipList class implementation with basic methods */ class SkipList { - // Maximum level of the skiplist - int level; - // Pointer to the header node - Node *header; + int level; ///< Maximum level of the skiplist + Node *header; ///< Pointer to the header node public: SkipList(); int randomLevel(); From f970ce361cd1f17e289068a1e36c19eb362db1a0 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:00:27 -0400 Subject: [PATCH 251/261] tidied up code based on error reports by clang-tidy --- data_structures/skip_list.cpp | 422 +++++++++++++++++----------------- 1 file changed, 208 insertions(+), 214 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 373b93dad..d7982f866 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -1,241 +1,235 @@ /** * @file skip_list.cpp - * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ time + * @brief Data structure for fast searching and insertion in \f$O(\log n)\f$ + * time * @details - * A skip list is a data structure that is used for storing a sorted list of items with a - * help of hierarchy of linked lists that connect increasingly sparse subsequences of the items - * - * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code + * A skip list is a data structure that is used for storing a sorted list of + * items with a help of hierarchy of linked lists that connect increasingly + * sparse subsequences of the items + * + * References used: [GeeksForGeek](https://www.geeksforgeeks.org/skip-list/), + * [OpenGenus](https://iq.opengenus.org/skip-list) for PseudoCode and Code * @author [enqidu](https://github.com/enqidu) - * . -*/ + * @author [Krishna Vedala](https://github.com/kvedala) + */ -#include -#include +#include #include -#include +#include +#include +#include +#include -using std::vector; -using std::endl; - -#define MAX_LEVEL 2 ///< Maximum level of skip list -#define PROBABILITY 0.5 ///< Current probability for "coin toss" - +/** \namespace data_structure + * \brief Data-structure algorithms + */ +namespace data_structure { +constexpr int MAX_LEVEL = 2; ///< Maximum level of skip list +constexpr float PROBABILITY = 0.5; ///< Current probability for "coin toss" /** * Node structure [Key][Node*, Node*...] -*/ -struct Node { - int key; ///< key integer - void* value; ///< pointer of value - vector forward; ///< nodes of the given one in all levels - // Constructor of the node - Node(int key, int level, void* value); + */ +struct Node { + int key; ///< key integer + void* value; ///< pointer of value + std::vector> + forward; ///< nodes of the given one in all levels + + /** + * Creates node with provided key, level and value + * @param key is number that is used for comparision + * @param level is the maximum level node's going to added + */ + Node(int key, int level, void* value = nullptr) : key(key) { + // Initialization of forward vector + for (int i = 0; i < (level + 1); i++) { + forward.push_back(nullptr); + } + } }; -/** - * Creates node with provided key, level and value - * @param key is number that is used for comparision - * @param level is the maximum level node's going to added -*/ -Node::Node(int key, int level, void* value) { - this->key = key; - - //Initialization of forward vector - for (int i = 0; i < (level+1); i++){ - forward.push_back(nullptr); - } -} - /** * SkipList class implementation with basic methods -*/ -class SkipList { - int level; ///< Maximum level of the skiplist - Node *header; ///< Pointer to the header node -public: - SkipList(); - int randomLevel(); - void insertElement(int, void*); - void deleteElement(int); - void* searchElement(int); - void displayList(); - ~SkipList(); + */ +class SkipList { + int level; ///< Maximum level of the skiplist + std::shared_ptr header; ///< Pointer to the header node + + public: + /** + * Skip List constructor. Initializes header, start + * Node for searching in the list + */ + SkipList() { + level = 0; + // Header initialization + header = std::shared_ptr(new Node(-1, MAX_LEVEL)); + } + + /** + * Destructor for skiplist class + */ + ~SkipList() { + for (int i = 0; i <= level; i++) { + std::shared_ptr node = header->forward[i]; + std::shared_ptr temp; + while (node != nullptr) { + temp = node; + node = node->forward[i]; + temp.reset(); + } + } + header.reset(); + } + + /** + * Returns random level of the skip list. + * Every higher level is 2 times less likely. + * @return random level for skip list + */ + int randomLevel() { + int lvl = 0; + while (static_cast(std::rand() / RAND_MAX) < PROBABILITY && + lvl < MAX_LEVEL) + lvl++; + return lvl; + } + + /** + * Inserts elements with given key and value; + * It's level is computed by randomLevel() function. + * @param key is number that is used for comparision + * @param value pointer to a value, that can be any type + */ + void insertElement(int key, void* value) { + std::cout << "Inserting" << key << "..."; + std::shared_ptr x = header; + std::array, MAX_LEVEL + 1> update; + update.fill(nullptr); + + for (int i = level; i >= 0; i--) { + while (x->forward[i] != nullptr && x->forward[i]->key < key) + x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == nullptr || x->key != key); + if (doesnt_exist) { + int rlevel = randomLevel(); + + if (rlevel > level) { + for (int i = level + 1; i < rlevel + 1; i++) update[i] = header; + + // Update current level + level = rlevel; + } + + std::shared_ptr n = + std::shared_ptr(new Node(key, rlevel, value)); + for (int i = 0; i <= rlevel; i++) { + n->forward[i] = update[i]->forward[i]; + update[i]->forward[i] = n; + } + std::cout << "Inserted" << std::endl; + + } else { + std::cout << "Exists" << std::endl; + } + } + + /** + * Deletes an element by key and prints if has been removed successfully + * @param key is number that is used for comparision. + */ + void deleteElement(int key) { + std::shared_ptr x = header; + + std::array, MAX_LEVEL + 1> update; + update.fill(nullptr); + + for (int i = level; i >= 0; i--) { + while (x->forward[i] != nullptr && x->forward[i]->key < key) + x = x->forward[i]; + update[i] = x; + } + + x = x->forward[0]; + + bool doesnt_exist = (x == nullptr || x->key != key); + + if (!doesnt_exist) { + for (int i = 0; i <= level; i++) { + if (update[i]->forward[i] != x) + break; + update[i]->forward[i] = x->forward[i]; + } + /* Remove empty levels*/ + while (level > 0 && header->forward[level] == nullptr) level--; + std::cout << "Deleted" << std::endl; + } else { + std::cout << "Doesn't exist" << std::endl; + } + } + + /** + * Searching element in skip list structure + * @param key is number that is used for comparision + * @return pointer to the value of the node + */ + void* searchElement(int key) { + std::shared_ptr x = header; + std::cout << "Searching for " << key << std::endl; + + for (int i = level; i >= 0; i--) { + while (x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; + } + + x = x->forward[0]; + if (x && x->key == key) { + std::cout << "Found" << std::endl; + return x->value; + } else { + std::cout << "Not Found" << std::endl; + return nullptr; + } + } + + /* + * Display skip list level + */ + void displayList() { + std::cout << "Displaying list:\n" << std::endl; + for (int i = 0; i <= level; i++) { + std::shared_ptr node = header->forward[i]; + std::cout << "Level " << (i) << ": "; + while (node != nullptr) { + std::cout << node->key << " "; + node = node->forward[i]; + } + std::cout << std::endl; + } + } }; - -/** - * Skeep List constructor. Initializes header, start - * Node for searching in the list -*/ -SkipList::SkipList() { - level = 0; - // Header initialization - header = new Node(-1, MAX_LEVEL, nullptr); -} - -/** - * Destructor for skiplist class -*/ -SkipList::~SkipList(){ - for(int i=0; i <= level; i++) { - Node *node = header->forward[i]; - Node* temp; - while(node != nullptr) { - temp = node; - node = node->forward[i]; - delete temp; - } - } - delete header; -} - - -/** - * Returns random level of the skip list. - * Every higher level is 2 times less likely. - * @return lvl: random level for skip list; -*/ -int SkipList::randomLevel() { - int lvl = 0; - while(static_cast(std::rand())/RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; - return lvl; -} - - - -/** - * Inserts elements with given key and value; - * It's level is computed by randomLevel() function. - * @param key is number that is used for comparision - * @param value pointer to a value, that can be any type -*/ -void SkipList::insertElement(int key, void* value) { - std::cout << "Inserting" << key << "..."; - Node *x = header; - Node *update[MAX_LEVEL+1]; - memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); - - - for(int i = level; i >= 0; i--) { - while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; - update[i] = x; - } - - x = x->forward[0]; - - bool doesnt_exist = (x == nullptr || x->key != key); - if (doesnt_exist) { - int rlevel = randomLevel(); - - if(rlevel > level) { - for(int i=level+1;iforward[i] = update[i]->forward[i]; - update[i]->forward[i] = n; - } - std::cout << "Inserted" << endl; - - } else { - std::cout << "Exists" << endl; - } -} - -/** - * Deletes an element by key and prints if has been removed successfully - * @param key is number that is used for comparision. -*/ -void SkipList::deleteElement(int key) { - Node *x = header; - - Node *update[MAX_LEVEL+1]; - memset(update, 0, sizeof(Node*)*(MAX_LEVEL+1)); - - for(int i = level; i >= 0; i--) { - while(x->forward[i] != nullptr && x->forward[i]->key < key) x = x->forward[i]; - update[i] = x; - } - - x = x->forward[0]; - - bool doesnt_exist = (x == nullptr || x->key != key); - - if(!doesnt_exist) { - for(int i=0;i<=level;i++) { - if(update[i]->forward[i] != x) break; - update[i]->forward[i] = x->forward[i]; - } - /* Remove empty levels*/ - while(level>0 && header->forward[level] == 0) level--; - std::cout << "Deleted" << endl; - } else { - std::cout << "Doesn't exist" << endl; - } -} - - -/** - * Searching element in skip list structure - * @param key is number that is used for comparision - * @return pointer to the value of the node -*/ -void* SkipList::searchElement(int key) { - Node *x = header; - std::cout << "Searching for " + key << endl; - - for(int i = level; i >= 0; i--) { - while(x->forward[i] && x->forward[i]->key < key) x = x->forward[i]; - } - - x = x->forward[0]; - if(x && x->key == key){ - std::cout << "Found" << endl; - return x->value; - } else { - std::cout << "Not Found" << endl; - return nullptr; - } -} - -/* - * Display skip list level - */ -void SkipList::displayList() { - std::cout << "Displaying list:\n" << endl; - for(int i=0; i <= level; i++) { - Node *node = header->forward[i]; - std::cout << "Level " << (i) << ": "; - while(node != nullptr) { - std::cout << node->key << " "; - node = node->forward[i]; - } - std::cout << endl; - } -} - +} // namespace data_structure /** * Main function: * Creates and inserts random 2^[number of levels] * elements into the skip lists and than displays it - */ -int main() -{ + */ +int main() { std::srand(std::time(nullptr)); - SkipList lst; + data_structure::SkipList lst; - for (int j = 0; j < (1 << (MAX_LEVEL+1)); j++){ - int k = (std::rand()%( 1 << (MAX_LEVEL+2)) + 1); - lst.insertElement(k, &j); + for (int j = 0; j < (1 << (data_structure::MAX_LEVEL + 1)); j++) { + int k = (std::rand() % (1 << (data_structure::MAX_LEVEL + 2)) + 1); + lst.insertElement(k, &j); } lst.displayList(); - -} +} From c15c962f02d284f50b7a62b4af92fe2ef696a7a1 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:04:09 -0400 Subject: [PATCH 252/261] since we are using smart pointers, an explicit destructor is not required --- data_structures/skip_list.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index d7982f866..2cb78b8c8 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -67,22 +67,6 @@ class SkipList { header = std::shared_ptr(new Node(-1, MAX_LEVEL)); } - /** - * Destructor for skiplist class - */ - ~SkipList() { - for (int i = 0; i <= level; i++) { - std::shared_ptr node = header->forward[i]; - std::shared_ptr temp; - while (node != nullptr) { - temp = node; - node = node->forward[i]; - temp.reset(); - } - } - header.reset(); - } - /** * Returns random level of the skip list. * Every higher level is 2 times less likely. From 47f5ad9aaf0f497afec0bdcbb0138c344b9364e8 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sun, 12 Jul 2020 17:47:57 -0400 Subject: [PATCH 253/261] fix randomlevel float conversion --- data_structures/skip_list.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 2cb78b8c8..b1b24ea20 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -41,7 +41,7 @@ struct Node { * @param key is number that is used for comparision * @param level is the maximum level node's going to added */ - Node(int key, int level, void* value = nullptr) : key(key) { + Node(int key, int level, void* value = nullptr) : key(key), value(value) { // Initialization of forward vector for (int i = 0; i < (level + 1); i++) { forward.push_back(nullptr); @@ -74,7 +74,7 @@ class SkipList { */ int randomLevel() { int lvl = 0; - while (static_cast(std::rand() / RAND_MAX) < PROBABILITY && + while (static_cast(std::rand()) / RAND_MAX < PROBABILITY && lvl < MAX_LEVEL) lvl++; return lvl; @@ -185,7 +185,7 @@ class SkipList { * Display skip list level */ void displayList() { - std::cout << "Displaying list:\n" << std::endl; + std::cout << "Displaying list:\n"; for (int i = 0; i <= level; i++) { std::shared_ptr node = header->forward[i]; std::cout << "Level " << (i) << ": "; From 8ab9a2ae939b915f0da7d5daacb03eec2aed91c1 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 13 Jul 2020 07:52:38 -0400 Subject: [PATCH 254/261] [cpp fixes] tidied up code based on error reports by clang-tidy (#950) * tidied up code based on error reports by clang-tidy * added doc for activation function --- machine_learning/adaline_learning.cpp | 107 ++++++++------ machine_learning/kohonen_som_topology.cpp | 130 ++++++++++-------- machine_learning/kohonen_som_trace.cpp | 88 +++++++----- .../ordinary_least_squares_regressor.cpp | 48 ++++--- numerical_methods/newton_raphson_method.cpp | 11 +- numerical_methods/ode_forward_euler.cpp | 31 +++-- 6 files changed, 243 insertions(+), 172 deletions(-) diff --git a/machine_learning/adaline_learning.cpp b/machine_learning/adaline_learning.cpp index a8426ac4e..6da839a9d 100644 --- a/machine_learning/adaline_learning.cpp +++ b/machine_learning/adaline_learning.cpp @@ -26,6 +26,7 @@ * computed using stochastic gradient descent method. */ +#include #include #include #include @@ -35,7 +36,8 @@ #include #include -#define MAX_ITER 500 // INT_MAX ///< Maximum number of iterations to learn +/** Maximum number of iterations to learn */ +constexpr int MAX_ITER = 500; // INT_MAX /** \namespace machine_learning * \brief Machine learning algorithms @@ -50,8 +52,8 @@ class adaline { * \param[in] convergence accuracy (optional, * default=\f$1\times10^{-5}\f$) */ - adaline(int num_features, const double eta = 0.01f, - const double accuracy = 1e-5) + explicit adaline(int num_features, const double eta = 0.01f, + const double accuracy = 1e-5) : eta(eta), accuracy(accuracy) { if (eta <= 0) { std::cerr << "learning rate should be positive and nonzero" @@ -64,7 +66,7 @@ class adaline { 1); // additional weight is for the constant bias term // initialize with random weights in the range [-50, 49] - for (int i = 0; i < weights.size(); i++) weights[i] = 1.f; + for (double &weight : weights) weight = 1.f; // weights[i] = (static_cast(std::rand() % 100) - 50); } @@ -75,8 +77,9 @@ class adaline { out << "<"; for (int i = 0; i < ada.weights.size(); i++) { out << ada.weights[i]; - if (i < ada.weights.size() - 1) + if (i < ada.weights.size() - 1) { out << ", "; + } } out << ">"; return out; @@ -90,28 +93,33 @@ class adaline { * model prediction output */ int predict(const std::vector &x, double *out = nullptr) { - if (!check_size_match(x)) + if (!check_size_match(x)) { return 0; + } double y = weights.back(); // assign bias value // for (int i = 0; i < x.size(); i++) y += x[i] * weights[i]; y = std::inner_product(x.begin(), x.end(), weights.begin(), y); - if (out != nullptr) // if out variable is provided + if (out != nullptr) { // if out variable is provided *out = y; + } return activation(y); // quantizer: apply ADALINE threshold function } /** * Update the weights of the model using supervised learning for one - * feature vector \param[in] x feature vector \param[in] y known output - * value \returns correction factor + * feature vector + * \param[in] x feature vector + * \param[in] y known output value + * \returns correction factor */ double fit(const std::vector &x, const int &y) { - if (!check_size_match(x)) + if (!check_size_match(x)) { return 0; + } /* output of the model with current weights */ int p = predict(x); @@ -129,21 +137,23 @@ class adaline { /** * Update the weights of the model using supervised learning for an - * array of vectors. \param[in] X array of feature vector \param[in] y - * known output value for each feature vector + * array of vectors. + * \param[in] X array of feature vector + * \param[in] y known output value for each feature vector */ - template - void fit(std::vector const (&X)[N], const int *y) { + template + void fit(std::array, N> const &X, + std::array const &Y) { double avg_pred_error = 1.f; - int iter; + int iter = 0; for (iter = 0; (iter < MAX_ITER) && (avg_pred_error > accuracy); iter++) { avg_pred_error = 0.f; // perform fit for each sample for (int i = 0; i < N; i++) { - double err = fit(X[i], y[i]); + double err = fit(X[i], Y[i]); avg_pred_error += std::abs(err); } avg_pred_error /= N; @@ -154,15 +164,25 @@ class adaline { << "\tAvg error: " << avg_pred_error << std::endl; } - if (iter < MAX_ITER) - + if (iter < MAX_ITER) { std::cout << "Converged after " << iter << " iterations." << std::endl; - else + } else { std::cout << "Did not converge after " << iter << " iterations." << std::endl; + } } + /** Defines activation function as Heaviside's step function. + * \f[ + * f(x) = \begin{cases} + * -1 & \forall x \le 0\\ + * 1 & \forall x > 0 + * \end{cases} + * \f] + * @param x input value to apply activation on + * @return activation output + */ int activation(double x) { return x > 0 ? 1 : -1; } private: @@ -206,15 +226,19 @@ void test1(double eta = 0.01) { const int N = 10; // number of sample points - std::vector X[N] = {{0, 1}, {1, -2}, {2, 3}, {3, -1}, - {4, 1}, {6, -5}, {-7, -3}, {-8, 5}, - {-9, 2}, {-10, -15}}; - int y[] = {1, -1, 1, -1, -1, -1, 1, 1, 1, -1}; // corresponding y-values + std::array, N> X = { + std::vector({0, 1}), std::vector({1, -2}), + std::vector({2, 3}), std::vector({3, -1}), + std::vector({4, 1}), std::vector({6, -5}), + std::vector({-7, -3}), std::vector({-8, 5}), + std::vector({-9, 2}), std::vector({-10, -15})}; + std::array y = {1, -1, 1, -1, -1, + -1, 1, 1, 1, -1}; // corresponding y-values std::cout << "------- Test 1 -------" << std::endl; std::cout << "Model before fit: " << ada << std::endl; - ada.fit(X, y); + ada.fit(X, y); std::cout << "Model after fit: " << ada << std::endl; int predict = ada.predict({5, -3}); @@ -240,17 +264,17 @@ void test2(double eta = 0.01) { const int N = 50; // number of sample points - std::vector X[N]; - int Y[N]; // corresponding y-values + std::array, N> X; + std::array Y{}; // corresponding y-values // generate sample points in the interval // [-range2/100 , (range2-1)/100] int range = 500; // sample points full-range int range2 = range >> 1; // sample points half-range for (int i = 0; i < N; i++) { - double x0 = ((std::rand() % range) - range2) / 100.f; - double x1 = ((std::rand() % range) - range2) / 100.f; - X[i] = {x0, x1}; + double x0 = (static_cast(std::rand() % range) - range2) / 100.f; + double x1 = (static_cast(std::rand() % range) - range2) / 100.f; + X[i] = std::vector({x0, x1}); Y[i] = (x0 + 3. * x1) > -1 ? 1 : -1; } @@ -262,8 +286,8 @@ void test2(double eta = 0.01) { int N_test_cases = 5; for (int i = 0; i < N_test_cases; i++) { - double x0 = ((std::rand() % range) - range2) / 100.f; - double x1 = ((std::rand() % range) - range2) / 100.f; + double x0 = (static_cast(std::rand() % range) - range2) / 100.f; + double x1 = (static_cast(std::rand() % range) - range2) / 100.f; int predict = ada.predict({x0, x1}); @@ -291,18 +315,18 @@ void test3(double eta = 0.01) { const int N = 100; // number of sample points - std::vector X[N]; - int Y[N]; // corresponding y-values + std::array, N> X; + std::array Y{}; // corresponding y-values // generate sample points in the interval // [-range2/100 , (range2-1)/100] int range = 200; // sample points full-range int range2 = range >> 1; // sample points half-range for (int i = 0; i < N; i++) { - double x0 = ((std::rand() % range) - range2) / 100.f; - double x1 = ((std::rand() % range) - range2) / 100.f; - double x2 = ((std::rand() % range) - range2) / 100.f; - X[i] = {x0, x1, x2, x0 * x0, x1 * x1, x2 * x2}; + double x0 = (static_cast(std::rand() % range) - range2) / 100.f; + double x1 = (static_cast(std::rand() % range) - range2) / 100.f; + double x2 = (static_cast(std::rand() % range) - range2) / 100.f; + X[i] = std::vector({x0, x1, x2, x0 * x0, x1 * x1, x2 * x2}); Y[i] = ((x0 * x0) + (x1 * x1) + (x2 * x2)) <= 1.f ? 1 : -1; } @@ -314,9 +338,9 @@ void test3(double eta = 0.01) { int N_test_cases = 5; for (int i = 0; i < N_test_cases; i++) { - double x0 = ((std::rand() % range) - range2) / 100.f; - double x1 = ((std::rand() % range) - range2) / 100.f; - double x2 = ((std::rand() % range) - range2) / 100.f; + double x0 = (static_cast(std::rand() % range) - range2) / 100.f; + double x1 = (static_cast(std::rand() % range) - range2) / 100.f; + double x2 = (static_cast(std::rand() % range) - range2) / 100.f; int predict = ada.predict({x0, x1, x2, x0 * x0, x1 * x1, x2 * x2}); @@ -334,8 +358,9 @@ int main(int argc, char **argv) { std::srand(std::time(nullptr)); // initialize random number generator double eta = 0.1; // default value of eta - if (argc == 2) // read eta value from commandline argument if present + if (argc == 2) { // read eta value from commandline argument if present eta = strtof(argv[1], nullptr); + } test1(eta); diff --git a/machine_learning/kohonen_som_topology.cpp b/machine_learning/kohonen_som_topology.cpp index 016fe6d1e..cccc9faa3 100644 --- a/machine_learning/kohonen_som_topology.cpp +++ b/machine_learning/kohonen_som_topology.cpp @@ -25,8 +25,11 @@ */ #define _USE_MATH_DEFINES //< required for MS Visual C++ #include +#include +#include #include #include +#include #include #include #include @@ -68,7 +71,8 @@ int save_2d_data(const char *fname, fp.open(fname); if (!fp.is_open()) { // error with opening file to write - std::cerr << "Error opening file " << fname << "\n"; + std::cerr << "Error opening file " << fname << ": " + << std::strerror(errno) << "\n"; return -1; } @@ -76,12 +80,14 @@ int save_2d_data(const char *fname, for (int i = 0; i < num_points; i++) { // for each feature in the array for (int j = 0; j < num_features; j++) { - fp << X[i][j]; // print the feature value - if (j < num_features - 1) // if not the last feature - fp << ","; // suffix comma + fp << X[i][j]; // print the feature value + if (j < num_features - 1) { // if not the last feature + fp << ","; // suffix comma + } + } + if (i < num_points - 1) { // if not the last row + fp << "\n"; // start a new line } - if (i < num_points - 1) // if not the last row - fp << "\n"; // start a new line } fp.close(); @@ -99,12 +105,12 @@ int save_2d_data(const char *fname, void get_min_2d(const std::vector> &X, double *val, int *x_idx, int *y_idx) { val[0] = INFINITY; // initial min value - int N = X.size(); + size_t N = X.size(); for (int i = 0; i < N; i++) { // traverse each x-index auto result = std::min_element(std::begin(X[i]), std::end(X[i])); double d_min = *result; - int j = std::distance(std::begin(X[i]), result); + std::ptrdiff_t j = std::distance(std::begin(X[i]), result); if (d_min < val[0]) { // if a lower value is found // save the value and its index @@ -119,7 +125,8 @@ void get_min_2d(const std::vector> &X, double *val, * \brief Machine learning algorithms */ namespace machine_learning { -#define MIN_DISTANCE 1e-4 ///< Minimum average distance of image nodes +/** Minimum average distance of image nodes */ +constexpr double MIN_DISTANCE = 1e-4; /** * Create the distance matrix or @@ -136,9 +143,8 @@ int save_u_matrix(const char *fname, const std::vector>> &W) { std::ofstream fp(fname); if (!fp) { // error with fopen - char msg[120]; - std::snprintf(msg, sizeof(msg), "File error (%s): ", fname); - std::perror(msg); + std::cerr << "File error (" << fname << "): " << std::strerror(errno) + << std::endl; return -1; } @@ -153,7 +159,7 @@ int save_u_matrix(const char *fname, int to_x = std::min(W.size(), i + R + 1); int from_y = std::max(0, j - R); int to_y = std::min(W[0].size(), j + R + 1); - int l, m; + int l = 0, m = 0; #ifdef _OPENMP #pragma omp parallel for reduction(+ : distance) #endif @@ -172,8 +178,9 @@ int save_u_matrix(const char *fname, fp << ','; // suffix comma } } - if (i < W.size() - 1) // if not the last row - fp << '\n'; // start a new line + if (i < W.size() - 1) { // if not the last row + fp << '\n'; // start a new line + } } fp.close(); @@ -194,10 +201,11 @@ double update_weights(const std::valarray &X, std::vector>> *W, std::vector> *D, double alpha, int R) { - int x, y; + int x = 0, y = 0; int num_out_x = static_cast(W->size()); // output nodes - in X int num_out_y = static_cast(W[0][0].size()); // output nodes - in Y - int num_features = static_cast(W[0][0][0].size()); // features = in Z + // int num_features = static_cast(W[0][0][0].size()); // features = + // in Z double d_min = 0.f; #ifdef _OPENMP @@ -217,7 +225,7 @@ double update_weights(const std::valarray &X, // step 2: get closest node i.e., node with snallest Euclidian distance // to the current pattern - int d_min_x, d_min_y; + int d_min_x = 0, d_min_y = 0; get_min_2d(*D, &d_min, &d_min_x, &d_min_y); // step 3a: get the neighborhood range @@ -261,10 +269,10 @@ double update_weights(const std::valarray &X, void kohonen_som(const std::vector> &X, std::vector>> *W, double alpha_min) { - int num_samples = X.size(); // number of rows - int num_features = X[0].size(); // number of columns - int num_out = W->size(); // output matrix size - int R = num_out >> 2, iter = 0; + size_t num_samples = X.size(); // number of rows + // size_t num_features = X[0].size(); // number of columns + size_t num_out = W->size(); // output matrix size + size_t R = num_out >> 2, iter = 0; double alpha = 1.f; std::vector> D(num_out); @@ -283,15 +291,17 @@ void kohonen_som(const std::vector> &X, } // every 100th iteration, reduce the neighborhood range - if (iter % 300 == 0 && R > 1) + if (iter % 300 == 0 && R > 1) { R--; + } dmin /= num_samples; // termination condition variable -> % change in minimum distance dmin_ratio = (past_dmin - dmin) / past_dmin; - if (dmin_ratio < 0) + if (dmin_ratio < 0) { dmin_ratio = 1.f; + } past_dmin = dmin; std::cout << "iter: " << iter << "\t alpha: " << alpha << "\t R: " << R @@ -320,14 +330,14 @@ using machine_learning::save_u_matrix; void test_2d_classes(std::vector> *data) { const int N = data->size(); const double R = 0.3; // radius of cluster - int i; + int i = 0; const int num_classes = 4; - const double centres[][2] = { + std::array, num_classes> centres = { // centres of each class cluster - {.5, .5}, // centre of class 1 - {.5, -.5}, // centre of class 2 - {-.5, .5}, // centre of class 3 - {-.5, -.5} // centre of class 4 + std::array({.5, .5}), // centre of class 1 + std::array({.5, -.5}), // centre of class 2 + std::array({-.5, .5}), // centre of class 3 + std::array({-.5, -.5}) // centre of class 4 }; #ifdef _OPENMP @@ -357,15 +367,16 @@ void test_2d_classes(std::vector> *data) { * * `w12.csv`: trained SOM map */ void test1() { - int j, N = 300; + int j = 0, N = 300; int features = 2; int num_out = 30; std::vector> X(N); std::vector>> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::vector>(num_out); for (int k = 0; k < num_out; k++) { @@ -373,9 +384,10 @@ void test1() { #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][k][j] = _random(-10, 10); + } } } } @@ -397,16 +409,16 @@ void test1() { * \param[out] data matrix to store data in */ void test_3d_classes1(std::vector> *data) { - const int N = data->size(); + const size_t N = data->size(); const double R = 0.3; // radius of cluster - int i; + int i = 0; const int num_classes = 4; - const double centres[][3] = { + const std::array, num_classes> centres = { // centres of each class cluster - {.5, .5, .5}, // centre of class 1 - {.5, -.5, -.5}, // centre of class 2 - {-.5, .5, .5}, // centre of class 3 - {-.5, -.5 - .5} // centre of class 4 + std::array({.5, .5, .5}), // centre of class 1 + std::array({.5, -.5, -.5}), // centre of class 2 + std::array({-.5, .5, .5}), // centre of class 3 + std::array({-.5, -.5 - .5}) // centre of class 4 }; #ifdef _OPENMP @@ -437,15 +449,16 @@ void test_3d_classes1(std::vector> *data) { * * `w22.csv`: trained SOM map */ void test2() { - int j, N = 300; + int j = 0, N = 300; int features = 3; int num_out = 30; std::vector> X(N); std::vector>> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::vector>(num_out); for (int k = 0; k < num_out; k++) { @@ -453,9 +466,10 @@ void test2() { #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][k][j] = _random(-10, 10); + } } } } @@ -477,20 +491,20 @@ void test2() { * \param[out] data matrix to store data in */ void test_3d_classes2(std::vector> *data) { - const int N = data->size(); + const size_t N = data->size(); const double R = 0.2; // radius of cluster - int i; + int i = 0; const int num_classes = 8; - const double centres[][3] = { + const std::array, num_classes> centres = { // centres of each class cluster - {.5, .5, .5}, // centre of class 1 - {.5, .5, -.5}, // centre of class 2 - {.5, -.5, .5}, // centre of class 3 - {.5, -.5, -.5}, // centre of class 4 - {-.5, .5, .5}, // centre of class 5 - {-.5, .5, -.5}, // centre of class 6 - {-.5, -.5, .5}, // centre of class 7 - {-.5, -.5, -.5} // centre of class 8 + std::array({.5, .5, .5}), // centre of class 1 + std::array({.5, .5, -.5}), // centre of class 2 + std::array({.5, -.5, .5}), // centre of class 3 + std::array({.5, -.5, -.5}), // centre of class 4 + std::array({-.5, .5, .5}), // centre of class 5 + std::array({-.5, .5, -.5}), // centre of class 6 + std::array({-.5, -.5, .5}), // centre of class 7 + std::array({-.5, -.5, -.5}) // centre of class 8 }; #ifdef _OPENMP @@ -521,15 +535,16 @@ void test_3d_classes2(std::vector> *data) { * * `w32.csv`: trained SOM map */ void test3() { - int j, N = 500; + int j = 0, N = 500; int features = 3; int num_out = 30; std::vector> X(N); std::vector>> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::vector>(num_out); for (int k = 0; k < num_out; k++) { @@ -537,9 +552,10 @@ void test3() { #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][k][j] = _random(-10, 10); + } } } } diff --git a/machine_learning/kohonen_som_trace.cpp b/machine_learning/kohonen_som_trace.cpp index 273a2a57c..63a0c02c6 100644 --- a/machine_learning/kohonen_som_trace.cpp +++ b/machine_learning/kohonen_som_trace.cpp @@ -20,6 +20,7 @@ */ #define _USE_MATH_DEFINES // required for MS Visual C++ #include +#include #include #include #include @@ -71,12 +72,14 @@ int save_nd_data(const char *fname, for (int i = 0; i < num_points; i++) { // for each feature in the array for (int j = 0; j < num_features; j++) { - fp << X[i][j]; // print the feature value - if (j < num_features - 1) // if not the last feature - fp << ","; // suffix comma + fp << X[i][j]; // print the feature value + if (j < num_features - 1) { // if not the last feature + fp << ","; // suffix comma + } + } + if (i < num_points - 1) { // if not the last row + fp << "\n"; // start a new line } - if (i < num_points - 1) // if not the last row - fp << "\n"; // start a new line } fp.close(); @@ -100,9 +103,9 @@ namespace machine_learning { void update_weights(const std::valarray &x, std::vector> *W, std::valarray *D, double alpha, int R) { - int j, k; - int num_out = W->size(); // number of SOM output nodes - int num_features = x.size(); // number of data features + int j = 0, k = 0; + int num_out = W->size(); // number of SOM output nodes + // int num_features = x.size(); // number of data features #ifdef _OPENMP #pragma omp for @@ -117,7 +120,7 @@ void update_weights(const std::valarray &x, // step 2: get closest node i.e., node with snallest Euclidian distance to // the current pattern auto result = std::min_element(std::begin(*D), std::end(*D)); - double d_min = *result; + // double d_min = *result; int d_min_idx = std::distance(std::begin(*D), result); // step 3a: get the neighborhood range @@ -129,9 +132,10 @@ void update_weights(const std::valarray &x, #ifdef _OPENMP #pragma omp for #endif - for (j = from_node; j < to_node; j++) + for (j = from_node; j < to_node; j++) { // update weights of nodes in the neighborhood (*W)[j] += alpha * (x - (*W)[j]); + } } /** @@ -145,16 +149,16 @@ void update_weights(const std::valarray &x, void kohonen_som_tracer(const std::vector> &X, std::vector> *W, double alpha_min) { - int num_samples = X.size(); // number of rows - int num_features = X[0].size(); // number of columns - int num_out = W->size(); // number of rows + int num_samples = X.size(); // number of rows + // int num_features = X[0].size(); // number of columns + int num_out = W->size(); // number of rows int R = num_out >> 2, iter = 0; double alpha = 1.f; std::valarray D(num_out); // Loop alpha from 1 to slpha_min - for (; alpha > alpha_min; alpha -= 0.01, iter++) { + do { // Loop for each sample pattern in the data set for (int sample = 0; sample < num_samples; sample++) { // update weights for the current input pattern sample @@ -162,9 +166,13 @@ void kohonen_som_tracer(const std::vector> &X, } // every 10th iteration, reduce the neighborhood range - if (iter % 10 == 0 && R > 1) + if (iter % 10 == 0 && R > 1) { R--; - } + } + + alpha -= 0.01; + iter++; + } while (alpha > alpha_min); } } // namespace machine_learning @@ -190,7 +198,7 @@ void test_circle(std::vector> *data) { const double R = 0.75, dr = 0.3; double a_t = 0., b_t = 2.f * M_PI; // theta random between 0 and 2*pi double a_r = R - dr, b_r = R + dr; // radius random between R-dr and R+dr - int i; + int i = 0; #ifdef _OPENMP #pragma omp for @@ -223,24 +231,26 @@ void test_circle(std::vector> *data) { * output](https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/docs/images/machine_learning/kohonen/test1.svg) */ void test1() { - int j, N = 500; + int j = 0, N = 500; int features = 2; int num_out = 50; std::vector> X(N); std::vector> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::valarray(features); #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][j] = _random(-1, 1); + } } } @@ -267,7 +277,7 @@ void test1() { void test_lamniscate(std::vector> *data) { const int N = data->size(); const double dr = 0.2; - int i; + int i = 0; #ifdef _OPENMP #pragma omp for @@ -303,24 +313,26 @@ void test_lamniscate(std::vector> *data) { * output](https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/docs/images/machine_learning/kohonen/test2.svg) */ void test2() { - int j, N = 500; + int j = 0, N = 500; int features = 2; int num_out = 20; std::vector> X(N); std::vector> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::valarray(features); #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][j] = _random(-1, 1); + } } } @@ -347,18 +359,18 @@ void test2() { void test_3d_classes(std::vector> *data) { const int N = data->size(); const double R = 0.1; // radius of cluster - int i; + int i = 0; const int num_classes = 8; - const double centres[][3] = { + const std::array, num_classes> centres = { // centres of each class cluster - {.5, .5, .5}, // centre of class 0 - {.5, .5, -.5}, // centre of class 1 - {.5, -.5, .5}, // centre of class 2 - {.5, -.5, -.5}, // centre of class 3 - {-.5, .5, .5}, // centre of class 4 - {-.5, .5, -.5}, // centre of class 5 - {-.5, -.5, .5}, // centre of class 6 - {-.5, -.5, -.5} // centre of class 7 + std::array({.5, .5, .5}), // centre of class 0 + std::array({.5, .5, -.5}), // centre of class 1 + std::array({.5, -.5, .5}), // centre of class 2 + std::array({.5, -.5, -.5}), // centre of class 3 + std::array({-.5, .5, .5}), // centre of class 4 + std::array({-.5, .5, -.5}), // centre of class 5 + std::array({-.5, -.5, .5}), // centre of class 6 + std::array({-.5, -.5, -.5}) // centre of class 7 }; #ifdef _OPENMP @@ -400,24 +412,26 @@ void test_3d_classes(std::vector> *data) { * output](https://raw.githubusercontent.com/TheAlgorithms/C-Plus-Plus/docs/images/machine_learning/kohonen/test3.svg) */ void test3() { - int j, N = 200; + int j = 0, N = 200; int features = 3; int num_out = 20; std::vector> X(N); std::vector> W(num_out); for (int i = 0; i < std::max(num_out, N); i++) { // loop till max(N, num_out) - if (i < N) // only add new arrays if i < N + if (i < N) { // only add new arrays if i < N X[i] = std::valarray(features); + } if (i < num_out) { // only add new arrays if i < num_out W[i] = std::valarray(features); #ifdef _OPENMP #pragma omp for #endif - for (j = 0; j < features; j++) + for (j = 0; j < features; j++) { // preallocate with random initial weights W[i][j] = _random(-1, 1); + } } } diff --git a/machine_learning/ordinary_least_squares_regressor.cpp b/machine_learning/ordinary_least_squares_regressor.cpp index 896504e20..0c865761b 100644 --- a/machine_learning/ordinary_least_squares_regressor.cpp +++ b/machine_learning/ordinary_least_squares_regressor.cpp @@ -25,9 +25,10 @@ std::ostream &operator<<(std::ostream &out, const char separator = ' '; for (size_t row = 0; row < v.size(); row++) { - for (size_t col = 0; col < v[row].size(); col++) + for (size_t col = 0; col < v[row].size(); col++) { out << std::left << std::setw(width) << std::setfill(separator) << v[row][col]; + } out << std::endl; } @@ -42,9 +43,10 @@ std::ostream &operator<<(std::ostream &out, std::vector const &v) { const int width = 15; const char separator = ' '; - for (size_t row = 0; row < v.size(); row++) + for (size_t row = 0; row < v.size(); row++) { out << std::left << std::setw(width) << std::setfill(separator) << v[row]; + } return out; } @@ -57,9 +59,11 @@ template inline bool is_square(std::vector> const &A) { // Assuming A is square matrix size_t N = A.size(); - for (size_t i = 0; i < N; i++) - if (A[i].size() != N) + for (size_t i = 0; i < N; i++) { + if (A[i].size() != N) { return false; + } + } return true; } @@ -90,8 +94,9 @@ std::vector> operator*(std::vector> const &A, std::vector v(N_B); for (size_t col = 0; col < N_B; col++) { v[col] = static_cast(0); - for (size_t j = 0; j < B.size(); j++) + for (size_t j = 0; j < B.size(); j++) { v[col] += A[row][j] * B[j][col]; + } } result[row] = v; } @@ -154,8 +159,9 @@ std::vector operator*(std::vector const &A, float const scalar) { std::vector result(N_A); - for (size_t row = 0; row < N_A; row++) + for (size_t row = 0; row < N_A; row++) { result[row] = A[row] * static_cast(scalar); + } return result; } @@ -226,8 +232,9 @@ std::vector> get_inverse( for (size_t row = 0; row < N; row++) { // preallocatae a resultant identity matrix inverse[row] = std::vector(N); - for (size_t col = 0; col < N; col++) + for (size_t col = 0; col < N; col++) { inverse[row][col] = (row == col) ? 1.f : 0.f; + } } if (!is_square(A)) { @@ -239,8 +246,9 @@ std::vector> get_inverse( std::vector> temp(N); for (size_t row = 0; row < N; row++) { std::vector v(N); - for (size_t col = 0; col < N; col++) + for (size_t col = 0; col < N; col++) { v[col] = static_cast(A[row][col]); + } temp[row] = v; } @@ -267,13 +275,14 @@ std::vector> get_inverse( } // set diagonal to 1 - float divisor = static_cast(temp[row][row]); + auto divisor = static_cast(temp[row][row]); temp[row] = temp[row] / divisor; inverse[row] = inverse[row] / divisor; // Row transformations for (size_t row2 = 0; row2 < N; row2++) { - if (row2 == row) + if (row2 == row) { continue; + } float factor = temp[row2][row]; temp[row2] = temp[row2] - factor * temp[row]; inverse[row2] = inverse[row2] - factor * inverse[row]; @@ -313,9 +322,10 @@ std::vector fit_OLS_regressor(std::vector> const &X, std::vector const &Y) { // NxF std::vector> X2 = X; - for (size_t i = 0; i < X2.size(); i++) + for (size_t i = 0; i < X2.size(); i++) { // add Y-intercept -> Nx(F+1) X2[i].push_back(1); + } // (F+1)xN std::vector> Xt = get_transpose(X2); // (F+1)x(F+1) @@ -347,8 +357,9 @@ std::vector predict_OLS_regressor(std::vector> const &X, for (size_t rows = 0; rows < X.size(); rows++) { // -> start with constant term result[rows] = beta[X[0].size()]; - for (size_t cols = 0; cols < X[0].size(); cols++) + for (size_t cols = 0; cols < X[0].size(); cols++) { result[rows] += beta[cols] * X[rows][cols]; + } } // Nx1 return result; @@ -375,8 +386,9 @@ void ols_test() { // predicted regression outputs std::vector out1 = predict_OLS_regressor(test_data1, beta1); // compare predicted results are within +-0.01 limit of expected - for (size_t rows = 0; rows < out1.size(); rows++) + for (size_t rows = 0; rows < out1.size(); rows++) { assert(std::abs(out1[rows] - expected1[rows]) < 0.01); + } std::cout << "passed\n"; /* test function = x^3 + x^2 - 100 */ @@ -396,8 +408,9 @@ void ols_test() { // predicted regression outputs std::vector out2 = predict_OLS_regressor(test_data2, beta2); // compare predicted results are within +-0.01 limit of expected - for (size_t rows = 0; rows < out2.size(); rows++) + for (size_t rows = 0; rows < out2.size(); rows++) { assert(std::abs(out2[rows] - expected2[rows]) < 0.01); + } std::cout << "passed\n"; std::cout << std::endl; // ensure test results are displayed on screen @@ -410,7 +423,7 @@ void ols_test() { int main() { ols_test(); - size_t N, F; + size_t N = 0, F = 0; std::cout << "Enter number of features: "; // number of features = columns @@ -429,9 +442,10 @@ int main() { for (size_t rows = 0; rows < N; rows++) { std::vector v(F); std::cout << "Sample# " << rows + 1 << ": "; - for (size_t cols = 0; cols < F; cols++) + for (size_t cols = 0; cols < F; cols++) { // get the F features std::cin >> v[cols]; + } data[rows] = v; // get the corresponding output std::cin >> Y[rows]; @@ -440,7 +454,7 @@ int main() { std::vector beta = fit_OLS_regressor(data, Y); std::cout << std::endl << std::endl << "beta:" << beta << std::endl; - size_t T; + size_t T = 0; std::cout << "Enter number of test samples: "; // number of test sample inputs std::cin >> T; diff --git a/numerical_methods/newton_raphson_method.cpp b/numerical_methods/newton_raphson_method.cpp index 7597f1b8a..17147e0be 100644 --- a/numerical_methods/newton_raphson_method.cpp +++ b/numerical_methods/newton_raphson_method.cpp @@ -17,8 +17,8 @@ #include #include -#define EPSILON 1e-10 ///< system accuracy limit -#define MAX_ITERATIONS INT16_MAX ///< Maximum number of iterations to check +constexpr double EPSILON = 1e-10; ///< system accuracy limit +constexpr int16_t MAX_ITERATIONS = INT16_MAX; ///< Maximum number of iterations /** define \f$f(x)\f$ to find root for. * Currently defined as: @@ -44,8 +44,8 @@ static double eq_der(double i) { int main() { std::srand(std::time(nullptr)); // initialize randomizer - double z, c = std::rand() % 100, m, n; - int i; + double z = NAN, c = std::rand() % 100, m = NAN, n = NAN; + int i = 0; std::cout << "\nInitial approximation: " << c; @@ -57,8 +57,9 @@ int main() { z = c - (m / n); c = z; - if (std::abs(m) < EPSILON) // stoping criteria + if (std::abs(m) < EPSILON) { // stoping criteria break; + } } std::cout << "\n\nRoot: " << z << "\t\tSteps: " << i << std::endl; diff --git a/numerical_methods/ode_forward_euler.cpp b/numerical_methods/ode_forward_euler.cpp index a4455c57a..5e4dda31b 100644 --- a/numerical_methods/ode_forward_euler.cpp +++ b/numerical_methods/ode_forward_euler.cpp @@ -54,8 +54,8 @@ void problem(const double &x, std::valarray *y, std::valarray *dy) { const double omega = 1.F; // some const for the problem - dy[0][0] = y[0][1]; // x dot - dy[0][1] = -omega * omega * y[0][0]; // y dot + (*dy)[0] = (*y)[1]; // x dot // NOLINT + (*dy)[1] = -omega * omega * (*y)[0]; // y dot // NOLINT } /** @@ -83,10 +83,10 @@ void exact_solution(const double &x, std::valarray *y) { * @param[in,out] y take \f$y_n\f$ and compute \f$y_{n+1}\f$ * @param[in,out] dy compute \f$f\left(x_n,y_n\right)\f$ */ -void forward_euler_step(const double dx, const double &x, +void forward_euler_step(const double dx, const double x, std::valarray *y, std::valarray *dy) { problem(x, y, dy); - y[0] += dy[0] * dx; + *y += *dy * dx; } /** @@ -101,7 +101,7 @@ void forward_euler_step(const double dx, const double &x, */ double forward_euler(double dx, double x0, double x_max, std::valarray *y, bool save_to_file = false) { - std::valarray dy = y[0]; + std::valarray dy = *y; std::ofstream fp; if (save_to_file) { @@ -122,9 +122,9 @@ double forward_euler(double dx, double x0, double x_max, // write to file fp << x << ","; for (int i = 0; i < L - 1; i++) { - fp << y[0][i] << ","; + fp << y[0][i] << ","; // NOLINT } - fp << y[0][L - 1] << "\n"; + fp << y[0][L - 1] << "\n"; // NOLINT } forward_euler_step(dx, x, y, &dy); // perform integration @@ -133,8 +133,9 @@ double forward_euler(double dx, double x0, double x_max, /* end of integration */ std::clock_t t2 = std::clock(); - if (fp.is_open()) + if (fp.is_open()) { fp.close(); + } return static_cast(t2 - t1) / CLOCKS_PER_SEC; } @@ -153,7 +154,7 @@ void save_exact_solution(const double &X0, const double &X_MAX, const double &step_size, const std::valarray &Y0) { double x = X0; - std::valarray y = Y0; + std::valarray y(Y0); std::ofstream fp("exact.csv", std::ostream::out); if (!fp.is_open()) { @@ -166,9 +167,9 @@ void save_exact_solution(const double &X0, const double &X_MAX, do { fp << x << ","; for (int i = 0; i < y.size() - 1; i++) { - fp << y[i] << ","; + fp << y[i] << ","; // NOLINT } - fp << y[y.size() - 1] << "\n"; + fp << y[y.size() - 1] << "\n"; // NOLINT exact_solution(x, &y); @@ -186,10 +187,10 @@ void save_exact_solution(const double &X0, const double &X_MAX, * Main Function */ int main(int argc, char *argv[]) { - double X0 = 0.f; /* initial value of x0 */ - double X_MAX = 10.F; /* upper limit of integration */ - std::valarray Y0 = {1.f, 0.f}; /* initial value Y = y(x = x_0) */ - double step_size; + double X0 = 0.f; /* initial value of x0 */ + double X_MAX = 10.F; /* upper limit of integration */ + std::valarray Y0{1.f, 0.f}; /* initial value Y = y(x = x_0) */ + double step_size = NAN; if (argc == 1) { std::cout << "\nEnter the step size: "; From dc4a72c4181ee000cfdfede684c089adbc3a0774 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 13 Jul 2020 08:07:10 -0400 Subject: [PATCH 255/261] fix doc comment block --- data_structures/skip_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index b1b24ea20..39dda5ce6 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -181,7 +181,7 @@ class SkipList { } } - /* + /** * Display skip list level */ void displayList() { From eefe46688deb4197d14a7d123135037c7888a304 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Mon, 13 Jul 2020 08:07:44 -0400 Subject: [PATCH 256/261] main function must return --- data_structures/skip_list.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_structures/skip_list.cpp b/data_structures/skip_list.cpp index 39dda5ce6..cc679a31c 100644 --- a/data_structures/skip_list.cpp +++ b/data_structures/skip_list.cpp @@ -216,4 +216,6 @@ int main() { } lst.displayList(); + + return 0; } From 076d156302cc93101eb56958c1cbd9d5829a4251 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 13 Jul 2020 13:34:13 +0000 Subject: [PATCH 257/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index bc007bc5f..57a1b1c13 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -33,6 +33,7 @@ * [Queue Using Array2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_array2.cpp) * [Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linked_list.cpp) * [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linkedlist.cpp) + * [Skip List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/skip_list.cpp) * [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h) * [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_array.cpp) * [Stack Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_linked_list.cpp) From cac5fbe4aad104140f792a4a4ae72cc6084e2041 Mon Sep 17 00:00:00 2001 From: Deep Raval Date: Sat, 18 Jul 2020 03:57:40 +0530 Subject: [PATCH 258/261] feat: add Bogo Sort (#952) * Added Bogo Sort * Changed code according to guidelines * Added Comments and example * Improved code quality * Added range based loop and included cassert * Changed Vectors to Array * Added const to vector arg and now returning sorted array * Changed vector to array and changed description format * Added namespace sorting, Function description and tests * Update sorting/Bogo_Sort.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Replaced Shuffle with std::random_shuffle * Renamed filename to smallercase, Added shuffle for ref and updated bracket styling * Added missing ')' * updating DIRECTORY.md * Added spaces in single line comments * Added Spaces * Update sorting/bogo_sort.cpp Co-authored-by: David Leal Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal --- DIRECTORY.md | 1 + sorting/bogo_sort.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 sorting/bogo_sort.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 57a1b1c13..cd47fe955 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -215,6 +215,7 @@ ## Sorting * [Bead Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bead_sort.cpp) * [Bitonic Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bitonic_sort.cpp) + * [Bogo Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bogo_sort.cpp) * [Bubble Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bubble_sort.cpp) * [Bucket Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/bucket_sort.cpp) * [Cocktail Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/cocktail_selection_sort.cpp) diff --git a/sorting/bogo_sort.cpp b/sorting/bogo_sort.cpp new file mode 100644 index 000000000..a7dfd8496 --- /dev/null +++ b/sorting/bogo_sort.cpp @@ -0,0 +1,115 @@ +/** + * @file + * @brief Implementation of [Bogosort algorithm](https://en.wikipedia.org/wiki/Bogosort) + * + * @details + * In computer science, bogosort (also known as permutation sort, stupid sort, slowsort, + * shotgun sort, random sort, monkey sort, bobosort or shuffle sort) is a highly inefficient + * sorting algorithm based on the generate and test paradigm. Two versions of this algorithm + * exist: a deterministic version that enumerates all permutations until it hits a sorted one, + * and a randomized version that randomly permutes its input.Randomized version is implemented here. + * + * Algorithm - + * + * Shuffle the array untill array is sorted. + * + */ +#include +#include +#include +#include + + +/** + * @namespace sorting + * @brief Sorting algorithms + */ +namespace sorting { +/** + * Function to shuffle the elements of an array. (for reference) + * @tparam T typename of the array + * @tparam N length of array + * @param arr array to shuffle + * @returns new array with elements shuffled from a given array + */ +template +std::array shuffle (std::array arr) { + for (int i = 0; i < N; i++) { + // Swaps i'th index with random index (less than array size) + std::swap(arr[i], arr[std::rand() % N]); + } + return arr; +} +/** + * Implement randomized Bogosort algorithm and sort the elements of a given array. + * @tparam T typename of the array + * @tparam N length of array + * @param arr array to sort + * @returns new array with elements sorted from a given array + */ +template +std::array randomized_bogosort (std::array arr) { + // Untill array is not sorted + while (!std::is_sorted(arr.begin(), arr.end())) { + std::random_shuffle(arr.begin(), arr.end());// Shuffle the array + } + return arr; +} + +} // namespace sorting + +/** + * Function to display array on screen + * @tparam T typename of the array + * @tparam N length of array + * @param arr array to display + */ +template +void show_array (const std::array &arr) { + for (int x : arr) { + std::cout << x << ' '; + } + std::cout << '\n'; +} + +/** + * Function to test above algorithm + */ +void test() { + // Test 1 + std::array arr1; + for (int &x : arr1) { + x = std::rand() % 100; + } + std::cout << "Original Array : "; + show_array(arr1); + arr1 = sorting::randomized_bogosort(arr1); + std::cout << "Sorted Array : "; + show_array(arr1); + assert(std::is_sorted(arr1.begin(), arr1.end())); + // Test 2 + std::array arr2; + for (int &x : arr2) { + x = std::rand() % 100; + } + std::cout << "Original Array : "; + show_array(arr2); + arr2 = sorting::randomized_bogosort(arr2); + std::cout << "Sorted Array : "; + show_array(arr2); + assert(std::is_sorted(arr2.begin(), arr2.end())); +} + +/** Driver Code */ +int main() { + // Testing + test(); + // Example Usage + std::array arr = {3, 7, 10, 4, 1}; // Defining array which we want to sort + std::cout << "Original Array : "; + show_array(arr); + arr = sorting::randomized_bogosort(arr); // Callling bogo sort on it + std::cout << "Sorted Array : "; + show_array(arr); // Printing sorted array + return 0; +} From 426ecd03f1797d65134389c2acb44f07054ada83 Mon Sep 17 00:00:00 2001 From: shoniavika <48753228+shoniavika@users.noreply.github.com> Date: Sun, 19 Jul 2020 01:01:03 +0400 Subject: [PATCH 259/261] Added queue implementation using two stacks (#953) * added queue implementation using 2 stacks * added empty queue error handling * added empty queue error handling * updated format * deleted macro * added documentation * updated documentation, new func for testing * added copyright * documented queue class * made queue a generic one * handles lvalue error & added consts * added namespace --- data_structures/queue_using_two_stacks.cpp | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 data_structures/queue_using_two_stacks.cpp diff --git a/data_structures/queue_using_two_stacks.cpp b/data_structures/queue_using_two_stacks.cpp new file mode 100644 index 000000000..a09644686 --- /dev/null +++ b/data_structures/queue_using_two_stacks.cpp @@ -0,0 +1,144 @@ +/** + * @author [shoniavika](https://github.com/shoniavika) + * @file + * + * Implementation of a Queue using two Stacks. + */ + +#include +#include +#include + +namespace { +/** + * @brief Queue data structure. Stores elements in FIFO + * (first-in-first-out) manner. + * @tparam T datatype to store in the queue + */ +template +class MyQueue { + private: + std::stack s1, s2; + + public: + /** + * Constructor for queue. + */ + MyQueue() = default; + + /** + * Pushes x to the back of queue. + */ + void push(T x); + + /** + * Removes an element from the front of the queue. + */ + const T& pop(); + + /** + * Returns first element, without removing it. + */ + const T& peek() const; + + /** + * Returns whether the queue is empty. + */ + bool empty() const; +}; + +/** + * Appends element to the end of the queue + */ +template +void MyQueue::push(T x) { + while (!s2.empty()) { + s1.push(s2.top()); + s2.pop(); + } + s2.push(x); + while (!s1.empty()) { + s2.push(s1.top()); + s1.pop(); + } +} + +/** + * Removes element from the front of the queue + */ +template +const T& MyQueue::pop() { + const T& temp = MyQueue::peek(); + s2.pop(); + return temp; +} + +/** + * Returns element in the front. + * Does not remove it. + */ +template +const T& MyQueue::peek() const { + if (!empty()) { + return s2.top(); + } + std::cerr << "Queue is empty" << std::endl; + exit(0); +} + +/** + * Checks whether a queue is empty + */ +template +bool MyQueue::empty() const { + return s2.empty() && s1.empty(); +} +} // namespace + +/** + * Testing function + */ +void queue_test() { + MyQueue que; + std::cout << "Test #1\n"; + que.push(2); + que.push(5); + que.push(0); + assert(que.peek() == 2); + assert(que.pop() == 2); + assert(que.peek() == 5); + assert(que.pop() == 5); + assert(que.peek() == 0); + assert(que.pop() == 0); + assert(que.empty() == true); + std::cout << "PASSED\n"; + + std::cout << "Test #2\n"; + que.push(-1); + assert(que.empty() == false); + assert(que.peek() == -1); + assert(que.pop() == -1); + std::cout << "PASSED\n"; + + MyQueue que2; + std::cout << "Test #3\n"; + que2.push(2.31223); + que2.push(3.1415926); + que2.push(2.92); + + assert(que2.peek() == 2.31223); + assert(que2.pop() == 2.31223); + assert(que2.peek() == 3.1415926); + assert(que2.pop() == 3.1415926); + assert(que2.peek() == 2.92); + assert(que2.pop() == 2.92); + std::cout << "PASSED\n"; +} + +/** + * Main function, calls testing function + */ +int main() { + queue_test(); + return 0; +} From e07b0ce9f833f9c6c1d3201c2e97fe0b1de8f960 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sat, 18 Jul 2020 21:01:51 +0000 Subject: [PATCH 260/261] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index cd47fe955..0e699ba95 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -33,6 +33,7 @@ * [Queue Using Array2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_array2.cpp) * [Queue Using Linked List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linked_list.cpp) * [Queue Using Linkedlist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_linkedlist.cpp) + * [Queue Using Two Stacks](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/queue_using_two_stacks.cpp) * [Skip List](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/skip_list.cpp) * [Stack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack.h) * [Stack Using Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/data_structures/stack_using_array.cpp) From 67ec2aa982918a5c55ed88be2b889a6ed8088092 Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Sat, 18 Jul 2020 17:16:45 -0400 Subject: [PATCH 261/261] [feature] Gnome sort (#956) * implement gnome sort algorithm * change name as in contribute.md * remove std and fixed style on clang-format * Delete GnomeSort.cpp * style changes * add documentation * T template * style changes * style changes * repeated error fix * cout fixed * fix gnome_sort * add assertions' * added random values test * updating DIRECTORY.md * clang-tidy fixes for 97161cf894dc547ad4b97bd1bc3af4e068a2c137 * fix initial index value * add braces to one line for-loops * fix function documentation Co-authored-by: beqakd Co-authored-by: beqakd <39763019+beqakd@users.noreply.github.com> Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + sorting/gnome_sort.cpp | 133 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 sorting/gnome_sort.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 0e699ba95..439c601a9 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -223,6 +223,7 @@ * [Comb Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/comb_sort.cpp) * [Counting Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort.cpp) * [Counting Sort String](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort_string.cpp) + * [Gnome Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/gnome_sort.cpp) * [Heap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/heap_sort.cpp) * [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/insertion_sort.cpp) * [Library Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/library_sort.cpp) diff --git a/sorting/gnome_sort.cpp b/sorting/gnome_sort.cpp new file mode 100644 index 000000000..d56662479 --- /dev/null +++ b/sorting/gnome_sort.cpp @@ -0,0 +1,133 @@ +/** + * @file + * @brief Implementation of [gnome + * sort](https://en.wikipedia.org/wiki/Gnome_sort) algorithm. + * @author [beqakd](https://github.com/beqakd) + * @author [Krishna Vedala](https://github.com/kvedala) + * @details + * Gnome sort algorithm is not the best one but it is widely used. + * The algorithm iteratively checks the order of pairs in the array. If they are + * on right order it moves to the next successive pair, otherwise it swaps + * elements. This operation is repeated until no more swaps are made thus + * indicating the values to be in ascending order. + * + * The time Complexity of the algorithm is \f$O(n^2)\f$ and in some cases it + * can be \f$O(n)\f$. + */ + +#include // for std::swap +#include // for std::array +#include // for assertions +#include // for io operations + +/** + * @namespace sorting + * Sorting algorithms + */ +namespace sorting { +/** + * This implementation is for a C-style array input that gets modified in place. + * @param [in,out] arr our array of elements. + * @param size size of given array + */ +template +void gnomeSort(T *arr, int size) { + // few easy cases + if (size <= 1) { + return; + } + + int index = 0; // initialize some variables. + while (index < size) { + // check for swap + if ((index == 0) || (arr[index] >= arr[index - 1])) { + index++; + } else { + std::swap(arr[index], arr[index - 1]); // swap + index--; + } + } +} + +/** + * This implementation is for a C++-style array input. The function argument is + * a pass-by-value and hence a copy of the array gets created which is then + * modified by the function and returned. + * @tparam T type of data variables in the array + * @tparam size size of the array + * @param [in] arr our array of elements. + * @return array with elements sorted + */ +template +std::array gnomeSort(std::array arr) { + // few easy cases + if (size <= 1) { + return arr; + } + + int index = 0; // initialize loop index + while (index < size) { + // check for swap + if ((index == 0) || (arr[index] >= arr[index - 1])) { + index++; + } else { + std::swap(arr[index], arr[index - 1]); // swap + index--; + } + } + return arr; +} +} // namespace sorting + +/** + * Test function + */ +static void test() { + // Example 1. Creating array of int, + std::cout << "Test 1 - as a C-array..."; + const int size = 6; + std::array arr = {-22, 100, 150, 35, -10, 99}; + sorting::gnomeSort(arr.data(), + size); // pass array data as a C-style array pointer + assert(std::is_sorted(std::begin(arr), std::end(arr))); + std::cout << " Passed\n"; + for (int i = 0; i < size; i++) { + std::cout << arr[i] << ", "; + } + std::cout << std::endl; + + // Example 2. Creating array of doubles. + std::cout << "\nTest 2 - as a std::array..."; + std::array double_arr = {-100.2, 10.2, 20.0, 9.0, 7.5, 7.2}; + std::array sorted_arr = sorting::gnomeSort(double_arr); + assert(std::is_sorted(std::begin(sorted_arr), std::end(sorted_arr))); + std::cout << " Passed\n"; + for (int i = 0; i < size; i++) { + std::cout << double_arr[i] << ", "; + } + std::cout << std::endl; + + // Example 3. Creating random array of float. + std::cout << "\nTest 3 - 200 random numbers as a std::array..."; + const int size2 = 200; + std::array rand_arr{}; + + for (auto &a : rand_arr) { + // generate random numbers between -5.0 and 4.99 + a = float(std::rand() % 1000 - 500) / 100.f; + } + + std::array float_arr = sorting::gnomeSort(rand_arr); + assert(std::is_sorted(std::begin(float_arr), std::end(float_arr))); + std::cout << " Passed\n"; + // for (int i = 0; i < size; i++) std::cout << double_arr[i] << ", "; + std::cout << std::endl; +} + +/** + * Our main function with example of sort method. + */ +int main() { + test(); + return 0; +}