From e3f63822192c96322331eb2dd887c583ec292c40 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Sat, 17 Oct 2020 19:31:30 +0530 Subject: [PATCH 01/69] Create magic_number.cpp This Pull Request is for HacktoberFest 2020 --- math/magic_number.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 math/magic_number.cpp diff --git a/math/magic_number.cpp b/math/magic_number.cpp new file mode 100644 index 000000000..4a6edac4f --- /dev/null +++ b/math/magic_number.cpp @@ -0,0 +1,67 @@ +/** + * @file magic_number.cpp + * @brief A simple program to check if the given number is a magic number or not. + * A number is said to be a magic number, if the sum of its digits are calculated + * till a single digit recursively by adding the sum of the digits after every addition. + * If the single digit comes out to be 1,then the number is a magic number. + * @detail This is a shortcut method to verify Magic Number. + * On dividing the input by 9, if the remainder is 1 then the number is a magic number else not. + * The divisibility rule of 9 says that a number is divisible by 9 if the sum of its digits + * are also divisible by 9. Therefore, if a number is divisible by 9, then, recursively, + * all the digit sums are also divisible by 9. The final digit sum is always 9. + * An increase of 1 in the original number will increase the ultimate value by 1, + * making it 10 and the ultimate sum will be 1, thus verifying that it is a magic number. + * @author [Neha Hasija](https://github.com/neha-hasija17) + */ +#include +#include + +/** + * Function to check if the given number is magic number or not. + * @param n number to be checked. + * @return if number is a magic number, returns true, else false. + */ + +bool magic_number(int n) { + if (n <= 0) { + return false; + } + // result stores the modulus of @param n with 9 + int result=n%9; + //if result is 1 then the number is a magic number else not + if(result==1) return true; + else return false; +} + +/** Test function + * @returns void + */ +void tests() { + std::cout << "Test 1:\t n=60\n"; + assert(magic_number(60) == false); + std::cout << "passed\n"; + + std::cout << "Test 2:\t n=730\n"; + assert(magic_number(730) == true); + std::cout << "passed\n"; + + std::cout << "Test 3:\t n=0\n"; + assert(magic_number(0) == false); + std::cout << "passed\n"; + + std::cout << "Test 4:\t n=479001600\n"; + assert(magic_number(479001600) == false); + std::cout << "passed\n"; + + std::cout << "Test 5:\t n=-35\n"; + assert(magic_number(-35) == false); + std::cout << "passed\n"; +} + +/** Main function + * @returns 0 on exit + */ +int main() { + tests(); + return 0; +} From 3206660bcddb3276962b81ea3ffb269a3945f0a6 Mon Sep 17 00:00:00 2001 From: Pardeep Bhatt Date: Sun, 18 Oct 2020 23:53:56 +0530 Subject: [PATCH 02/69] added documentation in `dynamic_programming/0_1_knapsack.cpp` (#1207) * added docs * algorithm added in comments * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * updated template parameter * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: David Leal * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: David Leal * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: David Leal * Update dynamic_programming/0_1_knapsack.cpp Co-authored-by: David Leal Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Co-authored-by: David Leal --- dynamic_programming/0_1_knapsack.cpp | 177 ++++++++++++++++++--------- 1 file changed, 120 insertions(+), 57 deletions(-) diff --git a/dynamic_programming/0_1_knapsack.cpp b/dynamic_programming/0_1_knapsack.cpp index 7ea0c04c6..2e0a82e6a 100644 --- a/dynamic_programming/0_1_knapsack.cpp +++ b/dynamic_programming/0_1_knapsack.cpp @@ -1,66 +1,129 @@ -// 0-1 Knapsack problem - Dynamic programming -//#include +/** + * @file + * @brief Implementation of [0-1 Knapsack Problem] + * (https://en.wikipedia.org/wiki/Knapsack_problem) + * + * @details + * Given weights and values of n items, put these items in a knapsack of + * capacity `W` to get the maximum total value in the knapsack. In other words, + * given two integer arrays `val[0..n-1]` and `wt[0..n-1]` which represent + * values and weights associated with n items respectively. Also given an + * integer W which represents knapsack capacity, find out the maximum value + * subset of `val[]` such that sum of the weights of this subset is smaller than + * or equal to W. You cannot break an item, either pick the complete item or + * don’t pick it (0-1 property) + * + * ### Algorithm + * The idea is to consider all subsets of items and calculate the total weight + * and value of all subsets. Consider the only subsets whose total weight is + * smaller than `W`. From all such subsets, pick the maximum value subset. + * + * @author [Anmol](https://github.com/Anmol3299) + * @author [Pardeep](https://github.com/Pardeep009) + */ + +#include +#include #include -using namespace std; +#include -// void Print(int res[20][20], int i, int j, int capacity) -//{ -// if(i==0 || j==0) -// { -// return; -// } -// if(res[i-1][j]==res[i][j-1]) -// { -// if(i<=capacity) -// { -// cout<res[i][j-1]) -// { -// Print(res, i-1,j, capacity); -// } -// else if(res[i][j-1]>res[i-1][j]) -// { -// Print(res, i,j-1, capacity); -// } -//} +/** + * @namespace dynamic_programming + * @brief Dynamic Programming algorithms + */ +namespace dynamic_programming { +/** + * @namespace Knapsack + * @brief Implementation of 0-1 Knapsack problem + */ +namespace knapsack { +/** + * @brief Picking up all those items whose combined weight is below + * given capacity and calculating value of those picked items.Trying all + * possible combinations will yield the maximum knapsack value. + * @tparam n size of the weight and value array + * @param capacity capacity of the carrying bag + * @param weight array representing weight of items + * @param value array representing value of items + * @return maximum value obtainable with given capacity. + */ +template +int maxKnapsackValue(const int capacity, const std::array &weight, + const std::array &value) { + std::vector > maxValue(n + 1, + std::vector(capacity + 1, 0)); + // outer loop will select no of items allowed + // inner loop will select capcity of knapsack bag + int items = sizeof(weight) / sizeof(weight[0]); + for (size_t i = 0; i < items + 1; ++i) { + for (size_t j = 0; j < capacity + 1; ++j) { + if (i == 0 || j == 0) { + // if no of items is zero or capacity is zero, then maxValue + // will be zero + maxValue[i][j] = 0; + } else if (weight[i - 1] <= j) { + // if the ith item's weight(in actual array it will be at i-1) + // is less than or equal to the allowed weight i.e. j then we + // can pick that item for our knapsack. maxValue will be the + // obtained either by picking the current item or by not picking + // current item -int Knapsack(int capacity, int n, int weight[], int value[]) { - int res[20][20]; - for (int i = 0; i < n + 1; ++i) { - for (int j = 0; j < capacity + 1; ++j) { - if (i == 0 || j == 0) - res[i][j] = 0; - else if (weight[i - 1] <= j) - res[i][j] = max(value[i - 1] + res[i - 1][j - weight[i - 1]], - res[i - 1][j]); - else - res[i][j] = res[i - 1][j]; + // picking current item + int profit1 = value[i - 1] + maxValue[i - 1][j - weight[i - 1]]; + + // not picking current item + int profit2 = maxValue[i - 1][j]; + + maxValue[i][j] = std::max(profit1, profit2); + } else + // as weight of current item is greater than allowed weight, so + // maxProfit will be profit obtained by excluding current item. + maxValue[i][j] = maxValue[i - 1][j]; } } - // Print(res, n, capacity, capacity); - // cout<<"\n"; - return res[n][capacity]; + + // returning maximum value + return maxValue[items][capacity]; } +} // namespace knapsack +} // namespace dynamic_programming + +/** + * @brief Function to test above algorithm + * @returns void + */ +static void test() { + // Test 1 + const int n1 = 3; // number of items + std::array weight1 = {10, 20, 30}; // weight of each item + std::array value1 = {60, 100, 120}; // value of each item + const int capacity1 = 50; // capacity of carrying bag + const int max_value1 = dynamic_programming::knapsack::maxKnapsackValue( + capacity1, weight1, value1); + const int expected_max_value1 = 220; + assert(max_value1 == expected_max_value1); + std::cout << "Maximum Knapsack value with " << n1 << " items is " + << max_value1 << std::endl; + + // Test 2 + const int n2 = 4; // number of items + std::array weight2 = {24, 10, 10, 7}; // weight of each item + std::array value2 = {24, 18, 18, 10}; // value of each item + const int capacity2 = 25; // capacity of carrying bag + const int max_value2 = dynamic_programming::knapsack::maxKnapsackValue( + capacity2, weight2, value2); + const int expected_max_value2 = 36; + assert(max_value2 == expected_max_value2); + std::cout << "Maximum Knapsack value with " << n2 << " items is " + << max_value2 << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ int main() { - int n; - cout << "Enter number of items: "; - cin >> n; - int weight[n], value[n]; - cout << "Enter weights: "; - for (int i = 0; i < n; ++i) { - cin >> weight[i]; - } - cout << "Enter values: "; - for (int i = 0; i < n; ++i) { - cin >> value[i]; - } - int capacity; - cout << "Enter capacity: "; - cin >> capacity; - cout << Knapsack(capacity, n, weight, value); + // Testing + test(); return 0; } From 981f781d09dfcd9d67fedbf9cfa0fabf265f4539 Mon Sep 17 00:00:00 2001 From: Deep Raval Date: Mon, 19 Oct 2020 00:50:12 +0530 Subject: [PATCH 03/69] docs: Imporoved Documentation in neural_network.cpp (#1331) --- machine_learning/neural_network.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/machine_learning/neural_network.cpp b/machine_learning/neural_network.cpp index f77b732bb..978d658b4 100644 --- a/machine_learning/neural_network.cpp +++ b/machine_learning/neural_network.cpp @@ -826,7 +826,10 @@ static void test() { return; } -/** Driver Code */ +/** + * @brief Main function + * @returns 0 on exit + */ int main() { // Testing test(); From 579a290acb5cf0d0f346e5613d7ff296cbf068d0 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Mon, 19 Oct 2020 01:42:31 +0530 Subject: [PATCH 04/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 4a6edac4f..dd5cdc28f 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -36,7 +36,7 @@ bool magic_number(int n) { /** Test function * @returns void */ -void tests() { +static void tests() { std::cout << "Test 1:\t n=60\n"; assert(magic_number(60) == false); std::cout << "passed\n"; From f03910abdcc11826a3912bddf6bd2f96aeefd145 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Mon, 19 Oct 2020 01:42:38 +0530 Subject: [PATCH 05/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index dd5cdc28f..c6be43a9f 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -1,5 +1,5 @@ /** - * @file magic_number.cpp + * @file * @brief A simple program to check if the given number is a magic number or not. * A number is said to be a magic number, if the sum of its digits are calculated * till a single digit recursively by adding the sum of the digits after every addition. From db3f694490ca8db5e2ef71484dc06992ee3d4cf1 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Mon, 19 Oct 2020 01:42:47 +0530 Subject: [PATCH 06/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index c6be43a9f..de0a8fde3 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -4,7 +4,8 @@ * A number is said to be a magic number, if the sum of its digits are calculated * till a single digit recursively by adding the sum of the digits after every addition. * If the single digit comes out to be 1,then the number is a magic number. - * @detail This is a shortcut method to verify Magic Number. + * + * This is a shortcut method to verify Magic Number. * On dividing the input by 9, if the remainder is 1 then the number is a magic number else not. * The divisibility rule of 9 says that a number is divisible by 9 if the sum of its digits * are also divisible by 9. Therefore, if a number is divisible by 9, then, recursively, From 581715db048ae272ee048708dc018444dfaba7dc Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 18 Oct 2020 20:13:56 +0000 Subject: [PATCH 07/69] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 1aaf9dade..fa314c02e 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -141,6 +141,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) + * [Magic Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/magic_number.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) From a6b57f8896343da39fd312115b819c1c111076b6 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Sun, 18 Oct 2020 20:14:12 +0000 Subject: [PATCH 08/69] clang-format and clang-tidy fixes for db3f6944 --- math/magic_number.cpp | 35 ++++++------ sorting/pancake_sort.cpp | 112 ++++++++++++++++++++------------------- 2 files changed, 77 insertions(+), 70 deletions(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index de0a8fde3..c55225754 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -1,17 +1,19 @@ /** * @file - * @brief A simple program to check if the given number is a magic number or not. - * A number is said to be a magic number, if the sum of its digits are calculated - * till a single digit recursively by adding the sum of the digits after every addition. - * If the single digit comes out to be 1,then the number is a magic number. + * @brief A simple program to check if the given number is a magic number or + * not. A number is said to be a magic number, if the sum of its digits are + * calculated till a single digit recursively by adding the sum of the digits + * after every addition. If the single digit comes out to be 1,then the number + * is a magic number. * - * This is a shortcut method to verify Magic Number. - * On dividing the input by 9, if the remainder is 1 then the number is a magic number else not. - * The divisibility rule of 9 says that a number is divisible by 9 if the sum of its digits - * are also divisible by 9. Therefore, if a number is divisible by 9, then, recursively, - * all the digit sums are also divisible by 9. The final digit sum is always 9. - * An increase of 1 in the original number will increase the ultimate value by 1, - * making it 10 and the ultimate sum will be 1, thus verifying that it is a magic number. + * This is a shortcut method to verify Magic Number. + * On dividing the input by 9, if the remainder is 1 then the number is a magic + * number else not. The divisibility rule of 9 says that a number is divisible + * by 9 if the sum of its digits are also divisible by 9. Therefore, if a number + * is divisible by 9, then, recursively, all the digit sums are also divisible + * by 9. The final digit sum is always 9. An increase of 1 in the original + * number will increase the ultimate value by 1, making it 10 and the ultimate + * sum will be 1, thus verifying that it is a magic number. * @author [Neha Hasija](https://github.com/neha-hasija17) */ #include @@ -28,10 +30,13 @@ bool magic_number(int n) { return false; } // result stores the modulus of @param n with 9 - int result=n%9; - //if result is 1 then the number is a magic number else not - if(result==1) return true; - else return false; + int result = n % 9; + // if result is 1 then the number is a magic number else not + if (result == 1) { + return true; + } else { + return false; + } } /** Test function diff --git a/sorting/pancake_sort.cpp b/sorting/pancake_sort.cpp index accc5dbdb..e372e6097 100644 --- a/sorting/pancake_sort.cpp +++ b/sorting/pancake_sort.cpp @@ -1,26 +1,25 @@ /** * @file - * @brief pancake sort sorts a disordered stack of pancakes by flipping any number of pancakes using a spatula using minimum number of flips. + * @brief pancake sort sorts a disordered stack of pancakes by flipping any + * number of pancakes using a spatula using minimum number of flips. * * @details - * Unlike a traditional sorting algorithm, which attempts to sort with the fewest comparisons possible, - * the goal is to sort the sequence in as few reversals as possible. - * Overall time complexity of pancake sort is O(n^2) - * For example: example 1:- - * Disordered pancake sizes: {2,5,3,7,8} - * Sorted: {2,3,5,7,8} - * For example: example 2:- - * Disordered pancake sizes: {22,51,37,73,81} - * Sorted: {22,37,51,73,81} + * Unlike a traditional sorting algorithm, which attempts to sort with the + * fewest comparisons possible, the goal is to sort the sequence in as few + * reversals as possible. Overall time complexity of pancake sort is O(n^2) For + * example: example 1:- Disordered pancake sizes: {2,5,3,7,8} Sorted: + * {2,3,5,7,8} For example: example 2:- Disordered pancake sizes: + * {22,51,37,73,81} Sorted: {22,37,51,73,81} * @author [Divyansh Gupta](https://github.com/divyansh12323) * @see more on [Pancake sort](https://en.wikipedia.org/wiki/Pancake_sorting) - * @see related problem at [Leetcode](https://leetcode.com/problems/pancake-sorting/) -*/ + * @see related problem at + * [Leetcode](https://leetcode.com/problems/pancake-sorting/) + */ -#include // for io operations -#include // for std::vector #include // for std::is_sorted #include // for std::assert +#include // for io operations +#include // for std::vector /** * @namespace sorting @@ -29,52 +28,54 @@ namespace sorting { /** * @namespace pancake_sort - * @brief Functions for [Pancake sort](https://en.wikipedia.org/wiki/Pancake_sorting) algorithm + * @brief Functions for [Pancake + * sort](https://en.wikipedia.org/wiki/Pancake_sorting) algorithm */ namespace pancake_sort { - /** - * @brief This implementation is for reversing elements in a a C-style array . - * @param [start,end] arr our vector of elements. - * @param start starting index of array - * @param end ending index of array - * @returns void - */ - template - void reverse(std::vector &arr, int start, int end) { - T temp; //Temporary variable - while (start <= end) { - temp = arr[start]; - arr[start] = arr[end]; - arr[end] = temp; - start++; - end--; - } +/** + * @brief This implementation is for reversing elements in a a C-style array . + * @param [start,end] arr our vector of elements. + * @param start starting index of array + * @param end ending index of array + * @returns void + */ +template +void reverse(std::vector &arr, int start, int end) { + T temp; // Temporary variable + while (start <= end) { + temp = arr[start]; + arr[start] = arr[end]; + arr[end] = temp; + start++; + end--; } - /** - * @brief This implementation is for a C-style array input that gets modified in place. - * @param [start,end] arr our vector of elements. - * @param size size of given array - * @returns 0 on exit - */ - template - int pancakeSort(std::vector &arr, int size) { - for (int i = size; i > 1; --i) { - int max_index = 0, j; //intialize some variables. - T max_value = 0; - for (j = 0; j < i; j++) { - if (arr[j] >= max_value) { - max_value = arr[j]; - max_index = j; - } - } - if (max_index != i - 1) //check for reversing - { - reverse(arr, 0, max_index); - reverse(arr, 0, i - 1); +} +/** + * @brief This implementation is for a C-style array input that gets modified in + * place. + * @param [start,end] arr our vector of elements. + * @param size size of given array + * @returns 0 on exit + */ +template +int pancakeSort(std::vector &arr, int size) { + for (int i = size; i > 1; --i) { + int max_index = 0, j = 0; // intialize some variables. + T max_value = 0; + for (j = 0; j < i; j++) { + if (arr[j] >= max_value) { + max_value = arr[j]; + max_index = j; } } - return 0; + if (max_index != i - 1) // check for reversing + { + reverse(arr, 0, max_index); + reverse(arr, 0, i - 1); + } } + return 0; +} } // namespace pancake_sort } // namespace sorting @@ -98,7 +99,8 @@ static void test() { // example 2: vector of double const int size2 = 8; std::cout << "\nTest 2- as std::vector..."; - std::vector arr2 = {23.56, 10.62, 200.78, 111.484, 3.9, 1.2, 61.77, 79.6}; + std::vector arr2 = {23.56, 10.62, 200.78, 111.484, + 3.9, 1.2, 61.77, 79.6}; sorting::pancake_sort::pancakeSort(arr2, size2); assert(std::is_sorted(arr2.begin(), arr2.end())); std::cout << "Passed\n"; From fe538baac45fb1a9268c0fc71fa88472329dc783 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Mon, 19 Oct 2020 01:52:20 +0530 Subject: [PATCH 09/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index c55225754..1465aa11a 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -24,7 +24,6 @@ * @param n number to be checked. * @return if number is a magic number, returns true, else false. */ - bool magic_number(int n) { if (n <= 0) { return false; From 7c64998d425c155cc2dc703c51f9faf32d48562b Mon Sep 17 00:00:00 2001 From: David Leal Date: Mon, 19 Oct 2020 07:34:13 -0500 Subject: [PATCH 10/69] [fix/docs]: Improve CONTRIBUTING.md (#1300) * [fix/docs]: Improve CONTRIBUTING.md * fix: Add suggested changes --- CONTRIBUTING.md | 104 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd70b7b3e..e04cee749 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,17 @@ # CONTRIBUTION GUIDELINES ## Before contributing + Welcome to [TheAlgorithms/C-Plus-Plus](https://github.com/TheAlgorithms/C-Plus-Plus)! Before submitting pull requests, please make sure that you have **read the whole guidelines**. If you have any doubts about this contribution guide, please open [an issue](https://github.com/TheAlgorithms/C-Plus-Plus/issues/new/choose) and clearly state your concerns. ## Contributing + ### Contributor + We are very happy that you consider implementing algorithms and data structures for others! This repository is referred to and used by learners from around the globe. Being one of our contributors, you agree and confirm that: + - You did your own work. - - No plagiarism allowed. Any plagiarized work will not be merged. + - No plagiarism allowed. Any plagiarized work will not be merged. - Your work will be distributed under [MIT License](License) once your pull request has been merged. - You submitted work fulfils or mostly fulfils our styles and standards. @@ -20,36 +24,40 @@ We are very happy that you consider implementing algorithms and data structures ### Making Changes #### Code + - Please use the directory structure of the repository. -- File extension for code should be *.h *.cpp. +- File extension for code should be `*.hpp`, `*.h` or `*.cpp`. - Don't use **bits/stdc++.h** because this is quite Linux specific and slows down the compilation process. - Organize your code using **`struct`**, **`class`** and/or **`namespace`** keywords - If an implementation of the algorithm already exists, please refer to the [file-name section below](#new-file-name-guidelines). - You can suggest reasonable changes to existing algorithms. - 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. +- Our automated testing runs [__CMake__](https://cmake.org/) 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. +- Do not update [`README.md`](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/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`](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/README.md). +- The repository follows [Doxygen](https://www.doxygen.nl/manual/docblocks.html) standards and auto-generates the [repository 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. +- 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. Requires including the `cassert` header. + +#### Typical structure of a program -#### Typical structure of a program: ```cpp /** - * @file + * @file * @brief Add one line description here - * @details + * @details * This is a multi line * description containing links, references, * math equations, etc @@ -57,7 +65,8 @@ We are very happy that you consider implementing algorithms and data structures * @see related_file.cpp, another_file.cpp */ -#include +#include +#include /** * @namespace @@ -93,8 +102,12 @@ bool func(int param1, T param2) { return true; } +} // namespace name -/** Test function */ +/** + * @brief Test implementations + * @returns void + */ static void test() { /* desciptions of the following test */ assert(func(...) == ...); // this ensures that the algorithm works as expected @@ -102,7 +115,12 @@ static void test() { // can have multiple checks } -/** Main function */ +/** + * @brief Main function + * @param argc commandline argument count (ignored) + * @param argv commandline array of arguments (ignored) + * @returns 0 on exit + */ int main(int argc, char *argv[]) { test(); // execute the tests // code here @@ -111,76 +129,102 @@ int main(int argc, char *argv[]) { ``` #### New File Name guidelines + - Use lowercase words with ``"_"`` as separator - For instance -``` + +```markdown MyNewCppClass.CPP is incorrect my_new_cpp_class.cpp is correct format ``` + - It will be used to dynamically create a directory of files and implementation. - File name validation will run on docker to ensure the validity. - If an implementation of the algorithm already exists and your version is different from that implemented, please use incremental numeric digit as a suffix. For example, if `median_search.cpp` already exists in the `search` folder and you are contributing a new implementation, the filename should be `median_search2.cpp` and for a third implementation, `median_search3.cpp`. #### New Directory guidelines + - We recommend adding files to existing directories as much as possible. - Use lowercase words with ``"_"`` as separator ( no spaces or ```"-"``` allowed ) - For instance -``` + +```markdown SomeNew Fancy-Category is incorrect some_new_fancy_category is correct ``` + - Filepaths will be used to dynamically create a directory of our algorithms. - Filepath validation will run on GitHub Actions to ensure compliance. #### Commit Guidelines + - It is recommended to keep your changes grouped logically within individual commits. Maintainers find it easier to understand changes that are logically spilt across multiple commits. Try to modify just one or two files in the same directory. Pull requests that span multiple directories are often rejected. -``` + +```bash git add file_xyz.cpp git commit -m "your message" ``` + Examples of commit messages with semantic prefixes: -``` + +```markdown fix: xyz algorithm bug feat: add xyx algorithm, class xyz test: add test for xyz algorithm docs: add comments and explanation to xyz algorithm ``` + Common prefixes: + - fix: A bug fix - feat: A new feature - docs: Documentation changes - test: Correct existing tests or add new ones ### Pull Requests + - Checkout our [pull request template](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/.github/pull_request_template.md) #### Building Locally -Before submitting a pull request, build the code locally or using the convenient [![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) service. -``` + +Before submitting a pull request, + build the code locally or using the convenient [![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) service. + +```bash cmake -B build -S . ``` #### Static Code Analyzer + We use [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) as a static code analyzer with a configuration in [.clang-tidy](.clang-tidy). -``` + +```bash clang-tidy --fix --quiet -p build subfolder/file_to_check.cpp -- ``` #### Code Formatter + [__clang-format__](https://clang.llvm.org/docs/ClangFormat.html) is used for code forrmating. -* Installation (Only needs to be installed once.) - * Mac (using home-brew): `brew install clang-format` - * Mac (using macports): `sudo port install clang-10 +analyzer` - * Windows (MSYS2 64-bit): `pacman -S mingw-w64-x86_64-clang-tools-extra` - * Linux (Debian): `sudo apt-get install clang-format-10 clang-tidy-10` -* Running (all platforms): `clang-format -i -style="file" my_file.cpp` + +- Installation (only needs to be installed once.) + - Mac (using home-brew): `brew install clang-format` + - Mac (using macports): `sudo port install clang-10 +analyzer` + - Windows (MSYS2 64-bit): `pacman -S mingw-w64-x86_64-clang-tools-extra` + - Linux (Debian): `sudo apt-get install clang-format-10 clang-tidy-10` +- Running (all platforms): `clang-format -i -style="file" my_file.cpp` #### GitHub Actions -Enable GitHub Actions on your fork of the repository. -After enabling it will execute `clang-tidy` and `clang-format` after every a push (not a commit). -The result can create another commit if the actions made any changes on your behalf. -Hence, it is better to wait and check the results of GitHub Actions after every push. -Run `git pull` in your local clone if these actions made many changes in order to avoid merge conflicts. + +- Enable GitHub Actions on your fork of the repository. +After enabling it will execute `clang-tidy` and `clang-format` after every push (not a commit). + - Click on the tab "Actions", then click on the big green button to enable it. + +![GitHub Actions](https://user-images.githubusercontent.com/51391473/94609466-6e925100-0264-11eb-9d6f-3706190eab2b.png) + +- The result can create another commit if the actions made any changes on your behalf. +- Hence, it is better to wait and check the results of GitHub Actions after every push. +- Run `git pull` in your local clone if these actions made many changes in order to avoid merge conflicts. Most importantly, + - Happy coding! From 2854a463e198d1dc5810358f68c0536ee5f236c5 Mon Sep 17 00:00:00 2001 From: chestamittal Date: Tue, 20 Oct 2020 00:26:45 +0530 Subject: [PATCH 11/69] add lcm_sum.cpp --- math/lcm_sum.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 math/lcm_sum.cpp diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp new file mode 100644 index 000000000..2414f2d3a --- /dev/null +++ b/math/lcm_sum.cpp @@ -0,0 +1,90 @@ +/** + * @file + * @brief An algorithm to calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) + * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. + * The value of the sum is calculated by formula: + * ∑LCM(i, n) = ((∑(d * ETF(d)) + 1) * n) / 2 + * + * @author [Chesta Mittal](https://github.com/chestamittal) + */ + +#include // for std::cin std::cout +#include // for assert +#include // dor std::vector + +/** + * Function to compute sum of euler totients in sumOfEulerTotient vector + * @param num input number + * @returns int + */ +int lcmSum(int num) { + + int i=0, j=0; + int limit = 1000; + std::vector eulerTotient(limit); + std::vector sumOfEulerTotient(limit); + + // storing initial values in eulerTotient vector + for(i=1; i<=limit; i++) { + eulerTotient[i] = i; + } + + // applying totient sieve + for(i=2; i<=limit; i++) { + if(eulerTotient[i] == i) { + for(j=i; j<=limit; j+=i) { + eulerTotient[j] = eulerTotient[j]/i; + eulerTotient[j] = eulerTotient[j]*(i-1); + } + } + } + + // computing sum of euler totients + for(i=1; i<=limit; i++) { + for(j=i; j <=limit; j+=i) { + sumOfEulerTotient[j] += eulerTotient[i]*i; + } + } + + return ((sumOfEulerTotient[num] + 1 ) * num) / 2; +} + +/** + * Function for testing lcmSum function. + * test cases and assert statement. + * @returns `void` +*/ +static void test() { + int n = 2; + int test_1 = lcmSum(n); + assert(test_1 == 4); + std::cout << "Passed Test 1!" << std::endl; + + n = 5; + int test_2 = lcmSum(n); + assert(test_2 == 55); + std::cout << "Passed Test 2!" << std::endl; + + n = 10; + int test_3 = lcmSum(n); + assert(test_3 == 320); + std::cout << "Passed Test 3!" << std::endl; + + n = 11; + int test_4 = lcmSum(n); + assert(test_4 == 616); + std::cout << "Passed Test 4!" << std::endl; + + n = 15; + int test_5 = lcmSum(n); + assert(test_5 == 1110); + std::cout << "Passed Test 5!" << std::endl; +} + +/** +* main function +*/ +int main() { + test(); + return 0; +} From 2c13a7a3769aa76df0aff73ecea2da1b9e3f1e3a Mon Sep 17 00:00:00 2001 From: David Leal Date: Mon, 19 Oct 2020 14:59:20 -0500 Subject: [PATCH 12/69] [fix/docs]: Improve backtracking/n_queens_all_solution_optimised.cpp (#1041) * updating DIRECTORY.md * [fix/docs]: Improve backtracking/n_queens_... ...all_solution_optimised.cpp * fix: Remove function-like macros * clang-format and clang-tidy fixes for 689b788c Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- .../n_queens_all_solution_optimised.cpp | 122 +++++++++++++----- sorting/pancake_sort.cpp | 112 ++++++++-------- 2 files changed, 147 insertions(+), 87 deletions(-) diff --git a/backtracking/n_queens_all_solution_optimised.cpp b/backtracking/n_queens_all_solution_optimised.cpp index 4f42fba6f..bd150a98d 100644 --- a/backtracking/n_queens_all_solution_optimised.cpp +++ b/backtracking/n_queens_all_solution_optimised.cpp @@ -1,71 +1,129 @@ +/** + * @file + * @brief [N queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle) all + * optimized + * + * @author [Sombit Bose](https://github.com/deadshotsb) + * @author [David Leal](https://github.com/Panquesito7) + */ + +#include #include -#define n 4 -#define inc_loop(var, start, stop) for (int var = start; var <= stop; var++) -#define dec_loop(var, start, stop) for (int var = start; var >= stop; var--) -void PrintSol(int Board[n][n]) { - inc_loop(i, 0, n - 1) { - inc_loop(j, 0, n - 1) std::cout << Board[i][j] << " "; + +/** + * @namespace backtracking + * @brief Backtracking algorithms + */ +namespace backtracking { +/** + * @namespace n_queens_optimized + * @brief Functions for [Eight + * Queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle) puzzle optimized. + */ +namespace n_queens_optimized { +/** + * Utility function to print matrix + * @tparam n number of matrix size + * @param board matrix where numbers are saved + */ +template +void PrintSol(const std::array, n> &board) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + std::cout << board[i][j] << " "; + } std::cout << std::endl; } std::cout << std::endl; - if (n % 2 == 0 || (n % 2 == 1 && Board[n / 2 + 1][0] != 1)) { - inc_loop(i, 0, n - 1) { - dec_loop(j, n - 1, 0) std::cout << Board[i][j] << " "; + if (n % 2 == 0 || (n % 2 == 1 && board[n / 2 + 1][0] != 1)) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + std::cout << board[j][i] << " "; + } std::cout << std::endl; } std::cout << std::endl; } } -bool CanIMove(int Board[n][n], int row, int col) { +/** + * Check if a queen can be placed on matrix + * @tparam n number of matrix size + * @param board matrix where numbers are saved + * @param row current index in rows + * @param col current index in columns + * @returns `true` if queen can be placed on matrix + * @returns `false` if queen can't be placed on matrix + */ +template +bool CanIMove(const std::array, n> &board, int row, + int col) { /// check in the row - inc_loop(i, 0, col - 1) { - if (Board[row][i] == 1) + for (int i = 0; i <= col; i++) { + if (board[row][i] == 1) { return false; + } } /// check the first diagonal for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) { - if (Board[i][j] == 1) + if (board[i][j] == 1) { return false; + } } /// check the second diagonal for (int i = row, j = col; i <= n - 1 && j >= 0; i++, j--) { - if (Board[i][j] == 1) + if (board[i][j] == 1) { return false; + } } return true; } -void NQueenSol(int Board[n][n], int col) { +/** + * Solve n queens problem + * @tparam n number of matrix size + * @param board matrix where numbers are saved + * @param col current index in columns + */ +template +void NQueenSol(std::array, n> board, int col) { if (col >= n) { - PrintSol(Board); + PrintSol(board); return; } - inc_loop(i, 0, n - 1) { - if (CanIMove(Board, i, col)) { - Board[i][col] = 1; - NQueenSol(Board, col + 1); - Board[i][col] = 0; + for (int i = 0; i < n; i++) { + if (CanIMove(board, i, col)) { + board[i][col] = 1; + NQueenSol(board, col + 1); + board[i][col] = 0; } } } +} // namespace n_queens_optimized +} // namespace backtracking +/** + * @brief Main function + * @returns 0 on exit + */ int main() { - int Board[n][n] = {0}; + const int n = 4; + std::array, n> board{}; + if (n % 2 == 0) { - inc_loop(i, 0, n / 2 - 1) { - if (CanIMove(Board, i, 0)) { - Board[i][0] = 1; - NQueenSol(Board, 1); - Board[i][0] = 0; + for (int i = 0; i <= n / 2 - 1; i++) { // 😎 + if (backtracking::n_queens_optimized::CanIMove(board, i, 0)) { + board[i][0] = 1; + backtracking::n_queens_optimized::NQueenSol(board, 1); + board[i][0] = 0; } } } else { - inc_loop(i, 0, n / 2) { - if (CanIMove(Board, i, 0)) { - Board[i][0] = 1; - NQueenSol(Board, 1); - Board[i][0] = 0; + for (int i = 0; i <= n / 2; i++) { // 😏 + if (backtracking::n_queens_optimized::CanIMove(board, i, 0)) { + board[i][0] = 1; + backtracking::n_queens_optimized::NQueenSol(board, 1); + board[i][0] = 0; } } } diff --git a/sorting/pancake_sort.cpp b/sorting/pancake_sort.cpp index accc5dbdb..e372e6097 100644 --- a/sorting/pancake_sort.cpp +++ b/sorting/pancake_sort.cpp @@ -1,26 +1,25 @@ /** * @file - * @brief pancake sort sorts a disordered stack of pancakes by flipping any number of pancakes using a spatula using minimum number of flips. + * @brief pancake sort sorts a disordered stack of pancakes by flipping any + * number of pancakes using a spatula using minimum number of flips. * * @details - * Unlike a traditional sorting algorithm, which attempts to sort with the fewest comparisons possible, - * the goal is to sort the sequence in as few reversals as possible. - * Overall time complexity of pancake sort is O(n^2) - * For example: example 1:- - * Disordered pancake sizes: {2,5,3,7,8} - * Sorted: {2,3,5,7,8} - * For example: example 2:- - * Disordered pancake sizes: {22,51,37,73,81} - * Sorted: {22,37,51,73,81} + * Unlike a traditional sorting algorithm, which attempts to sort with the + * fewest comparisons possible, the goal is to sort the sequence in as few + * reversals as possible. Overall time complexity of pancake sort is O(n^2) For + * example: example 1:- Disordered pancake sizes: {2,5,3,7,8} Sorted: + * {2,3,5,7,8} For example: example 2:- Disordered pancake sizes: + * {22,51,37,73,81} Sorted: {22,37,51,73,81} * @author [Divyansh Gupta](https://github.com/divyansh12323) * @see more on [Pancake sort](https://en.wikipedia.org/wiki/Pancake_sorting) - * @see related problem at [Leetcode](https://leetcode.com/problems/pancake-sorting/) -*/ + * @see related problem at + * [Leetcode](https://leetcode.com/problems/pancake-sorting/) + */ -#include // for io operations -#include // for std::vector #include // for std::is_sorted #include // for std::assert +#include // for io operations +#include // for std::vector /** * @namespace sorting @@ -29,52 +28,54 @@ namespace sorting { /** * @namespace pancake_sort - * @brief Functions for [Pancake sort](https://en.wikipedia.org/wiki/Pancake_sorting) algorithm + * @brief Functions for [Pancake + * sort](https://en.wikipedia.org/wiki/Pancake_sorting) algorithm */ namespace pancake_sort { - /** - * @brief This implementation is for reversing elements in a a C-style array . - * @param [start,end] arr our vector of elements. - * @param start starting index of array - * @param end ending index of array - * @returns void - */ - template - void reverse(std::vector &arr, int start, int end) { - T temp; //Temporary variable - while (start <= end) { - temp = arr[start]; - arr[start] = arr[end]; - arr[end] = temp; - start++; - end--; - } +/** + * @brief This implementation is for reversing elements in a a C-style array . + * @param [start,end] arr our vector of elements. + * @param start starting index of array + * @param end ending index of array + * @returns void + */ +template +void reverse(std::vector &arr, int start, int end) { + T temp; // Temporary variable + while (start <= end) { + temp = arr[start]; + arr[start] = arr[end]; + arr[end] = temp; + start++; + end--; } - /** - * @brief This implementation is for a C-style array input that gets modified in place. - * @param [start,end] arr our vector of elements. - * @param size size of given array - * @returns 0 on exit - */ - template - int pancakeSort(std::vector &arr, int size) { - for (int i = size; i > 1; --i) { - int max_index = 0, j; //intialize some variables. - T max_value = 0; - for (j = 0; j < i; j++) { - if (arr[j] >= max_value) { - max_value = arr[j]; - max_index = j; - } - } - if (max_index != i - 1) //check for reversing - { - reverse(arr, 0, max_index); - reverse(arr, 0, i - 1); +} +/** + * @brief This implementation is for a C-style array input that gets modified in + * place. + * @param [start,end] arr our vector of elements. + * @param size size of given array + * @returns 0 on exit + */ +template +int pancakeSort(std::vector &arr, int size) { + for (int i = size; i > 1; --i) { + int max_index = 0, j = 0; // intialize some variables. + T max_value = 0; + for (j = 0; j < i; j++) { + if (arr[j] >= max_value) { + max_value = arr[j]; + max_index = j; } } - return 0; + if (max_index != i - 1) // check for reversing + { + reverse(arr, 0, max_index); + reverse(arr, 0, i - 1); + } } + return 0; +} } // namespace pancake_sort } // namespace sorting @@ -98,7 +99,8 @@ static void test() { // example 2: vector of double const int size2 = 8; std::cout << "\nTest 2- as std::vector..."; - std::vector arr2 = {23.56, 10.62, 200.78, 111.484, 3.9, 1.2, 61.77, 79.6}; + std::vector arr2 = {23.56, 10.62, 200.78, 111.484, + 3.9, 1.2, 61.77, 79.6}; sorting::pancake_sort::pancakeSort(arr2, size2); assert(std::is_sorted(arr2.begin(), arr2.end())); std::cout << "Passed\n"; From d817968d1ad2be6e61790d40328d34a91cf2707c Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 01:39:23 +0530 Subject: [PATCH 13/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 2414f2d3a..12141afd1 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -83,7 +83,7 @@ static void test() { /** * main function -*/ + */ int main() { test(); return 0; From 1e1d11d03e210e142d1f9f9862981d72d5393d76 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 01:39:35 +0530 Subject: [PATCH 14/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 12141afd1..6ccb5abfe 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -85,6 +85,6 @@ static void test() { * main function */ int main() { - test(); + test(); // execute the tests return 0; } From 261960cfb00407e98398b75d4e74bcd9f44aec7d Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 01:39:58 +0530 Subject: [PATCH 15/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 6ccb5abfe..91cd6832e 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -82,7 +82,8 @@ static void test() { } /** -* main function + * @brief Main function + * @returns 0 on exit */ int main() { test(); // execute the tests From 6dc89cc441542b131958fe8b6084fbd118043820 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 01:40:10 +0530 Subject: [PATCH 16/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 91cd6832e..dca5530d2 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -8,14 +8,14 @@ * @author [Chesta Mittal](https://github.com/chestamittal) */ -#include // for std::cin std::cout -#include // for assert -#include // dor std::vector +#include /// for std::cin and std::cout +#include /// for assert +#include /// for std::vector /** * Function to compute sum of euler totients in sumOfEulerTotient vector * @param num input number - * @returns int + * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num */ int lcmSum(int num) { From 7f97119f8ad2d290ff2cd1bfe4c589d80309fa0f Mon Sep 17 00:00:00 2001 From: Deep Raval Date: Tue, 20 Oct 2020 02:55:28 +0530 Subject: [PATCH 17/69] feat: Added Morse Code (#1322) * Added Morse Code * updating DIRECTORY.md * clang-format and clang-tidy fixes for 7ff8c973 * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal * Update ciphers/morse_code.cpp Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal --- DIRECTORY.md | 1 + ciphers/morse_code.cpp | 272 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 ciphers/morse_code.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 1aaf9dade..31a9f4141 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -13,6 +13,7 @@ ## Ciphers * [Caesar Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/caesar_cipher.cpp) * [Hill Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/hill_cipher.cpp) + * [Morse Code](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/morse_code.cpp) * [Vigenere Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/vigenere_cipher.cpp) * [Xor Cipher](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/ciphers/xor_cipher.cpp) diff --git a/ciphers/morse_code.cpp b/ciphers/morse_code.cpp new file mode 100644 index 000000000..f8ff51c5c --- /dev/null +++ b/ciphers/morse_code.cpp @@ -0,0 +1,272 @@ +/** + * @file + * @author [Deep Raval](https://github.com/imdeep2905) + * + * @brief Implementation of [Morse Code] + * (https://en.wikipedia.org/wiki/Morse_code). + * + * @details + * Morse code is a method used in telecommunication to encode text characters + * as standardized sequences of two different signal durations, called dots + * and dashes or dits and dahs. Morse code is named after Samuel Morse, an + * inventor of the telegraph. + */ +#include +#include +#include +#include + +/** \namespace ciphers + * \brief Algorithms for encryption and decryption + */ +namespace ciphers { +/** \namespace morse + * \brief Functions for [Morse Code] + * (https://en.wikipedia.org/wiki/Morse_code). + */ +namespace morse { +/** + * Get the morse representation for given character. + * @param c Character + * @returns morse representation string of character + */ +std::string char_to_morse(const char &c) { + // return corresponding morse code + switch (c) { + case 'a': + return ".-"; + case 'b': + return "-..."; + case 'c': + return "-.-."; + case 'd': + return "-.."; + case 'e': + return "."; + case 'f': + return "..-."; + case 'g': + return "--."; + case 'h': + return "...."; + case 'i': + return ".."; + case 'j': + return ".---"; + case 'k': + return "-.-"; + case 'l': + return ".-.."; + case 'm': + return "--"; + case 'n': + return "-."; + case 'o': + return "---"; + case 'p': + return ".--."; + case 'q': + return "--.-"; + case 'r': + return ".-."; + case 's': + return "..."; + case 't': + return "-"; + case 'u': + return "..-"; + case 'v': + return "...-"; + case 'w': + return ".--"; + case 'x': + return "-..-"; + case 'y': + return "-.--"; + case 'z': + return "--.."; + case '1': + return ".----"; + case '2': + return "..---"; + case '3': + return "...--"; + case '4': + return "....-"; + case '5': + return "....."; + case '6': + return "-...."; + case '7': + return "--..."; + case '8': + return "---.."; + case '9': + return "----."; + case '0': + return "-----"; + default: + std::cerr << "Found invalid character: " << c << ' ' << std::endl; + std::exit(0); + } +} +/** + * Get character from the morse representation. + * @param s Morse representation + * @returns corresponding character + */ +char morse_to_char(const std::string &s) { + // return corresponding character + if (s == ".-") { + return 'a'; + } else if (s == "-...") { + return 'b'; + } else if (s == "-.-.") { + return 'c'; + } else if (s == "-..") { + return 'd'; + } else if (s == ".") { + return 'e'; + } else if (s == "..-.") { + return 'f'; + } else if (s == "--.") { + return 'g'; + } else if (s == "....") { + return 'h'; + } else if (s == "..") { + return 'i'; + } else if (s == ".---") { + return 'j'; + } else if (s == "-.-") { + return 'k'; + } else if (s == ".-..") { + return 'l'; + } else if (s == "--") { + return 'm'; + } else if (s == "-.") { + return 'n'; + } else if (s == "---") { + return 'o'; + } else if (s == ".--.") { + return 'p'; + } else if (s == "--.-") { + return 'q'; + } else if (s == ".-.") { + return 'r'; + } else if (s == "...") { + return 's'; + } else if (s == "-") { + return 't'; + } else if (s == "..-") { + return 'u'; + } else if (s == "...-") { + return 'v'; + } else if (s == ".--") { + return 'w'; + } else if (s == "-..-") { + return 'x'; + } else if (s == "-.--") { + return 'y'; + } else if (s == "--..") { + return 'z'; + } else if (s == ".----") { + return '1'; + } else if (s == "..---") { + return '2'; + } else if (s == "...--") { + return '3'; + } else if (s == "....-") { + return '4'; + } else if (s == ".....") { + return '5'; + } else if (s == "-....") { + return '6'; + } else if (s == "--...") { + return '7'; + } else if (s == "---..") { + return '8'; + } else if (s == "----.") { + return '9'; + } else if (s == "-----") { + return '0'; + } else { + std::cerr << "Found invalid Morse code: " << s << ' ' << std::endl; + std::exit(0); + } +} +/** + * Encrypt given text using morse code. + * @param text text to be encrypted + * @returns new encrypted text + */ +std::string encrypt(const std::string &text) { + std::string encrypted_text = ""; // Empty string to store encrypted text + // Going through each character of text and converting it + // to morse representation + for (const char &c : text) { + encrypted_text += ciphers::morse::char_to_morse(c) + " "; + } + return encrypted_text; // Returning encrypted text +} +/** + * Decrypt given morse coded text. + * @param text text to be decrypted + * @returns new decrypted text + */ +std::string decrypt(const std::string &text) { + // Going through each character of text and converting it + // back to normal representation. + std::string decrypted_text = ""; // Empty string to store decrypted text + // Spliting string (with delimiter = " ") and storing it + // in vector + std::size_t pos_start = 0, pos_end = 0, delim_len = 1; + std::vector splits; + while ((pos_end = text.find(' ', pos_start)) != std::string::npos) { + std::string token = text.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + splits.push_back(token); + } + + // Traversing through each morse code string + for (const std::string &s : splits) { + // Add corresponding character + decrypted_text += ciphers::morse::morse_to_char(s); + } + + return decrypted_text; // Returning decrypted text +} +} // namespace morse +} // namespace ciphers + +/** + * @brief Function to test above algorithm + * @returns void + */ +static void test() { + // Test 1 + std::string text1 = "01234567890"; + std::string encrypted1 = ciphers::morse::encrypt(text1); + std::string decrypted1 = ciphers::morse::decrypt(encrypted1); + assert(text1 == decrypted1); + std::cout << "Original text : " << text1 << std::endl; + std::cout << "Encrypted text : " << encrypted1 << std::endl; + std::cout << "Decrypted text : " << decrypted1 << std::endl; + // Test 2 + std::string text2 = "abcdefghijklmnopqrstuvwxyz"; + std::string encrypted2 = ciphers::morse::encrypt(text2); + std::string decrypted2 = ciphers::morse::decrypt(encrypted2); + assert(text2 == decrypted2); + std::cout << "Original text : " << text2 << std::endl; + std::cout << "Encrypted text : " << encrypted2 << std::endl; + std::cout << "Decrypted text : " << decrypted2 << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + // Testing + test(); + return 0; +} From 403f44d9245e0587a9ed920f39209c85dd0bd930 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:02:11 +0530 Subject: [PATCH 18/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index dca5530d2..4a317784b 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -61,7 +61,7 @@ static void test() { std::cout << "Passed Test 1!" << std::endl; n = 5; - int test_2 = lcmSum(n); + int test_2 = math::lcmSum(n); assert(test_2 == 55); std::cout << "Passed Test 2!" << std::endl; From 2db80b5066c0eb862c34633e74d00b844b090c2e Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:02:21 +0530 Subject: [PATCH 19/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 4a317784b..950a90c17 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -76,7 +76,7 @@ static void test() { std::cout << "Passed Test 4!" << std::endl; n = 15; - int test_5 = lcmSum(n); + int test_5 = math::lcmSum(n); assert(test_5 == 1110); std::cout << "Passed Test 5!" << std::endl; } From 0978680880f928150f4a98a1913316518bdb3a2f Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:02:32 +0530 Subject: [PATCH 20/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 950a90c17..c27514d02 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -71,7 +71,7 @@ static void test() { std::cout << "Passed Test 3!" << std::endl; n = 11; - int test_4 = lcmSum(n); + int test_4 = math::lcmSum(n); assert(test_4 == 616); std::cout << "Passed Test 4!" << std::endl; From 1c7fe2628525aee717202b9c2c163ac49403260c Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:02:41 +0530 Subject: [PATCH 21/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index c27514d02..bababab9d 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -66,7 +66,7 @@ static void test() { std::cout << "Passed Test 2!" << std::endl; n = 10; - int test_3 = lcmSum(n); + int test_3 = math::lcmSum(n); assert(test_3 == 320); std::cout << "Passed Test 3!" << std::endl; From c89a0e3bf0ff8bcfcb5576bbdd145ed84a28bb0d Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:02:50 +0530 Subject: [PATCH 22/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index bababab9d..46452120e 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -56,7 +56,7 @@ int lcmSum(int num) { */ static void test() { int n = 2; - int test_1 = lcmSum(n); + int test_1 = math::lcmSum(n); assert(test_1 == 4); std::cout << "Passed Test 1!" << std::endl; From 1ebb42185f08c436214556d99a5398dadb638243 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:03:03 +0530 Subject: [PATCH 23/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 46452120e..b29de72de 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -48,6 +48,7 @@ int lcmSum(int num) { return ((sumOfEulerTotient[num] + 1 ) * num) / 2; } +} // namespace math /** * Function for testing lcmSum function. From c7912e7b1be729088aa11a5aeefb308b1db4a46b Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 03:03:12 +0530 Subject: [PATCH 24/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 57 ++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index b29de72de..ee341bd2b 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -13,41 +13,46 @@ #include /// for std::vector /** - * Function to compute sum of euler totients in sumOfEulerTotient vector - * @param num input number - * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num + * @namespace math + * @brief Mathematical algorithms */ -int lcmSum(int num) { +namespace math { + /** + * Function to compute sum of euler totients in sumOfEulerTotient vector + * @param num input number + * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num + */ + int lcmSum(int num) { - int i=0, j=0; - int limit = 1000; - std::vector eulerTotient(limit); - std::vector sumOfEulerTotient(limit); + int i=0, j=0; + int limit = 1000; + std::vector eulerTotient(limit); + std::vector sumOfEulerTotient(limit); - // storing initial values in eulerTotient vector - for(i=1; i<=limit; i++) { - eulerTotient[i] = i; - } + // storing initial values in eulerTotient vector + for(i=1; i<=limit; i++) { + eulerTotient[i] = i; + } - // applying totient sieve - for(i=2; i<=limit; i++) { - if(eulerTotient[i] == i) { - for(j=i; j<=limit; j+=i) { - eulerTotient[j] = eulerTotient[j]/i; - eulerTotient[j] = eulerTotient[j]*(i-1); + // applying totient sieve + for(i=2; i<=limit; i++) { + if(eulerTotient[i] == i) { + for(j=i; j<=limit; j+=i) { + eulerTotient[j] = eulerTotient[j]/i; + eulerTotient[j] = eulerTotient[j]*(i-1); + } } } - } - // computing sum of euler totients - for(i=1; i<=limit; i++) { - for(j=i; j <=limit; j+=i) { - sumOfEulerTotient[j] += eulerTotient[i]*i; + // computing sum of euler totients + for(i=1; i<=limit; i++) { + for(j=i; j <=limit; j+=i) { + sumOfEulerTotient[j] += eulerTotient[i]*i; + } } + + return ((sumOfEulerTotient[num] + 1 ) * num) / 2; } - - return ((sumOfEulerTotient[num] + 1 ) * num) / 2; -} } // namespace math /** From ed033c38b39296a1b4e4136e994d6ce98afc4f1e Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Mon, 19 Oct 2020 21:39:00 +0000 Subject: [PATCH 25/69] updating DIRECTORY.md --- DIRECTORY.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 1aaf9dade..4765d74c3 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -140,6 +140,7 @@ * [Gcd Recursive Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_recursive_euclidean.cpp) * [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) + * [Lcm Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/lcm_sum.cpp) * [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) From 234a29939a8fb0ed47b34ff4076ebf5be8764bac Mon Sep 17 00:00:00 2001 From: x0rld <45242856+x0rld@users.noreply.github.com> Date: Mon, 19 Oct 2020 23:40:03 +0200 Subject: [PATCH 26/69] fix: remove using namespace std (#1264) Remove `using namespace std;` in greedy_algorithms/kruskals_minimum_spanning_tree.cpp * remove using namespace std * change static C array to vector * change vector to array and remove global variable --- .../kruskals_minimum_spanning_tree.cpp | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/greedy_algorithms/kruskals_minimum_spanning_tree.cpp b/greedy_algorithms/kruskals_minimum_spanning_tree.cpp index 9f35e86ac..42c044241 100644 --- a/greedy_algorithms/kruskals_minimum_spanning_tree.cpp +++ b/greedy_algorithms/kruskals_minimum_spanning_tree.cpp @@ -1,31 +1,30 @@ #include -using namespace std; +#include -#define V 6 -#define INFINITY 99999 - -int graph[V][V] = {{0, 4, 1, 4, INFINITY, INFINITY}, - {4, 0, 3, 8, 3, INFINITY}, - {1, 3, 0, INFINITY, 1, INFINITY}, - {4, 8, INFINITY, 0, 5, 7}, - {INFINITY, 3, 1, 5, 0, INFINITY}, - {INFINITY, INFINITY, INFINITY, 7, INFINITY, 0}}; - -void findMinimumEdge() { - for (int i = 0; i < V; i++) { +void findMinimumEdge(int INFINITY, std::array< std::array< int ,6 >,6 > graph) { + for (int i = 0; i < graph.size(); i++) { int min = INFINITY; int minIndex = 0; - for (int j = 0; j < V; j++) { + for (int j = 0; j < graph.size(); j++) { if (graph[i][j] != 0 && graph[i][j] < min) { min = graph[i][j]; minIndex = j; } } - cout << i << " - " << minIndex << "\t" << graph[i][minIndex] << "\n"; + std::cout << i << " - " << minIndex << "\t" << graph[i][minIndex] << std::endl; } } int main() { - findMinimumEdge(); + constexpr int INFINITY = 99999; + std::array< std::array< int ,6 >,6 >graph + {0, 4, 1, 4, INFINITY, INFINITY, + 4, 0, 3, 8, 3, INFINITY, + 1, 3, 0, INFINITY, 1, INFINITY, + 4, 8, INFINITY, 0, 5, 7, + INFINITY, 3, 1, 5, 0, INFINITY, + INFINITY, INFINITY, INFINITY, 7, INFINITY, 0}; + + findMinimumEdge(INFINITY,graph); return 0; } From e466714e27f5c5e2e4482465216ce96b1e1c4a75 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 14:19:15 +0530 Subject: [PATCH 27/69] Update math/lcm_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/lcm_sum.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index ee341bd2b..d64bcd668 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -1,6 +1,7 @@ /** * @file - * @brief An algorithm to calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) + * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ + * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. * The value of the sum is calculated by formula: * ∑LCM(i, n) = ((∑(d * ETF(d)) + 1) * n) / 2 From b1e2d1ed8e10bf51241a65b64ef9d98abad5271b Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 20 Oct 2020 14:19:29 +0530 Subject: [PATCH 28/69] Update math/lcm_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/lcm_sum.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index d64bcd668..d9c61fb95 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -4,7 +4,9 @@ * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. * The value of the sum is calculated by formula: - * ∑LCM(i, n) = ((∑(d * ETF(d)) + 1) * n) / 2 + * \f[ + * \sum\mathrm{LCM}(i, n) = \frac{1}{2} \left[\left(\sum (d * \mathrm{ETF}(d)) + 1\right) * n\right] + * \f] * * @author [Chesta Mittal](https://github.com/chestamittal) */ @@ -26,19 +28,18 @@ namespace math { int lcmSum(int num) { int i=0, j=0; - int limit = 1000; - std::vector eulerTotient(limit); - std::vector sumOfEulerTotient(limit); + std::vector eulerTotient(num+1); + std::vector sumOfEulerTotient(num+1); // storing initial values in eulerTotient vector - for(i=1; i<=limit; i++) { + for(i=1; i<=num; i++) { eulerTotient[i] = i; } // applying totient sieve - for(i=2; i<=limit; i++) { + for(i=2; i<=num; i++) { if(eulerTotient[i] == i) { - for(j=i; j<=limit; j+=i) { + for(j=i; j<=num; j+=i) { eulerTotient[j] = eulerTotient[j]/i; eulerTotient[j] = eulerTotient[j]*(i-1); } @@ -46,8 +47,8 @@ namespace math { } // computing sum of euler totients - for(i=1; i<=limit; i++) { - for(j=i; j <=limit; j+=i) { + for(i=1; i<=num; i++) { + for(j=i; j <=num; j+=i) { sumOfEulerTotient[j] += eulerTotient[i]*i; } } From b5cbf0e84abc6cda72357be6853ea44dceed7559 Mon Sep 17 00:00:00 2001 From: gpamangkp Date: Wed, 21 Oct 2020 10:25:43 +0530 Subject: [PATCH 29/69] Modified the source for wider range of inputs 1. Replaced the namespace with a generic class Graph 2. Created add edge function to account for both directional and bidirectional graph 3. test case to include string nodes also --- graph/breadth_first_search.cpp | 199 ++++++++++++++++----------------- 1 file changed, 98 insertions(+), 101 deletions(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 28cad4930..132687107 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -6,6 +6,7 @@ * * \author [Ayaan Khan](http://github.com/ayaankhan98) * + * * \details * Breadth First Search also quoted as BFS is a Graph Traversal Algorithm. * Time Complexity O(|V| + |E|) where V are the number of vertices and E @@ -48,132 +49,127 @@ #include #include #include +#include +#include +#include -/** - * \namespace graph - * \brief Graph algorithms - */ -namespace graph { -/** - * \brief Representation of the graph as an adjacency list. - * - * For every vertex, there is a list of its neighbors in the order in which - * they were added to the graph. By default, the edges are directed, but - * an undirected graph can be represented simply by storing each each as - * two directed edges in both directions. - */ -using adjacency_list = std::vector>; - -/** - * \brief - * Adds a directed edge from vertex u to vertex v. - * - * @param graph Adjacency list representation of graph - * @param u first vertex - * @param v second vertex - * - */ -void add_directed_edge(adjacency_list *graph, int u, int v) { - (*graph)[u].push_back(v); -} - -/** - * \brief - * Adds an undirected edge from vertex u to vertex v. - * Essentially adds too directed edges to the adjacency list reprsentation - * of the graph. - * - * @param graph Adjacency list representation of graph - * @param u first vertex - * @param v second vertex - * - */ -void add_undirected_edge(adjacency_list *graph, int u, int v) { - add_directed_edge(graph, u, v); - add_directed_edge(graph, v, u); -} - -/** - * \brief - * Function performs the breadth first search algorithm over the graph - * - * @param graph Adjacency list representation of graph - * @param start vertex from where traversing starts - * @returns a binary vector indicating which vertices were visited during the - * search. - * - */ -std::vector breadth_first_search(const adjacency_list &graph, int start) { - /// vector to keep track of visited vertices - std::vector visited(graph.size(), false); - /// queue that stores vertices that need to be further explored - std::queue tracker; - - /// mark the starting vertex as visited - visited[start] = true; - tracker.push(start); - while (!tracker.empty()) { - size_t vertex = tracker.front(); - tracker.pop(); - for (auto x : graph[vertex]) { - /// if the vertex is not visited then mark it as visited - /// and push it to the queue - if (!visited[x]) { - visited[x] = true; - tracker.push(x); - } - } +/* Class Graph definition */ +template +class Graph{ + /** + * adjacency_list maps every vertex to the list of its neighbours in the order + * in which they are added. + */ + std::map > adjacency_list; + public: + Graph(){}; + void add_edge(T u,T v, bool bidir=true){ + /** + * add_edge(u,v,bidir) is used to add an edge between node u and node v + * by default , bidir is made true , i.e graph is bidirectional . + * It means if edge(u,v) is added then u-->v and v-->u both edges exist. + * + * to make the graph unidirectional pass the third parameter of add_edge as + * false which will + */ + adjacency_list[u].push_back(v); // u-->v edge added + if(bidir==true){ + // if graph is bidirectional + adjacency_list[v].push_back(u); // v-->u edge added + } } - return visited; -} + /** + * this function performs the breadth first search on graph and return a + * mapping which maps the nodes to a boolean value representing whether the + * node was traversed or not. + */ + std::map breadth_first_search(T src){ + std::map tracker; -} // namespace graph + for(auto adjlist: adjacency_list){ + tracker[adjlist.first]=false; + for(auto node:adjacency_list[adjlist.first]){ + tracker[node]=false; + } + } + std::queue q; + q.push(src); + tracker[src]=true; + while(!q.empty()){ + T node = q.front(); + q.pop(); + for(T neighbour : adjacency_list[node]){ + if(!tracker[neighbour]){ + q.push(neighbour); + tracker[neighbour]=true; + } + } + } + return tracker; + } +}; /** Test function */ static void tests() { /// Test 1 Begin - graph::adjacency_list graph(4, std::vector()); - graph::add_undirected_edge(&graph, 0, 1); - graph::add_undirected_edge(&graph, 1, 2); - graph::add_undirected_edge(&graph, 2, 3); + Graph g; + std::map correct_result; + g.add_edge(0,1); + g.add_edge(1,2); + g.add_edge(2,3); + correct_result[0]=true; + correct_result[1]=true; + correct_result[2]=true; + correct_result[3]=true; - std::vector returned_result = graph::breadth_first_search(graph, 2); - std::vector correct_result = {true, true, true, true}; + std::map returned_result = g.breadth_first_search(2); - assert(std::equal(correct_result.begin(), correct_result.end(), - returned_result.begin())); + assert(returned_result==correct_result); std::cout << "Test 1 Passed..." << std::endl; /// Test 2 Begin - returned_result = graph::breadth_first_search(graph, 0); + returned_result = g.breadth_first_search(0); - assert(std::equal(correct_result.begin(), correct_result.end(), - returned_result.begin())); + assert(returned_result==correct_result); std::cout << "Test 2 Passed..." << std::endl; /// Test 3 Begins - graph.clear(); - graph.resize(6); - graph::add_directed_edge(&graph, 0, 1); - graph::add_directed_edge(&graph, 0, 2); - graph::add_directed_edge(&graph, 1, 3); - graph::add_directed_edge(&graph, 2, 3); - graph::add_directed_edge(&graph, 1, 4); - graph::add_directed_edge(&graph, 3, 5); + // 0-> Gorakhpur + // 1-> Lucknow + // 2-> Kanpur + // 3-> Agra + // 4-> Prayagraj + // 5-> Noida + Graph g2; - returned_result = graph::breadth_first_search(graph, 2); - correct_result = {false, false, true, true, false, true}; + g2.add_edge("Gorakhpur","Lucknow",false); + g2.add_edge("Gorakhpur","Kanpur",false); + g2.add_edge("Lucknow","Agra",false); + g2.add_edge("Kanpur","Agra",false); + g2.add_edge("Lucknow","Prayagraj",false); + g2.add_edge("Agra","Noida",false); - assert(std::equal(correct_result.begin(), correct_result.end(), - returned_result.begin())); + std::map correct_res; + std::map returned_res=g2.breadth_first_search("Kanpur"); + correct_res["Gorakhpur"]=false; + correct_res["Lucknow"]=false; + correct_res["Kanpur"]=true; + correct_res["Agra"]=true; + correct_res["Prayagraj"]=false; + correct_res["Noida"]=true; + for(auto x: returned_res){ + std::cout<> vertices; @@ -193,5 +189,6 @@ int main() { } graph::breadth_first_search(graph, 0); +*/ return 0; } From 676db2e57b9d56b3f3875c487cf0f61b4942f418 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 10:37:32 +0530 Subject: [PATCH 30/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 1465aa11a..0ee714671 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -16,8 +16,8 @@ * sum will be 1, thus verifying that it is a magic number. * @author [Neha Hasija](https://github.com/neha-hasija17) */ -#include -#include +#include /// for assert +#include /// for io operations /** * Function to check if the given number is magic number or not. From 7672e3998c84398b270bd50539e404a5a2603705 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 10:37:51 +0530 Subject: [PATCH 31/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 0ee714671..fb0b30468 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -38,7 +38,8 @@ bool magic_number(int n) { } } -/** Test function +/** + * @brief Test function * @returns void */ static void tests() { From 45dc717621b9fa789b1b71f3bef6c65362df3a0e Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 10:38:02 +0530 Subject: [PATCH 32/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index fb0b30468..bec86b888 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -68,6 +68,6 @@ static void tests() { * @returns 0 on exit */ int main() { - tests(); + tests(); // execute the tests return 0; } From 1e6c2d5aa049ed4e921b2fd577a06b4bc538ea49 Mon Sep 17 00:00:00 2001 From: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Date: Wed, 21 Oct 2020 05:10:05 +0000 Subject: [PATCH 33/69] clang-format and clang-tidy fixes for 45dc7176 --- math/magic_number.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index bec86b888..3720dff65 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -16,8 +16,8 @@ * sum will be 1, thus verifying that it is a magic number. * @author [Neha Hasija](https://github.com/neha-hasija17) */ -#include /// for assert -#include /// for io operations +#include /// for assert +#include /// for io operations /** * Function to check if the given number is magic number or not. @@ -68,6 +68,6 @@ static void tests() { * @returns 0 on exit */ int main() { - tests(); // execute the tests + tests(); // execute the tests return 0; } From a19da7954517da446f1253d4001c603bf83a622e Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 10:41:16 +0530 Subject: [PATCH 34/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 3720dff65..c913c5dbd 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -37,6 +37,7 @@ bool magic_number(int n) { return false; } } +} // namespace math /** * @brief Test function From 651c2693175d70e8fca73446152c478302bfacf8 Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Wed, 21 Oct 2020 11:04:34 +0530 Subject: [PATCH 35/69] Modified the code as per the suggestions --- graph/breadth_first_search.cpp | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 132687107..f6846e00e 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -87,9 +87,9 @@ class Graph{ std::map breadth_first_search(T src){ std::map tracker; - for(auto adjlist: adjacency_list){ + for(auto const adjlist: adjacency_list){ tracker[adjlist.first]=false; - for(auto node:adjacency_list[adjlist.first]){ + for(auto const node:adjacency_list[adjlist.first]){ tracker[node]=false; } } @@ -99,7 +99,7 @@ class Graph{ while(!q.empty()){ T node = q.front(); q.pop(); - for(T neighbour : adjacency_list[node]){ + for(T const neighbour : adjacency_list[node]){ if(!tracker[neighbour]){ q.push(neighbour); tracker[neighbour]=true; @@ -109,6 +109,7 @@ class Graph{ return tracker; } }; +/* Class definition ends */ /** Test function */ static void tests() { @@ -135,12 +136,6 @@ static void tests() { std::cout << "Test 2 Passed..." << std::endl; /// Test 3 Begins - // 0-> Gorakhpur - // 1-> Lucknow - // 2-> Kanpur - // 3-> Agra - // 4-> Prayagraj - // 5-> Noida Graph g2; g2.add_edge("Gorakhpur","Lucknow",false); @@ -158,9 +153,6 @@ static void tests() { correct_res["Agra"]=true; correct_res["Prayagraj"]=false; correct_res["Noida"]=true; - for(auto x: returned_res){ - std::cout<> vertices; + size_t edges = 0; std::cout << "Enter the number of edges: "; std::cin >> edges; - graph::adjacency_list graph(vertices); + Graph g; std::cout << "Enter space-separated pairs of vertices that form edges: " << std::endl; while (edges--) { int u = 0, v = 0; std::cin >> u >> v; - // Decrement the vertex index so that we can read more convenint - // 1-based indexing from the user input. - graph::add_directed_edge(&graph, u - 1, v - 1); + g.add_edge(u,v); } - graph::breadth_first_search(graph, 0); -*/ + g.breadth_first_search(0); return 0; } From 2e5c68a54e8d83c70830d8a78a15e9f175ad95fe Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Wed, 21 Oct 2020 11:09:48 +0530 Subject: [PATCH 36/69] included referenced variable to avoid repitition --- graph/breadth_first_search.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index f6846e00e..2553efc72 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -87,9 +87,9 @@ class Graph{ std::map breadth_first_search(T src){ std::map tracker; - for(auto const adjlist: adjacency_list){ + for(auto const &adjlist: adjacency_list){ tracker[adjlist.first]=false; - for(auto const node:adjacency_list[adjlist.first]){ + for(auto const &node:adjacency_list[adjlist.first]){ tracker[node]=false; } } @@ -99,7 +99,7 @@ class Graph{ while(!q.empty()){ T node = q.front(); q.pop(); - for(T const neighbour : adjacency_list[node]){ + for(T const &neighbour : adjacency_list[node]){ if(!tracker[neighbour]){ q.push(neighbour); tracker[neighbour]=true; From b1079da17d34fed4327af58b222e8d04add4b635 Mon Sep 17 00:00:00 2001 From: Tsung-Han Ho Date: Wed, 21 Oct 2020 23:07:53 +0800 Subject: [PATCH 37/69] feat: add cycle sort algorithm (#1252) * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * updating DIRECTORY.md * Add namespace decription * fix: add assert and template * fix: add some comment * fix: update some suggested changes * fix: update some suggested changes Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + sorting/cycle_sort.cpp | 104 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 sorting/cycle_sort.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 31a9f4141..c857306da 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -240,6 +240,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) + * [Cycle Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/cycle_sort.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) diff --git a/sorting/cycle_sort.cpp b/sorting/cycle_sort.cpp new file mode 100644 index 000000000..2d14f399e --- /dev/null +++ b/sorting/cycle_sort.cpp @@ -0,0 +1,104 @@ +/** + * @file + * @brief Implementation of [Cycle sort](https://en.wikipedia.org/wiki/Cycle_sort) algorithm + * + * @details + * Cycle Sort is a sorting algorithm that works in \f$O(n^2)\f$ time in best cas and works in \f$O(n^2)\f$ in worst case. + * If a element is already at its correct position, do nothing. + * If a element is not at its correct position, we then need to move it to its correct position by computing the correct positions.Therefore, we should make sure the duplicate elements. + * + * @author [TsungHan Ho](https://github.com/dalaoqi) + */ + +#include /// for std::is_sorted, std::swap +#include /// for assert +#include /// for io operations +#include /// for std::vector + +/** + * @namespace sorting + * @brief Sorting algorithms + */ +namespace sorting { +/** + * @namespace cycle_sort + * @brief Functions for [Cycle sort](https://en.wikipedia.org/wiki/Cycle_sort) algorithm + */ +namespace cycle_sort { +/** + * @brief The main function implements cycleSort + * @tparam T type of array + * @param in_arr array to be sorted + * @returns void + */ +template +std::vector cycleSort(const std::vector &in_arr) { + std::vector arr(in_arr); + for (size_t cycle_start = 0; cycle_start <= arr.size() - 1; cycle_start++) { + // initialize item + T item = arr[cycle_start]; + + // Count the number of elements smaller than item, this number is the correct index of item. + int pos = cycle_start; + for (size_t i = cycle_start + 1; i < arr.size(); i++) { + if (arr[i] < item) { + pos++; + } + } + + // item is already in correct position + if (pos == cycle_start) { + continue; + } + + // duplicate elements + while (item == arr[pos]) pos += 1; + std::swap(item, arr[pos]); + + // Rest of the elements + while (pos != cycle_start) { + pos = cycle_start; + // Find position where we put the element + for (size_t i = cycle_start + 1; i < arr.size(); i++) { + if (arr[i] < item) { + pos += 1; + } + } + // duplicate elements + while (item == arr[pos]) pos += 1; + std::swap(item, arr[pos]); + } + } + return arr; +} +} // namespace cycle_sort +} // namespace sorting + +/** + * @brief Test implementations + * @returns void + */ +static void test() { + // [506, 48, 123, 79, 0, 362, 951, 500, 0] return [0, 0, 48, 79, 123, 362, 500, 506, 951] + std::vector array1 = {506, 48, 123, 79, 0, 362, 951, 500, 0}; + std::cout << "Test 1... "; + std::vector arr1 = sorting::cycle_sort::cycleSort(array1); + assert(std::is_sorted(std::begin(arr1), std::end(arr1))); + std::cout << "passed" << std::endl; + + // [4.3, -6.5, -7.4, 0, 2.7, 1.8] return [-7.4, -6.5, 0, 1.8, 2.7, 4.3] + std::vector array2 = {4.3, -6.5, -7.4, 0, 2.7, 1.8}; + std::cout << "Test 2... "; + std::vector arr2 = sorting::cycle_sort::cycleSort(array2); + assert(std::is_sorted(std::begin(arr2), std::end(arr2))); + std::cout << "passed" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the test + return 0; +} From 1af94ccf6fe788e2c2f4ff3fa050a0008d81fff8 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:15:06 +0530 Subject: [PATCH 38/69] Update math/lcm_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index d9c61fb95..60bac3283 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -1,6 +1,6 @@ /** * @file - * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ + * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. * The value of the sum is calculated by formula: From 388ee0098571230cca261db9081baa3044c45878 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:06:37 +0530 Subject: [PATCH 39/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index c913c5dbd..0d1fc3711 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -19,6 +19,11 @@ #include /// for assert #include /// for io operations +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { /** * Function to check if the given number is magic number or not. * @param n number to be checked. From 7643a23359641c9aeb19ae7f0e2add2fbf0e9a8b Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:36:54 +0530 Subject: [PATCH 40/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 0d1fc3711..3765b69e3 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -50,7 +50,7 @@ bool magic_number(int n) { */ static void tests() { std::cout << "Test 1:\t n=60\n"; - assert(magic_number(60) == false); + assert(math::magic_number(60) == false); std::cout << "passed\n"; std::cout << "Test 2:\t n=730\n"; From bbb182c42bd1ed9b92c91be3eef2f53b89856d7a Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:37:05 +0530 Subject: [PATCH 41/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 3765b69e3..6f5de1698 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -54,7 +54,7 @@ static void tests() { std::cout << "passed\n"; std::cout << "Test 2:\t n=730\n"; - assert(magic_number(730) == true); + assert(math::magic_number(730) == true); std::cout << "passed\n"; std::cout << "Test 3:\t n=0\n"; From 6359899caa483f2dcfba68cfa9f68154a3a84986 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:37:16 +0530 Subject: [PATCH 42/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 6f5de1698..42f02c691 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -58,7 +58,7 @@ static void tests() { std::cout << "passed\n"; std::cout << "Test 3:\t n=0\n"; - assert(magic_number(0) == false); + assert(math::magic_number(0) == false); std::cout << "passed\n"; std::cout << "Test 4:\t n=479001600\n"; From 534dacae359699324ca2bc8b2d441e3bf648b418 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:37:27 +0530 Subject: [PATCH 43/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 42f02c691..b00a3b858 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -62,7 +62,7 @@ static void tests() { std::cout << "passed\n"; std::cout << "Test 4:\t n=479001600\n"; - assert(magic_number(479001600) == false); + assert(math::magic_number(479001600) == false); std::cout << "passed\n"; std::cout << "Test 5:\t n=-35\n"; From 137c444398f13b8b4c5ca9270c863f0e2d4d08d3 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Wed, 21 Oct 2020 23:37:39 +0530 Subject: [PATCH 44/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index b00a3b858..389ff26d2 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -66,7 +66,7 @@ static void tests() { std::cout << "passed\n"; std::cout << "Test 5:\t n=-35\n"; - assert(magic_number(-35) == false); + assert(math::magic_number(-35) == false); std::cout << "passed\n"; } From 997404b48aa18eb42c3570fa183bf99f0bacc957 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Wed, 21 Oct 2020 22:15:20 +0530 Subject: [PATCH 45/69] Update math/lcm_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/lcm_sum.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 60bac3283..dd9667b49 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -1,13 +1,13 @@ /** * @file - * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ + * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. * The value of the sum is calculated by formula: * \f[ * \sum\mathrm{LCM}(i, n) = \frac{1}{2} \left[\left(\sum (d * \mathrm{ETF}(d)) + 1\right) * n\right] * \f] - * + * where \mathrm{ETF}(i) represents Euler totient function of i. * @author [Chesta Mittal](https://github.com/chestamittal) */ @@ -25,11 +25,11 @@ namespace math { * @param num input number * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num */ - int lcmSum(int num) { + uint64_t lcmSum(uint64_t num) { - int i=0, j=0; - std::vector eulerTotient(num+1); - std::vector sumOfEulerTotient(num+1); + uint64_t i=0, j=0; + std::vector eulerTotient(num+1); + std::vector sumOfEulerTotient(num+1); // storing initial values in eulerTotient vector for(i=1; i<=num; i++) { @@ -63,28 +63,28 @@ namespace math { * @returns `void` */ static void test() { - int n = 2; - int test_1 = math::lcmSum(n); + uint64_t n = 2; + uint64_t test_1 = math::lcmSum(n); assert(test_1 == 4); std::cout << "Passed Test 1!" << std::endl; n = 5; - int test_2 = math::lcmSum(n); + uint64_t test_2 = math::lcmSum(n); assert(test_2 == 55); std::cout << "Passed Test 2!" << std::endl; n = 10; - int test_3 = math::lcmSum(n); + uint64_t test_3 = math::lcmSum(n); assert(test_3 == 320); std::cout << "Passed Test 3!" << std::endl; n = 11; - int test_4 = math::lcmSum(n); + uint64_t test_4 = math::lcmSum(n); assert(test_4 == 616); std::cout << "Passed Test 4!" << std::endl; n = 15; - int test_5 = math::lcmSum(n); + uint64_t test_5 = math::lcmSum(n); assert(test_5 == 1110); std::cout << "Passed Test 5!" << std::endl; } From 8a24e44a4c4fddd0a3ce9f5b12ed1f9e66657a6c Mon Sep 17 00:00:00 2001 From: Sagar Pandya <31953933+sagarpandyansit@users.noreply.github.com> Date: Thu, 22 Oct 2020 23:10:22 +0530 Subject: [PATCH 46/69] fix: Issue in list_array.cpp resolved (#1342) * Exit code added to exit from infinite loop * fix typos and resolve all clang-tidy warnings * changed C type array style and changed code accordingly in list_array.cpp * pass const array to resolve clang-tidy error in list_array.cpp * Update newline in list_array.cpp Co-authored-by: David Leal Co-authored-by: David Leal --- data_structures/list_array.cpp | 73 +++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/data_structures/list_array.cpp b/data_structures/list_array.cpp index 24b04867b..6cbf8e154 100644 --- a/data_structures/list_array.cpp +++ b/data_structures/list_array.cpp @@ -4,31 +4,32 @@ * @warning The sorting algorithm is erroneous */ #include +#include struct list { - int data[50]; + std::array data{}; int top = 0; bool isSorted = false; - int BinarySearch(int *array, int first, int last, int x) { + int BinarySearch(const std::array& dataArr, int first, int last, int x) { if (last < first) { return -1; } int mid = (first + last) / 2; - if (array[mid] == x) + if (dataArr[mid] == x) return mid; - else if (x < array[mid]) - return (BinarySearch(array, first, mid - 1, x)); - else if (x > array[mid]) - return (BinarySearch(array, mid + 1, last, x)); + else if (x < dataArr[mid]) + return (BinarySearch(dataArr, first, mid - 1, x)); + else if (x > dataArr[mid]) + return (BinarySearch(dataArr, mid + 1, last, x)); std::cerr << __func__ << ":" << __LINE__ << ": Undefined condition\n"; return -1; } - int LinarSearch(int *array, int x) { + int LinearSearch(const std::array& dataArr, int x) const { for (int i = 0; i < top; i++) { - if (array[i] == x) { + if (dataArr[i] == x) { return i; } } @@ -37,12 +38,12 @@ struct list { } int Search(int x) { - int pos = -1; + int pos; if (isSorted) { pos = BinarySearch(data, 0, top - 1, x); } else { - pos = LinarSearch(data, x); + pos = LinearSearch(data, x); } if (pos != -1) { @@ -54,7 +55,7 @@ struct list { } void Sort() { - int i, j, pos; + int i, j, pos=0; for (i = 0; i < top; i++) { int min = data[i]; for (j = i + 1; j < top; j++) { @@ -121,6 +122,8 @@ int main() { int choice; int x; do { + // Choices for operations on the list_array. + std::cout << "\n0.Exit"; std::cout << "\n1.Insert"; std::cout << "\n2.Delete"; std::cout << "\n3.Search"; @@ -129,27 +132,31 @@ 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 0: + 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; + default: + std::cout << "\nplease enter valid option."; } } while (choice != 0); return 0; From baffac80ad9d52ddd624b1c01e2d67c085d085a9 Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Fri, 23 Oct 2020 08:30:13 +0530 Subject: [PATCH 47/69] fix : reused the namespace, improved documentation 1. Included the graph definition in the namespace graph 2. Added documentation for the breadth-first search function --- graph/breadth_first_search.cpp | 128 +++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 2553efc72..f7a0a5077 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -5,6 +5,7 @@ * (Breadth First Search)](https://en.wikipedia.org/wiki/Breadth-first_search) * * \author [Ayaan Khan](http://github.com/ayaankhan98) + * \contributor [Aman Kumar Pandey](http://github.com/gpamangkp) * * * \details @@ -53,68 +54,87 @@ #include #include - -/* Class Graph definition */ -template -class Graph{ - /** - * adjacency_list maps every vertex to the list of its neighbours in the order - * in which they are added. - */ - std::map > adjacency_list; - public: - Graph(){}; - void add_edge(T u,T v, bool bidir=true){ - /** - * add_edge(u,v,bidir) is used to add an edge between node u and node v - * by default , bidir is made true , i.e graph is bidirectional . - * It means if edge(u,v) is added then u-->v and v-->u both edges exist. - * - * to make the graph unidirectional pass the third parameter of add_edge as - * false which will - */ - adjacency_list[u].push_back(v); // u-->v edge added - if(bidir==true){ - // if graph is bidirectional - adjacency_list[v].push_back(u); // v-->u edge added - } - } +///namespace graph which contains the class Graph +namespace graph{ + /* Class Graph definition */ + template + class Graph{ /** - * this function performs the breadth first search on graph and return a - * mapping which maps the nodes to a boolean value representing whether the - * node was traversed or not. + * adjacency_list maps every vertex to the list of its neighbours in the order + * in which they are added. */ - std::map breadth_first_search(T src){ - std::map tracker; - - for(auto const &adjlist: adjacency_list){ - tracker[adjlist.first]=false; - for(auto const &node:adjacency_list[adjlist.first]){ - tracker[node]=false; + std::map > adjacency_list; + public: + Graph(){}; + void add_edge(T u,T v, bool bidir=true){ + /** + * add_edge(u,v,bidir) is used to add an edge between node u and node v + * by default , bidir is made true , i.e graph is bidirectional . + * It means if edge(u,v) is added then u-->v and v-->u both edges exist. + * + * to make the graph unidirectional pass the third parameter of add_edge as + * false which will + */ + adjacency_list[u].push_back(v); // u-->v edge added + if(bidir==true){ + // if graph is bidirectional + adjacency_list[v].push_back(u); // v-->u edge added } } - std::queue q; - q.push(src); - tracker[src]=true; - while(!q.empty()){ - T node = q.front(); - q.pop(); - for(T const &neighbour : adjacency_list[node]){ - if(!tracker[neighbour]){ - q.push(neighbour); - tracker[neighbour]=true; + + + /** + * this function performs the breadth first search on graph and return a + * mapping which maps the nodes to a boolean value representing whether the + * node was traversed or not. + */ + std::map breadth_first_search(T src){ + /// mapping to keep track of all visited nodes + std::map visited; + /// initialise every possible vertex to map to false + /// initially none of the vertices are unvisited + for(auto const &adjlist: adjacency_list){ + visited[adjlist.first]=false; + for(auto const &node:adjacency_list[adjlist.first]){ + visited[node]=false; } } + + /// queue to store the nodes which are yet to be traversed + std::queue tracker; + + /// push the source vertex to queue to begin traversing + tracker.push(src); + ///mark the source vertex as visited + visited[src]=true; + while(!tracker.empty()){ + /// traverse the graph till no connected vertex are left + /// extract a node from queue for further traversal + T node = tracker.front(); + /// remove the node from the queue + tracker.pop(); + for(T const &neighbour : adjacency_list[node]){ + /// check every vertex connected to the node which are still unvisited + if(!visited[neighbour]){ + /// if the neighbour is unvisited , push it into the queue + tracker.push(neighbour); + /// mark the neighbour as visited + visited[neighbour]=true; + } + } + } + return visited; } - return tracker; - } -}; -/* Class definition ends */ + }; + /* Class definition ends */ +} +///Namespace definition over + /** Test function */ static void tests() { /// Test 1 Begin - Graph g; + graph::Graph g; std::map correct_result; g.add_edge(0,1); g.add_edge(1,2); @@ -131,12 +151,12 @@ static void tests() { /// Test 2 Begin returned_result = g.breadth_first_search(0); - + assert(returned_result==correct_result); std::cout << "Test 2 Passed..." << std::endl; /// Test 3 Begins - Graph g2; + graph::Graph g2; g2.add_edge("Gorakhpur","Lucknow",false); g2.add_edge("Gorakhpur","Kanpur",false); @@ -165,7 +185,7 @@ int main() { std::cout << "Enter the number of edges: "; std::cin >> edges; - Graph g; + graph::Graph g; std::cout << "Enter space-separated pairs of vertices that form edges: " << std::endl; From 1cbc00c54181a2017f55b4fe5ddcfe9afe87be70 Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Fri, 23 Oct 2020 09:13:27 +0530 Subject: [PATCH 48/69] Update graph/breadth_first_search.cpp Co-authored-by: David Leal --- graph/breadth_first_search.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index f7a0a5077..3843ac18a 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -54,7 +54,10 @@ #include #include -///namespace graph which contains the class Graph +/** + * \namespace graph + * \brief Graph algorithms + */ namespace graph{ /* Class Graph definition */ template From 3025fc674c232765094acf631d73953f2634dca6 Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Fri, 23 Oct 2020 09:13:40 +0530 Subject: [PATCH 49/69] Update graph/breadth_first_search.cpp Co-authored-by: David Leal --- graph/breadth_first_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 3843ac18a..1d38fda24 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -4,7 +4,7 @@ * \brief [Breadth First Search Algorithm * (Breadth First Search)](https://en.wikipedia.org/wiki/Breadth-first_search) * - * \author [Ayaan Khan](http://github.com/ayaankhan98) + * \author [Ayaan Khan](https://github.com/ayaankhan98) * \contributor [Aman Kumar Pandey](http://github.com/gpamangkp) * * From c53f29fb53df3c1f3a16ce3c8e7c57be774c65cd Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Fri, 23 Oct 2020 09:13:48 +0530 Subject: [PATCH 50/69] Update graph/breadth_first_search.cpp Co-authored-by: David Leal --- graph/breadth_first_search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 1d38fda24..06af41a01 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -5,7 +5,7 @@ * (Breadth First Search)](https://en.wikipedia.org/wiki/Breadth-first_search) * * \author [Ayaan Khan](https://github.com/ayaankhan98) - * \contributor [Aman Kumar Pandey](http://github.com/gpamangkp) + * \author [Aman Kumar Pandey](https://github.com/gpamangkp) * * * \details From f763e8d13773efac82477cd8a1695784655c320e Mon Sep 17 00:00:00 2001 From: Gpamangkp <41160734+Gpamangkp@users.noreply.github.com> Date: Fri, 23 Oct 2020 09:13:58 +0530 Subject: [PATCH 51/69] Update graph/breadth_first_search.cpp Co-authored-by: David Leal --- graph/breadth_first_search.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/graph/breadth_first_search.cpp b/graph/breadth_first_search.cpp index 06af41a01..a0c872681 100644 --- a/graph/breadth_first_search.cpp +++ b/graph/breadth_first_search.cpp @@ -131,7 +131,6 @@ namespace graph{ }; /* Class definition ends */ } -///Namespace definition over /** Test function */ From a6526c8108c60e51c5d0471211f23f2fbbdda8a9 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Sat, 24 Oct 2020 10:36:20 +0530 Subject: [PATCH 52/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 389ff26d2..35da3b00e 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -70,7 +70,8 @@ static void tests() { std::cout << "passed\n"; } -/** Main function +/** + * @brief Main function * @returns 0 on exit */ int main() { From 288d3582b62ea83e5d582c213fa79aefc472dd07 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Thu, 22 Oct 2020 02:17:34 +0530 Subject: [PATCH 53/69] Update math/lcm_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- math/lcm_sum.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index dd9667b49..a27f6d239 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -1,7 +1,7 @@ /** * @file - * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ - * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + .. + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ + * @brief An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ + * @details An algorithm to calculate the sum of LCM: \f$\mathrm{LCM}(1,n) + \mathrm{LCM}(2,n) + \ldots + \mathrm{LCM}(n,n)\f$ where \f$\mathrm{LCM}(i,n)\f$ * denotes the Least Common Multiple of the integers i and n. For n greater than or equal to 1. * The value of the sum is calculated by formula: * \f[ From 57729bf37fe06dd7e34569894b56bee77d653adf Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Mon, 26 Oct 2020 00:00:43 +0530 Subject: [PATCH 54/69] Update math/lcm_sum.cpp Co-authored-by: David Leal --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index a27f6d239..4800ed66a 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -25,7 +25,7 @@ namespace math { * @param num input number * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num */ - uint64_t lcmSum(uint64_t num) { + uint64_t lcmSum(uint16_t num) { uint64_t i=0, j=0; std::vector eulerTotient(num+1); From 57a5dcb2c7f55404ad31847dba461f57bd91c4c0 Mon Sep 17 00:00:00 2001 From: Sujay008 <45827775+sujaykaushik008@users.noreply.github.com> Date: Mon, 26 Oct 2020 00:51:24 +0530 Subject: [PATCH 55/69] feat: add palindrome partitioning algorithm (#1319) * feat: add palindrome partitioning algorithm * Update palindrome_partitioning.cpp * updating DIRECTORY.md * Update palindrome_partitioning.cpp Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + .../palindrome_partitioning.cpp | 123 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 dynamic_programming/palindrome_partitioning.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index c857306da..15283332c 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -67,6 +67,7 @@ * [Longest Increasing Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_increasing_subsequence.cpp) * [Longest Increasing Subsequence (Nlogn)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/longest_increasing_subsequence_(nlogn).cpp) * [Matrix Chain Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/matrix_chain_multiplication.cpp) + * [Palindrome Partitioning](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/palindrome_partitioning.cpp) * [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/searching_of_element_in_dynamic_array.cpp) * [Shortest Common Supersequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/shortest_common_supersequence.cpp) * [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/tree_height.cpp) diff --git a/dynamic_programming/palindrome_partitioning.cpp b/dynamic_programming/palindrome_partitioning.cpp new file mode 100644 index 000000000..b5ab4ed6c --- /dev/null +++ b/dynamic_programming/palindrome_partitioning.cpp @@ -0,0 +1,123 @@ +/** + * @file + * @brief Implements [Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning-ii/) algorithm, giving you the minimum number of partitions you need to make + * + * @details + * palindrome partitioning uses dynamic programming and goes to all the possible partitions to find the minimum + * you are given a string and you need to give minimum number of partitions needed to divide it into a number of palindromes + * [Palindrome Partitioning] (https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/) + * overall time complexity O(n^2) + * For example: example 1:- + * String : "nitik" + * Output : 2 => "n | iti | k" + * For example: example 2:- + * String : "ababbbabbababa" + * Output : 3 => "aba | b | bbabb | ababa" + * @author [Sujay Kaushik] (https://github.com/sujaykaushik008) + */ + +#include // for io operations +#include // for std::vector +#include // for std::min +#include // for std::assert +#include // for INT_MAX + +/** + * @namespace dynamic_programming + * @brief Dynamic Programming algorithms + */ +namespace dynamic_programming { + + /** + * @namespace palindrome_partitioning + * @brief Functions for [Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning-ii/) algorithm + */ + namespace palindrome_partitioning { + + /** + * Function implementing palindrome partitioning algorithm using lookup table method. + * @param str input string + * @returns minimum number of partitions + */ + int pal_part(const std::string &str) { + + int n = str.size(); + + // creating lookup table for minimum number of cuts + std::vector > cuts(n, std::vector(n, 0)); + + // creating lookup table for palindrome checking + std::vector > is_palindrome(n, std::vector(n, false)); + + // initialization + for (int i = 0; i < n; i++) { + is_palindrome[i][i] = true; + cuts[i][i] = 0; + } + + for (int len = 2; len <= n; len++) { + for (int start_index = 0; start_index < n - len + 1; start_index++) { + + int end_index = start_index + len - 1; + + if (len == 2) { + is_palindrome[start_index][end_index] = (str[start_index] == str[end_index]); + } else { + is_palindrome[start_index][end_index] = + (str[start_index] == str[end_index]) && is_palindrome[start_index + 1][end_index - 1]; + } + + if (is_palindrome[start_index][end_index]) { + cuts[start_index][end_index] = 0; + } else { + cuts[start_index][end_index] = INT_MAX; + for (int partition = start_index; partition <= end_index - 1; partition++) { + cuts[start_index][end_index] = std::min(cuts[start_index][end_index], + cuts[start_index][partition] + + cuts[partition + 1][end_index] + 1); + } + } + } + } + + return cuts[0][n - 1]; + } + } // namespace palindrome_partitioning +} // namespace dynamic_programming + +/** + * @brief Test Function + * @return void +*/ +static void test() { + // custom input vector + std::vector custom_input{"nitik", "ababbbabbababa", "abdc"}; + + // calculated output vector by pal_part Function + std::vector calculated_output(3); + + for (int i = 0; i < 3; i++) { + calculated_output[i] = dynamic_programming::palindrome_partitioning::pal_part(custom_input[i]); + } + + // expected output vector + std::vector expected_output{2, 3, 3}; + + // Testing implementation via assert function + // It will throw error if any of the expected test fails + // Else it will give nothing + for (int i = 0; i < 3; i++) { + assert(expected_output[i] == calculated_output[i]); + } + + std::cout << "All tests passed successfully!\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the test + return 0; +} From 2d415763d7f456fc5313bee05dfe746e4614dd67 Mon Sep 17 00:00:00 2001 From: chestamittal <53469607+chestamittal@users.noreply.github.com> Date: Tue, 27 Oct 2020 01:09:08 +0530 Subject: [PATCH 56/69] Update math/lcm_sum.cpp Co-authored-by: Ayaan Khan --- math/lcm_sum.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/lcm_sum.cpp b/math/lcm_sum.cpp index 4800ed66a..34b46020f 100644 --- a/math/lcm_sum.cpp +++ b/math/lcm_sum.cpp @@ -25,7 +25,7 @@ namespace math { * @param num input number * @returns int Sum of LCMs, i.e. ∑LCM(i, num) from i = 1 to num */ - uint64_t lcmSum(uint16_t num) { + uint64_t lcmSum(const uint16_t& num) { uint64_t i=0, j=0; std::vector eulerTotient(num+1); From 69cacbc88b43b44f3c7a91c74a8471d264fcfde9 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Tue, 27 Oct 2020 06:33:14 +0530 Subject: [PATCH 57/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 35da3b00e..047278500 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -29,7 +29,7 @@ namespace math { * @param n number to be checked. * @return if number is a magic number, returns true, else false. */ -bool magic_number(int n) { +bool magic_number(const uint64_t &n) { if (n <= 0) { return false; } From 806f3251ee483a4f31b4ec4dd7e1f645a79630e9 Mon Sep 17 00:00:00 2001 From: Neha Hasija Date: Tue, 27 Oct 2020 06:33:29 +0530 Subject: [PATCH 58/69] Update math/magic_number.cpp Co-authored-by: David Leal --- math/magic_number.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/magic_number.cpp b/math/magic_number.cpp index 047278500..51232601b 100644 --- a/math/magic_number.cpp +++ b/math/magic_number.cpp @@ -34,7 +34,7 @@ bool magic_number(const uint64_t &n) { return false; } // result stores the modulus of @param n with 9 - int result = n % 9; + uint64_t result = n % 9; // if result is 1 then the number is a magic number else not if (result == 1) { return true; From 0f8324ed49ae0a33224a0e14912552c58c2af345 Mon Sep 17 00:00:00 2001 From: muskan0719 <53470969+muskan0719@users.noreply.github.com> Date: Wed, 28 Oct 2020 14:23:57 +0530 Subject: [PATCH 59/69] feat: add sum_of_binomial_coefficients (#1363) * Add files via upload * update sum_of_binomial_coefficients * Update math/sum_of_binomial_coefficient.cpp Co-authored-by: David Leal * Update math/sum_of_binomial_coefficient.cpp Co-authored-by: David Leal * updating DIRECTORY.md * clang-format and clang-tidy fixes for e7ac2255 * Update math/sum_of_binomial_coefficient.cpp Co-authored-by: David Leal * Update sum_of_binomial_coefficient.cpp * Update math/sum_of_binomial_coefficient.cpp Co-authored-by: Ayaan Khan Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Ayaan Khan --- DIRECTORY.md | 1 + math/sum_of_binomial_coefficient.cpp | 67 ++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 math/sum_of_binomial_coefficient.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index cf6f68050..1bdffd780 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -156,6 +156,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 Binomial Coefficient](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sum_of_binomial_coefficient.cpp) * [Sum Of Digits](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/sum_of_digits.cpp) ## Numerical Methods diff --git a/math/sum_of_binomial_coefficient.cpp b/math/sum_of_binomial_coefficient.cpp new file mode 100644 index 000000000..e0dc826b8 --- /dev/null +++ b/math/sum_of_binomial_coefficient.cpp @@ -0,0 +1,67 @@ +/** + * @file + * @brief Algorithm to find sum of binomial coefficients of a given positive integer. + * @details Given a positive integer n, the task is to find the sum of binomial coefficient i.e + * nC0 + nC1 + nC2 + ... + nCn-1 + nCn + * By induction, we can prove that the sum is equal to 2^n + * @see more on https://en.wikipedia.org/wiki/Binomial_coefficient#Sums_of_the_binomial_coefficients + * @author [muskan0719](https://github.com/muskan0719) + */ +#include /// for std::cin and std::cout +#include /// for assert + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { + + /** + * Function to calculate sum of binomial coefficients + * @param n number + * @return Sum of binomial coefficients of number + */ + uint64_t binomialCoeffSum(uint64_t n) + { + // Calculating 2^n + return (1 << n); + } +} // namespace math + +/** + * Function for testing binomialCoeffSum function. + * test cases and assert statement. + * @returns `void` +*/ +static void test() +{ + int test_case_1 = math::binomialCoeffSum(2); + assert(test_case_1==4); + std::cout<<"Test_case_1 Passed!"< Date: Wed, 28 Oct 2020 22:51:49 +0530 Subject: [PATCH 60/69] feat: add wiggle sort algorithm (#1265) * create wiggle_sort.cpp * used array instead of vector * update wiggle_sort.cpp * update wiggle_sort.cpp * updating DIRECTORY.md * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * update wiggle_sort.cpp * removed swap function and used std::swap * update wiggle_sort.cpp * update wiggle_sort.cpp * Update wiggle_sort.cpp * Update wiggle_sort.cpp Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + sorting/wiggle_sort.cpp | 136 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 sorting/wiggle_sort.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 1bdffd780..be27c717f 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -266,6 +266,7 @@ * [Strand Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/strand_sort.cpp) * [Swap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/swap_sort.cpp) * [Tim Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/tim_sort.cpp) + * [Wiggle Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/wiggle_sort.cpp) ## Strings * [Brute Force String Searching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/strings/brute_force_string_searching.cpp) diff --git a/sorting/wiggle_sort.cpp b/sorting/wiggle_sort.cpp new file mode 100644 index 000000000..4d75a22bb --- /dev/null +++ b/sorting/wiggle_sort.cpp @@ -0,0 +1,136 @@ +/** + * \addtogroup sorting Sorting Algorithms + * @{ + * \file + * \brief [Wiggle Sort Algorithm] + * (https://leetcode.com/problems/wiggle-sort-ii/) Implementation + * + * \author [Roshan Kanwar](http://github.com/roshan0708) + * + * \details + * Wiggle Sort sorts the array into a wave like array. + * An array ‘arr[0..n-1]’ is sorted in wave form, + * if arr[0] >= arr[1] <= arr[2] >= arr[3] <= arr[4] >= ….. + * + * \example + * arr = [1,1,5,6,1,4], after wiggle sort arr will become equal to [1,1,6,1,5,4] + * arr = [2,8,9,1,7], after wiggle sort arr will become equal to [8,2,9,1,7] + */ + +#include /// for io operations +#include +#include +#include +#include + +/** + * @namespace sorting + * @brief Sorting algorithms + */ +namespace sorting { + /** + * @namespace wiggle_sort + * @brief Functions for [Wiggle Sort](https://leetcode.com/problems/wiggle-sort-ii/) algorithm + */ + namespace wiggle_sort { + + /** + * + * @brief Function used for sorting the elements in wave form. + * @details + * Checking whether the even indexed elements are greater than + * their adjacent odd elements. + * Traversing all even indexed elements of the input arr. + * If current element is smaller than the previous odd element, swap them. + * If current element is smaller than the next odd element, swap them. + * + * @param arr input array (unsorted elements) + * + */ + template // this allows to have vectors of ints, double, float, etc + std::vector wiggleSort(const std::vector& arr) { + + uint32_t size = arr.size(); + + std::vector out(arr); // create a copy of input vector. this way, the original input vector does not get modified. a sorted array is is returned. + + for(int i = 0; i < size ; i +=2) { + + if(i > 0 && out[i-1] > out[i]) { + std::swap(out[i],out[i-1]); //swapping the two values + } + + if(i < size - 1 && out[i] < out[i+1]) { + std::swap(out[i],out[i+1]); //swapping the two values + } + + } + + return out; //returns the sorted vector + + } + } // namespace wiggle_sort +} // namespace sorting + +/** + * + * @brief Utility function used for printing the elements. + * Prints elements of the array after they're sorted using wiggle sort algorithm. + * + * @param arr array containing the sorted elements + * + */ +template +static void displayElements(const std::vector &arr) { + + uint32_t size = arr.size(); + + std::cout << "Sorted elements are as follows: "; + + std::cout << "["; + + for(int i = 0 ; i < size ; i++ ) { + + std::cout << arr[i] ; + if(i != size - 1) { + std::cout << ", " ; + } + + } + + std::cout << "]"< data1(100); + for (auto &d: data1) { // generate random numbers between -5.0 and 4.99 + d = float(std::rand() % 1000 - 500) / 100.f; + } + + std::vector sorted = sorting::wiggle_sort::wiggleSort(data1); + + displayElements(sorted); + + for(uint32_t j = 0; j < data1.size(); j+=2) { + assert(data1[j] <= data1[j+1] && data1[j+1] >= data1[j+2]); // check the validation condition + } + + std::cout << "Test 1 passed\n"; + +} + +/** Driver Code */ +int main() { + test(); + return 0; +} + +/** @} */ From fee3a74e35b19be0bd24b584cff7e56a790fb1cf Mon Sep 17 00:00:00 2001 From: Shri Prakash Bajpai <68155959+Shri2206@users.noreply.github.com> Date: Fri, 30 Oct 2020 01:52:32 +0530 Subject: [PATCH 61/69] feat: Add modular_exponentiation.cpp (#1276) * Add modular_exponentiation * Delete modular_exponentiation * Add modular_exponentiation * Update and rename modular_exponentiation to modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * updating DIRECTORY.md * clang-format and clang-tidy fixes for 4b93d5a5 * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update modular_exponentiation.cpp * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * clang-format and clang-tidy fixes for 053aea0b * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update math/modular_exponentiation.cpp Co-authored-by: David Leal * Update modular_exponentiation.cpp Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + math/modular_exponentiation.cpp | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 math/modular_exponentiation.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index be27c717f..d2aa95ba9 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -146,6 +146,7 @@ * [Least Common Multiple](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/least_common_multiple.cpp) * [Magic Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/magic_number.cpp) * [Miller Rabin](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/miller_rabin.cpp) + * [Modular Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_exponentiation.cpp) * [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp) * [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp) * [Power For Huge Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/power_for_huge_numbers.cpp) diff --git a/math/modular_exponentiation.cpp b/math/modular_exponentiation.cpp new file mode 100644 index 000000000..01410860f --- /dev/null +++ b/math/modular_exponentiation.cpp @@ -0,0 +1,89 @@ +/** + * @file + * @brief C++ Program for Modular Exponentiation Iteratively. + * @details The task is to calculate the value of an integer a raised to an + * integer exponent b under modulo c. + * @note The time complexity of this approach is O(log b). + * + * Example: + * (4^3) % 5 (where ^ stands for exponentiation and % for modulo) + * (4*4*4) % 5 + * (4 % 5) * ( (4*4) % 5 ) + * 4 * (16 % 5) + * 4 * 1 + * 4 + * We can also verify the result as 4^3 is 64 and 64 modulo 5 is 4 + * + * @author [Shri2206](https://github.com/Shri2206) + */ +#include /// for assert +#include /// for io operations + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { +/** + * @brief This function calculates a raised to exponent b under modulo c using + * modular exponentiation. + * @param a integer base + * @param b unsigned integer exponent + * @param c integer modulo + * @return a raised to power b modulo c + */ +uint64_t power(uint64_t a, uint64_t b, uint64_t c) { + uint64_t ans = 1; /// Initialize the answer to be returned + a = a % c; /// Update a if it is more than or equal to c + if (a == 0) { + return 0; /// In case a is divisible by c; + } + while (b > 0) { + /// If b is odd, multiply a with answer + if (b & 1) { + ans = ((ans % c) * (a % c)) % c; + } + /// b must be even now + b = b >> 1; /// b = b/2 + a = ((a % c) * (a % c)) % c; + } + return ans; +} + +} // namespace math + +/** + * Function for testing power function. + * test cases and assert statement. + * @returns `void` + */ +static void test() { + uint32_t test_case_1 = math::power(2, 5, 13); + assert(test_case_1 == 6); + std::cout << "Test 1 Passed!" << std::endl; + + uint32_t test_case_2 = math::power(14, 7, 15); + assert(test_case_2 == 14); + std::cout << "Test 2 Passed!" << std::endl; + + uint64_t test_case_3 = math::power(8, 15, 41); + assert(test_case_3 == 32); + std::cout << "Test 3 Passed!" << std::endl; + + uint64_t test_case_4 = math::power(27, 2, 5); + assert(test_case_4 == 4); + std::cout << "Test 4 Passed!" << std::endl; + + uint16_t test_case_5 = math::power(7, 3, 6); + assert(test_case_5 == 1); + std::cout << "Test 5 Passed!" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the tests + return 0; +} From 0c223567067fa2fbac7c5cf2afeb743f4682b48d Mon Sep 17 00:00:00 2001 From: samruddha patil <45798222+sampatil578@users.noreply.github.com> Date: Fri, 30 Oct 2020 17:04:33 +0530 Subject: [PATCH 62/69] feat/fix: Improve numerical_methods/false_position.cpp (#1321) * Update false_position.cpp * Update false_position.cpp * Update false_position.cpp * Update false_position.cpp * Improve numerical_methods/false_position.cpp * Improve numerical_methods/false_position.cpp Co-authored-by: David Leal * Improve numerical_methods/false_position.cpp Co-authored-by: David Leal * Improve numerical_methods/false_position.cpp * Improve numerical_methods/false_position.cpp Co-authored-by: David Leal * Improve numerical_methods/false_position.cpp Co-authored-by: David Leal * Improve numerical_methods/false_position.cpp * Improve numerical_methods/false_position.cpp Co-authored-by: David Leal --- numerical_methods/false_position.cpp | 149 ++++++++++++++++++--------- 1 file changed, 102 insertions(+), 47 deletions(-) diff --git a/numerical_methods/false_position.cpp b/numerical_methods/false_position.cpp index aebd154bb..f4554aa2d 100644 --- a/numerical_methods/false_position.cpp +++ b/numerical_methods/false_position.cpp @@ -4,7 +4,12 @@ * method](https://en.wikipedia.org/wiki/Regula_falsi), also known as the Secant * method * - * Given two points \f$a\f$ and \f$b\f$ such that \f$f(a)<0\f$ and + * \details + * First, multiple intervals are selected with the interval gap provided. + * Separate recursive function called for every root. + * Roots are printed Separatelt. + * + * For an interval [a,b] \f$a\f$ and \f$b\f$ such that \f$f(a)<0\f$ and * \f$f(b)>0\f$, then the \f$(i+1)^\text{th}\f$ approximation is given by: \f[ * x_{i+1} = \frac{a_i\cdot f(b_i) - b_i\cdot f(a_i)}{f(b_i) - f(a_i)} * \f] @@ -13,62 +18,112 @@ * continued till a close enough approximation is achieved. * * \see newton_raphson_method.cpp, bisection_method.cpp + * + * \author Unknown author + * \author [Samruddha Patil](https://github.com/sampatil578) */ -#include -#include -#include -#include +#include /// for math operations +#include /// for io operations -#define EPSILON \ - 1e-6 // 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 +/** + * @namespace numerical_methods + * @brief Numerical methods */ -static double eq(double i) { - return (std::pow(i, 3) - (4 * i) - 9); // origial equation +namespace numerical_methods { +/** + * @namespace false_position + * @brief Functions for [False Position] + * (https://en.wikipedia.org/wiki/Regula_falsi) method. + */ +namespace false_position { +/** +* @brief This function gives the value of f(x) for given x. +* @param x value for which we have to find value of f(x). +* @return value of f(x) for given x. +*/ +static float eq(float x) { + return (x*x-x); // original equation } -/** get the sign of any given number */ -template -int sgn(T val) { - return (T(0) < val) - (val < T(0)); +/** +* @brief This function finds root of the equation in given interval i.e. (x1,x2). +* @param x1,x2 values for an interval in which root is present. + @param y1,y2 values of function at x1, x2 espectively. +* @return root of the equation in the given interval. +*/ +static float regula_falsi(float x1,float x2,float y1,float y2){ + float diff = x1-x2; + if(diff<0){ + diff= (-1)*diff; + } + if(diff<0.00001){ + if (y1<0) { + y1=-y1; + } + if (y2<0) { + y2=-y2; + } + if (y1 Date: Fri, 30 Oct 2020 21:59:24 +0530 Subject: [PATCH 63/69] feat: Add Runge Kutta Method (#1286) * Runge Kutta Method * statically cast and initialised * changes applied * changes applied * minor changes applied * Proper Documentation updated * Proper Documentation updated with suggestions * minor changes * added returns to rungeKutta function * made a small commit * updating DIRECTORY.md * made a small change at line 99 * made a small change at line 99 * Changes made as suggested * Changes updated * espace reverted * changes made in the documentation * minor additions * Update rungekutta.cpp * Update change * Changes removed * Minor updates * test functions added * Test functions outside namespace * non-static to static test function * used vector * changed function brief * made a single test function * made a single test function and made a slight change * changed numerical method namespace description * made changes in test function * made slight changes as suggested * Added a space * Added the new suggestions * updated in latex Co-authored-by: Rudra Prasad Das Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + numerical_methods/rungekutta.cpp | 135 +++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 numerical_methods/rungekutta.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index d2aa95ba9..a9894499a 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -176,6 +176,7 @@ * [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) + * [Rungekutta](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/rungekutta.cpp) * [Successive Approximation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/numerical_methods/successive_approximation.cpp) ## Operations On Datastructures diff --git a/numerical_methods/rungekutta.cpp b/numerical_methods/rungekutta.cpp new file mode 100644 index 000000000..41dca468f --- /dev/null +++ b/numerical_methods/rungekutta.cpp @@ -0,0 +1,135 @@ +/** + * @{ + * \file + * \brief [Runge Kutta fourth order](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods) method implementation + * + * \author [Rudra Prasad Das](http://github.com/rudra697) + * + * \details + * It solves the unknown value of y + * for a given value of x + * only first order differential equations + * can be solved + * \example + * it solves \frac{\mathrm{d} y}{\mathrm{d} x}= \frac{\left ( x-y \right )}{2} + * given x for given initial + * conditions + * There can be many such equations + */ +#include /// for io operations +#include /// for using the vector container +#include /// asserting the test functions + +/** + * @brief The change() function is used + * to return the updated iterative value corresponding + * to the given function + * @param x is the value corresponding to the x coordinate + * @param y is the value corresponding to the y coordinate + * @returns the computed function value at that call + */ +static double change(double x, double y) +{ + return ((x - y)/2.0); + +} + +/** + * @namespace numerical_methods + * @brief Numerical Methods + */ +namespace numerical_methods { +/** + * @namespace runge_kutta + * @brief Functions for [Runge Kutta fourth order](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods) method + */ +namespace runge_kutta { +/** + * @brief the Runge Kutta method finds the value of integration of a function in the given limits. + * the lower limit of integration as the initial value and the upper limit is the given x + * @param init_x is the value of initial x and is updated after each call + * @param init_y is the value of initial x and is updated after each call + * @param x is current iteration at which the function needs to be evaluated + * @param h is the step value + * @returns the value of y at thr required value of x from the initial conditions + */ +double rungeKutta(double init_x, const double &init_y, const double &x, const double &h) +{ + + // Count number of iterations + // using step size or + // step height h + + + // n calucates the number of iterations + // k1, k2, k3, k4 are the Runge Kutta variables + // used for calculation of y at each iteration + + auto n = static_cast((x - init_x) / h); + // used a vector container for the variables + std::vector k(4,0.0); + + + // Iterate for number of iterations + + double y = init_y; + for (int i=1; i<=n; ++i) + { + + // Apply Runge Kutta Formulas + // to find next value of y + k[0] = h*change(init_x, y); + k[1] = h*change(init_x + 0.5*h, y + 0.5*k[0]); + k[2] = h*change(init_x + 0.5*h, y + 0.5*k[1]); + k[3] = h*change(init_x + h, y + k[2]); + + + // Update next value of y + + y += (1.0/6.0)*(k[0] + 2*k[1] + 2*k[2] + k[3]); + + // Update next value of x + + init_x += h; + } + + return y; +} +} // namespace runge_kutta +} // namespace numerical_methods + +/** + * @brief Tests to check algorithm implementation. + * @returns void + */ + static void test() + { + std::cout << "The Runge Kutta function will be tested on the basis of precomputed values\n"; + + std::cout << "Test 1...." << "\n"; + double valfirst=numerical_methods::runge_kutta::rungeKutta(2,3,4,0.2); // Tests the function with pre calculated values + assert(valfirst==3.10363932323749570); + std::cout << "Passed Test 1\n"; + + std::cout << "Test 2...." << "\n"; + double valsec=numerical_methods::runge_kutta::rungeKutta(1,2,5,0.1); // The value of step changed + assert(valsec==3.40600589380261409); + std::cout << "Passed Test 2\n"; + + std::cout << "Test 3...." << "\n"; + double valthird=numerical_methods::runge_kutta::rungeKutta(-1,3,4,0.1); // Tested with negative value + assert(valthird==2.49251005860244268); + std::cout << "Passed Test 3\n"; + } + + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() +{ + + test(); // Execute the tests + return 0; +} From c9d298fec63a12252fa643ae7e66941267c07389 Mon Sep 17 00:00:00 2001 From: Sarthak Sahu <53469278+SarthakSahu1009@users.noreply.github.com> Date: Fri, 30 Oct 2020 23:23:02 +0530 Subject: [PATCH 64/69] feat: add fibonacci_sum.cpp (#1343) * Johnson's Algorithm added * Update Johnson's algorithm.cpp @Panquesito7 plzz review * Update Johnson's algorithm.cpp * remove johnson'algo * add fibo_sum.cpp * updating DIRECTORY.md * Update math/fibonacci_sum.cpp Co-authored-by: David Leal * Update math/fibonacci_sum.cpp Co-authored-by: David Leal * Update math/fibonacci_sum.cpp Co-authored-by: David Leal * Update math/fibonacci_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update math/fibonacci_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update math/fibonacci_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * Update math/fibonacci_sum.cpp Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> * clang-format and clang-tidy fixes for a054b759 Co-authored-by: SarthakSahu1009 Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal Co-authored-by: Krishna Vedala <7001608+kvedala@users.noreply.github.com> --- DIRECTORY.md | 1 + math/fibonacci_sum.cpp | 138 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 math/fibonacci_sum.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index a9894499a..210f30b4b 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -137,6 +137,7 @@ * [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp) * [Fibonacci Fast](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci_fast.cpp) * [Fibonacci Large](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci_large.cpp) + * [Fibonacci Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci_sum.cpp) * [Gcd Iterative Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_iterative_euclidean.cpp) * [Gcd Of N Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_of_n_numbers.cpp) * [Gcd Recursive Euclidean](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/gcd_recursive_euclidean.cpp) diff --git a/math/fibonacci_sum.cpp b/math/fibonacci_sum.cpp new file mode 100644 index 000000000..abe85023b --- /dev/null +++ b/math/fibonacci_sum.cpp @@ -0,0 +1,138 @@ +/** + * @file + * @brief An algorithm to calculate the sum of [Fibonacci + * Sequence](https://en.wikipedia.org/wiki/Fibonacci_number): \f$\mathrm{F}(n) + + * \mathrm{F}(n+1) + .. + \mathrm{F}(m)\f$ + * @details An algorithm to calculate the sum of Fibonacci Sequence: + * \f$\mathrm{F}(n) + \mathrm{F}(n+1) + .. + \mathrm{F}(m)\f$ where + * \f$\mathrm{F}(i)\f$ denotes the i-th Fibonacci Number . Note that F(0) = 0 + * and F(1) = 1. The value of the sum is calculated using matrix exponentiation. + * Reference source: + * https://stackoverflow.com/questions/4357223/finding-the-sum-of-fibonacci-numbers + * @author [Sarthak Sahu](https://github.com/SarthakSahu1009) + */ + +#include /// for assert +#include /// for std::cin and std::cout +#include /// for std::vector + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { + /** + * @namespace fibonacci_sum + * @brief Functions for the sum of the Fibonacci Sequence: \f$\mathrm{F}(n) + + * \mathrm{F}(n+1) + .. + \mathrm{F}(m)\f$ + */ + namespace fibonacci_sum { + using matrix = std::vector >; + + /** + * Function to multiply two matrices + * @param T matrix 1 + * @param A martix 2 + * @returns resultant matrix + */ + math::fibonacci_sum::matrix multiply(const math::fibonacci_sum::matrix &T, const math::fibonacci_sum::matrix &A) { + math::fibonacci_sum::matrix result(2, std::vector(2, 0)); + + // multiplying matrices + result[0][0] = T[0][0]*A[0][0] + T[0][1]*A[1][0]; + result[0][1] = T[0][0]*A[0][1] + T[0][1]*A[1][1]; + result[1][0] = T[1][0]*A[0][0] + T[1][1]*A[1][0]; + result[1][1] = T[1][0]*A[0][1] + T[1][1]*A[1][1]; + + return result; + } + + /** + * Function to compute A^n where A is a matrix. + * @param T matrix + * @param ex power + * @returns resultant matrix + */ + math::fibonacci_sum::matrix power(math::fibonacci_sum::matrix T, uint64_t ex) { + math::fibonacci_sum::matrix A{{1, 1}, {1, 0}}; + if (ex == 0 || ex == 1) { + return T; + } + + T = power(T, ex / 2); + T = multiply(T, T); + if (ex & 1) { + T = multiply(T, A); + } + return T; + } + + /** + * Function to compute sum of fibonacci sequence from 0 to n. + * @param n number + * @returns uint64_t ans, the sum of sequence + */ + uint64_t result(uint64_t n) { + math::fibonacci_sum::matrix T{{1, 1}, {1, 0}}; + T = power(T, n); + uint64_t ans = T[0][1]; + ans = (ans - 1); + return ans; + } + + /** + * Function to compute sum of fibonacci sequence from n to m. + * @param n start of sequence + * @param m end of sequence + * @returns uint64_t the sum of sequence + */ + uint64_t fiboSum(uint64_t n, uint64_t m) { + return (result(m + 2) - result(n + 1)); + } + } // namespace fibonacci_sum +} // namespace math + +/** + * Function for testing fiboSum function. + * test cases and assert statement. + * @returns `void` + */ +static void test() { + uint64_t n = 0, m = 3; + uint64_t test_1 = math::fibonacci_sum::fiboSum(n, m); + assert(test_1 == 4); + std::cout << "Passed Test 1!" << std::endl; + + n = 3; + m = 5; + uint64_t test_2 = math::fibonacci_sum::fiboSum(n, m); + assert(test_2 == 10); + std::cout << "Passed Test 2!" << std::endl; + + n = 5; + m = 7; + uint64_t test_3 = math::fibonacci_sum::fiboSum(n, m); + assert(test_3 == 26); + std::cout << "Passed Test 3!" << std::endl; + + n = 7; + m = 10; + uint64_t test_4 = math::fibonacci_sum::fiboSum(n, m); + assert(test_4 == 123); + std::cout << "Passed Test 4!" << std::endl; + + n = 9; + m = 12; + uint64_t test_5 = math::fibonacci_sum::fiboSum(n, m); + assert(test_5 == 322); + std::cout << "Passed Test 5!" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the tests + return 0; +} From 7b92e8d6252da483cd3669fbaace5bb4f4cc9173 Mon Sep 17 00:00:00 2001 From: webdesignbydivyansh <62607594+webdesignbydivyansh@users.noreply.github.com> Date: Sat, 31 Oct 2020 11:42:24 +0530 Subject: [PATCH 65/69] feat: Coin Change Problem (#1378) * palindrome no a program to check if a number is palindrome or not * updated palindrome.cpp * updated palindrome.cpp missing equal to operator at line no 16 * flatten_a_binary_seach_tree This program flattens a binary search tree or in simple words, converts it into linked list in sorted form * a prog to convert bst into linked list A code that is used to convert a binary search tree into linked list * created merge k sorted arrays this program displays all the elements from the different arrays(sorted) into 1 single array(sorted). * updated braces in some parts * included braces in line no 58 * included braces in line 58 and 60 * created trap_rainwater.cpp A program to calculate the maximum amount of water that can be stored between buildings. * deleted rainwater harvesting * deleted palindrome * deleted merge k sorted arrays * deleted binary search tree to linked list * deleted binary search tree to linked list * created min_coins_topdown.cpp This is another version of coins exchange problem solved using top down approach * updated the code please take a look at it * final changes * updated my code * updating DIRECTORY.md * changed int64_t to int8_t and int16_t * edited line 3 * changed line 3 * edited line 3 & removed line 18 * added extra space Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + dynamic_programming/coin_change_topdown.cpp | 89 +++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 dynamic_programming/coin_change_topdown.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 210f30b4b..3930e67fd 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -55,6 +55,7 @@ * [Bellman Ford](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/bellman_ford.cpp) * [Catalan Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/catalan_numbers.cpp) * [Coin Change](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/coin_change.cpp) + * [Coin Change Topdown](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/coin_change_topdown.cpp) * [Cut Rod](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/cut_rod.cpp) * [Edit Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/edit_distance.cpp) * [Egg Dropping Puzzle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/dynamic_programming/egg_dropping_puzzle.cpp) diff --git a/dynamic_programming/coin_change_topdown.cpp b/dynamic_programming/coin_change_topdown.cpp new file mode 100644 index 000000000..e8112b089 --- /dev/null +++ b/dynamic_programming/coin_change_topdown.cpp @@ -0,0 +1,89 @@ +/** + * @file + * @brief [Minimum coins](https://leetcode.com/problems/coin-change/) change problem is a problem used to find the minimum number of + * coins required to completely reach a target amount. + * + * @details + * This problem can be solved using 2 methods: + * 1. Top down approach + * 2. Bottom up appraoch + * Top down approach involves a vector with all elements initialised to 0. + * It is based on optimal substructure and overlapping subproblems. + * Overall time complexity of coin change problem is O(n*t) + * For example: example 1:- + * Coins: {1,7,10} + * Target:15 + * Therfore minimum number of coins required = 3 of denomination 1,7 and 7. + * @author [Divyansh Kushwaha](https://github.com/webdesignbydivyansh) + */ + +#include // for io operations +#include // for std::vector +#include // for assert +#include // for INT_MAX + +/** + * @namespace dynamic_programming + * @brief Dynamic Programming algorithm + */ +namespace dynamic_programming { +/** + * @namespace mincoins_topdown + * @brief Functions for [minimum coin exchange](https://leetcode.com/problems/coin-change/) problem + */ +namespace mincoins_topdown { + /** + * @brief This implementation is for finding minimum number of coins . + * @param T template-type to use any kind of value + * @param n amount to be reached + * @param coins vector of coins + * @param t deontes the number of coins + * @param dp initilised to 0 + * @returns minimum number of coins + */ + template + int64_t mincoins(const T &n, const std::vector &coins, const int16_t &t, std::vector dp){ + if(n==0){ + return 0; + } + if(dp[n]!=0){ + return dp[n]; + } + int ans=INT_MAX; //variable to store min coins + for(int i=0;i=0){ //if after subtracting the current denomination is it greater than 0 or not + int sub=mincoins(n-coins[i],coins,t,dp); + ans=std::min(ans,sub+1); + } + } + dp[n]=ans; + return dp[n]; //returns minimum number of coins + } + +} // namespace mincoins_topdown +} // namespace dynamic_programming + +/** + * @brief Test implementations + * @returns void + */ +static void test() { + // example 1: number of coins=3 and minimum coins required=3(7,7,1) + const int64_t n1 = 15; + const int8_t t1=3, a1=0; + std::cout << "\nTest 1..."; + std::vector arr1 {1,7,10}; + std::vector dp1 (n1+1); + fill(dp1.begin(),dp1.end(),a1); + assert(dynamic_programming::mincoins_topdown::mincoins(n1, arr1, t1, dp1)==3); + std::cout << "Passed\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the test + return 0; +} From fb5e00f5fba9eac208777fa862d06c1197bac8ae Mon Sep 17 00:00:00 2001 From: Akanksha-Gupta920 <69674604+Akanksha-Gupta920@users.noreply.github.com> Date: Sat, 31 Oct 2020 12:07:43 +0530 Subject: [PATCH 66/69] feat: Add Gram Schmidt Orthogonalisation (#1339) * Add Gram Schmidt Orthogonalisation * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp After removing '&' while passing the parameters. The changes in array B are not reflected. * Update gram_schmidt.cpp * Update gram_schmidt.cpp All the changes have been done and changes in B are also reflected. * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Fix spelling of brief * updating DIRECTORY.md * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update gram_schmidt.cpp * Update linear_algebra/gram_schmidt.cpp * Update linear_algebra/gram_schmidt.cpp * Update linear_algebra/gram_schmidt.cpp Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Ayaan Khan --- DIRECTORY.md | 3 + linear_algebra/gram_schmidt.cpp | 251 ++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 linear_algebra/gram_schmidt.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 3930e67fd..63964913e 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -115,6 +115,9 @@ * [Linear Probing Hash Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/linear_probing_hash_table.cpp) * [Quadratic Probing Hash Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/hashing/quadratic_probing_hash_table.cpp) +## Linear Algebra + * [Gram Schmidt](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/linear_algebra/gram_schmidt.cpp) + ## Machine Learning * [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) diff --git a/linear_algebra/gram_schmidt.cpp b/linear_algebra/gram_schmidt.cpp new file mode 100644 index 000000000..09ebc8d7c --- /dev/null +++ b/linear_algebra/gram_schmidt.cpp @@ -0,0 +1,251 @@ +/** + * @file + * @brief [Gram Schmidt Orthogonalisation Process](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process) + * + * @details + * Takes the input of Linearly Independent Vectors, + * returns vectors orthogonal to each other. + * + * ### Algorithm + * Take the first vector of given LI vectors as first vector of Orthogonal vectors. + * Take projection of second input vector on the first vector of Orthogonal vector + * and subtract it from the 2nd LI vector. + * Take projection of third vector on the second vector of Othogonal vectors and subtract it from the 3rd LI vector. + * Keep repeating the above process until all the vectors in the given input array are exhausted. + * + * For Example: + * In R2, + * Input LI Vectors={(3,1),(2,2)} + * then Orthogonal Vectors= {(3, 1),(-0.4, 1.2)} + * + * Have defined maximum dimension of vectors to be 10 and number of vectors + * taken is 20. + * Please do not give linearly dependent vectors + * + * + * @author [Akanksha Gupta](https://github.com/Akanksha-Gupta920) + */ + +#include /// for io operations +#include /// for assert +#include /// for fabs +#include /// for std::array + +/** + * @namespace linear_algebra + * @brief Linear Algebra algorithms + */ +namespace linear_algebra { +/** + * @namespace gram_schmidt + * @brief Functions for [Gram Schmidt Orthogonalisation Process](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process) + */ +namespace gram_schmidt { +/** + * Dot product function. + * Takes 2 vectors along with their dimension as input and returns the dot product. + * @param x vector 1 + * @param y vector 2 + * @param c dimension of the vectors + * + * @returns sum + */ +double dot_product(const std::array& x, const std::array& y, const int& c) { + double sum = 0; + for (int i = 0; i < c; ++i) { + sum += x[i] * y[i]; + } + return sum; +} + +/** + * Projection Function + * Takes input of 2 vectors along with their dimension and evaluates their projection in temp + * + * @param x Vector 1 + * @param y Vector 2 + * @param c dimension of each vector + * + * @returns factor + */ +double projection(const std::array& x,const std::array& y, + const int& c) { + double dot = dot_product(x, y, c); ///The dot product of two vectors is taken + double anorm = dot_product(y, y, c); ///The norm of the second vector is taken. + double factor = dot / anorm; ///multiply that factor with every element in a 3rd vector, whose initial values are same as the 2nd vector. + return factor; +} + +/** + * Function to print the orthogonalised vector + * + * @param r number of vectors + * @param c dimenaion of vectors + * @param B stores orthogonalised vectors + * + * @returns void + */ +void display(const int& r,const int& c,const std::array, 20>& B) { + for (int i = 0; i < r; ++i) { + std::cout << "Vector " << i + 1 << ": "; + for (int j = 0; j < c; ++j) { + std::cout << B[i][j] << " "; + } + std::cout << '\n'; + } +} + +/** + * Function for the process of Gram Schimdt Process + * @param r number of vectors + * @param c dimension of vectors + * @param A stores input of given LI vectors + * @param B stores orthogonalised vectors + * + * @returns void + */ +void gram_schmidt(int r,const int& c,const std::array, 20>& A, + std::array, 20> B) { + if (c < r) { /// we check whether appropriate dimensions are given or not. + std::cout + << "Dimension of vector is less than number of vector, hence \n first " + << c << " vectors are orthogonalised\n"; + r = c; + } + + int k = 1; + + while (k <= r) { + if (k == 1) { + for (int j = 0; j < c; j++) B[0][j] = A[0][j]; ///First vector is copied as it is. + } + + else { + std::array all_projection{}; ///array to store projections + for (int i = 0; i < c; ++i) { + all_projection[i] = 0; ///First initialised to zero + } + + int l = 1; + while (l < k) { + std::array temp{}; ///to store previous projected array + double factor; ///to store the factor by which the previous array will change + factor = projection(A[k - 1], B[l - 1], c); + for(int i = 0; i < c; ++i) + temp[i] = B[l - 1][i] * factor; ///projected array created + for (int j = 0; j < c; ++j) { + all_projection[j] = all_projection[j] + temp[j]; ///we take the projection with all the previous vector and add them. + } + l++; + } + for (int i = 0; i < c; ++i) { + B[k - 1][i] = A[k - 1][i] - all_projection[i]; ///subtract total projection vector from the input vector + } + } + k++; + } + display(r, c, B); //for displaying orthogoanlised vectors +} +} // namespace gram_schmidt +} // namespace linear_algebra +/** + * Test Function. Process has been tested for 3 Sample Inputs + * @returns void + */ +static void test() { + std::array, 20> a1 = { + {{1, 0, 1, 0}, {1, 1, 1, 1}, {0, 1, 2, 1}}}; + std::array, 20> b1 = {{0}}; + double dot1 = 0; + linear_algebra::gram_schmidt::gram_schmidt(3, 4, a1, b1); + int flag = 1; + for (int i = 0; i < 2; ++i) + for (int j = i + 1; j < 3; ++j) { + dot1 = fabs(linear_algebra::gram_schmidt::dot_product(b1[i], b1[j], 4)); + if (dot1 > 0.1) { + flag = 0; + break; + } + } + if (flag == 0) std::cout << "Vectors are linearly dependent\n"; + assert(flag == 1); + std::cout << "Passed Test Case 1\n "; + + std::array, 20> a2 = {{{3, 1}, {2, 2}}}; + std::array, 20> b2 = {{0}}; + double dot2 = 0; + linear_algebra::gram_schmidt::gram_schmidt(2, 2, a2, b2); + flag = 1; + for (int i = 0; i < 1; ++i) + for (int j = i + 1; j < 2; ++j) { + dot2 = fabs(linear_algebra::gram_schmidt::dot_product(b2[i], b2[j], 2)); + if (dot2 > 0.1) { + flag = 0; + break; + } + } + if (flag == 0) std::cout << "Vectors are linearly dependent\n"; + assert(flag == 1); + std::cout << "Passed Test Case 2\n"; + + std::array, 20> a3 = {{{1, 2, 2}, {-4, 3, 2}}}; + std::array, 20> b3 = {{0}}; + double dot3 = 0; + linear_algebra::gram_schmidt::gram_schmidt(2, 3, a3, b3); + flag = 1; + for (int i = 0; i < 1; ++i) + for (int j = i + 1; j < 2; ++j) { + dot3 = fabs(linear_algebra::gram_schmidt::dot_product(b3[i], b3[j], 3)); + if (dot3 > 0.1) { + flag = 0; + break; + } + } + if (flag == 0) std::cout << "Vectors are linearly dependent\n" ; + assert(flag == 1); + std::cout << "Passed Test Case 3\n"; +} + +/** + * @brief Main Function + * @return 0 on exit + */ +int main() { + int r=0, c=0; + test(); // perform self tests + std::cout << "Enter the dimension of your vectors\n"; + std::cin >> c; + std::cout << "Enter the number of vectors you will enter\n"; + std::cin >> r; + + std::array, 20> + A{}; ///a 2-D array for storing all vectors + std::array, 20> B = { + {0}}; /// a 2-D array for storing orthogonalised vectors + /// storing vectors in array A + for (int i = 0; i < r; ++i) { + std::cout << "Enter vector " << i + 1 <<'\n'; ///Input of vectors is taken + for (int j = 0; j < c; ++j) { + std::cout << "Value " << j + 1 << "th of vector: "; + std::cin >> A[i][j]; + } + std::cout <<'\n'; + } + + linear_algebra::gram_schmidt::gram_schmidt(r, c, A, B); + + double dot = 0; + int flag = 1; ///To check whether vectors are orthogonal or not + for (int i = 0; i < r - 1; ++i) { + for (int j = i + 1; j < r; ++j) { + dot = fabs(linear_algebra::gram_schmidt::dot_product(B[i], B[j], c)); + if (dot > 0.1) /// take make the process numerically stable, upper bound for the dot product take 0.1 + { + flag = 0; + break; + } + } + } + if (flag == 0) std::cout << "Vectors are linearly dependent\n"; + return 0; +} From 5bd438066cabb0fa690cd059767110d17f66dc80 Mon Sep 17 00:00:00 2001 From: Suyash Jaiswal Date: Tue, 3 Nov 2020 02:10:53 +0530 Subject: [PATCH 67/69] feat: Add sorting/radix_sort2.cpp (#1268) * radix_sort2.cpp * Performed changes in radix_sort2.cpp * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * updating DIRECTORY.md * clang-format and clang-tidy fixes for e01027fa * update radix_sort2.cpp * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * Update sorting/radix_sort2.cpp Co-authored-by: David Leal * update radix_sort2.cpp * update radix_sort2.cpp * update radix_sort2.cpp * update radix_sort2.cpp * update radix_sort2.cpp * update radix_sort2.cpp * update radix_sort2.cpp Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + sorting/radix_sort2.cpp | 118 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 sorting/radix_sort2.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 63964913e..955518751 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -266,6 +266,7 @@ * [Quick Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/quick_sort.cpp) * [Quick Sort 3](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/quick_sort_3.cpp) * [Radix Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/radix_sort.cpp) + * [Radix Sort2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/radix_sort2.cpp) * [Selection Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/selection_sort.cpp) * [Shell Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/shell_sort.cpp) * [Shell Sort2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/shell_sort2.cpp) diff --git a/sorting/radix_sort2.cpp b/sorting/radix_sort2.cpp new file mode 100644 index 000000000..f1e8be836 --- /dev/null +++ b/sorting/radix_sort2.cpp @@ -0,0 +1,118 @@ +/** + * @file + * @brief Algorithm of [Radix sort](https://en.wikipedia.org/wiki/Radix_sort) + * @author [Suyash Jaiswal](https://github.com/Suyashjaiswal) + * @details + * Sort the vector of unsigned integers using radix sort i.e. sorting digit by digit + * using [Counting Sort](https://en.wikipedia.org/wiki/Counting_sort) as subroutine. + * Running time of radix sort is O(d*(n+b)) where b is the base for representing + * numbers and d in the max digits in input integers and n is number of unsigned integers. + * consider example for n = 5, aray elements = 432,234,143,332,123 + * sorting digit by digit + * sorting according to + * 1) 1st digit place + * => 432, 332, 143, 123, 234 + * + * 2) 2nd digit place + * => 123, 432, 332, 234, 143 + * + * 3) 3rd digit place + * => 123, 143, 234, 332, 432 + * + * using count sort at each step, which is stable. + * stable => already sorted according to previous digits. +*/ + +/// header files +#include /// for io operations +#include /// for std::vector +#include /// for collection of functions +#include /// for a macro called assert which can be used to verify assumptions + +/** + * @namespace sorting + * @brief Sorting algorithms + */ +namespace sorting { + /** + * @namespace radix_sort + * @brief Functions for [Radix sort](https://en.wikipedia.org/wiki/Radix_sort) + * algorithm + */ + namespace radix_sort { + /** + * @brief Function to sort vector according to current digit using stable + * sorting. + * @param cur_digit - sort according to the cur_digit + * @param ar - vector to be sorted + * @returns std::vector sorted till ith digit + */ + std::vector step_ith(uint16_t cur_digit, const std::vector& ar) { // sorting according to current digit. + int n = ar.size(); + std::vector position(10, 0); + for (int i = 0; i < n; ++i) { + position[(ar[i] / cur_digit) % + 10]++; // counting frequency of 0-9 at cur_digit. + } + int cur = 0; + for (int i = 0; i < 10; ++i) { + int a = position[i]; + position[i] = cur; // assingning starting position of 0-9. + cur += a; + } + std::vector temp(n); + for (int i = 0; i < n; ++i) { + temp[position[(ar[i] / cur_digit) % 10]] = + ar[i]; // storing ar[i] in ar[i]'s cur_digit expected position of + // this step. + position[(ar[i] / cur_digit) % + 10]++; // incrementing ar[i]'s cur_digit position by 1, as + // current place used by ar[i]. + } + return temp; + } + /** + * @brief Function to sort vector digit by digit. + * @param ar - vector to be sorted + * @returns sorted vector + */ + std::vector radix(const std::vector& ar) { + uint64_t max_ele = *max_element(ar.begin(), ar.end()); // returns the max element. + std::vector temp = ar; + for (int i = 1; max_ele / i > 0; + i *= 10) { // loop breaks when i > max_ele because no further digits + // left to makes changes in aray. + temp = step_ith(i,temp); + } + for (uint64_t i : temp) { + std::cout << i << " "; + } + std::cout << "\n"; + return temp; + } + } // namespace radix_sort +} // namespace sorting + +/** + * @brief Function to test the above algorithm + * @returns none + */ +static void tests() { + /// Test 1 + std::vector ar1 = {432, 234, 143, 332, 123}; + ar1 = sorting::radix_sort::radix(ar1); + assert(std::is_sorted(ar1.begin(), ar1.end())); + /// Test 2 + std::vector ar2 = {213, 3214, 123, 111, 112, 142, + 133, 132, 32, 12, 113}; + ar2 = sorting::radix_sort::radix(ar2); + assert(std::is_sorted(ar2.begin(), ar2.end())); +} +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + tests(); // execute the tests + return 0; +} From b4b182a61dbba7080200ecfedbe4dcb371b8e0d7 Mon Sep 17 00:00:00 2001 From: Farbod Ahmadian Date: Sat, 14 Nov 2020 05:31:11 +0330 Subject: [PATCH 68/69] [fix/docs]: Memory leakage caused by using `new` operator & refactoring/documentation (#1428) * fix: Fixed memory leak bug by using 'std::vector' instead of 'new' * Small refactoring * Small refactoring * Fix Code Formatter test failed * Code refactored based on PR review * Added return 0 based on PR review * docs: Added documentation for linear queue using array implementation * docs: Updated based on PR review * docs: Second update based on PR review * docs: Updated based on PR review * Change max_size data type * Use std::array instead of std::vector --- data_structures/queue_using_array.cpp | 117 ++++++++++++++++++-------- 1 file changed, 81 insertions(+), 36 deletions(-) diff --git a/data_structures/queue_using_array.cpp b/data_structures/queue_using_array.cpp index a887c99fc..4cda860ca 100644 --- a/data_structures/queue_using_array.cpp +++ b/data_structures/queue_using_array.cpp @@ -1,77 +1,120 @@ -/* - Write a program to implement Linear Queue using array. +/** + * @file + * @brief Implementation of Linear [Queue using array] + * (https://www.geeksforgeeks.org/array-implementation-of-queue-simple/). + * @details + * The Linear Queue is a data structure used for holding a sequence of + * values, which can be added to the end line (enqueue), removed from + * head of line (dequeue) and displayed. + * ### Algorithm + * Values can be added by increasing the `rear` variable by 1 (which points to + * the end of the array), then assigning new value to `rear`'s element of the array. + * + * Values can be removed by increasing the `front` variable by 1 (which points to + * the first of the array), so it cannot reached any more. + * + * @author [Pooja](https://github.com/pooja-git11) + * @author [Farbod Ahmadian](https://github.com/farbodahm) + */ +#include /// for io operations +#include /// for std::array - Functions to implement - Enqueue (Insertion) - Dequeue (Deletion) +constexpr uint16_t max_size{10}; ///< Maximum size of the queue -*/ -#include +/** + * @namespace data_structures + * @brief Algorithms with data structures + */ +namespace data_structures { -#define MAXSIZE 10 +/** + * @namespace queue_using_array + * @brief Functions for [Queue using Array] + * (https://www.geeksforgeeks.org/array-implementation-of-queue-simple/) implementation. + */ +namespace queue_using_array { +/** + * @brief Queue_Array class containing the main data and also index of head and tail of the array. + */ class Queue_Array { - int front; - int rear; - int size; - - public: - Queue_Array() { - front = -1; - rear = -1; - size = MAXSIZE; - } - int *arr = new int[size]; - void enqueue(int); - int dequeue(); - void display(); +public: + void enqueue(const int16_t&); ///< Add element to the first of the queue + int dequeue(); ///< Delete element from back of the queue + void display() const; ///< Show all saved data +private: + int8_t front{-1}; ///< Index of head of the array + int8_t rear{-1}; ///< Index of tail of the array + std::array arr; ///< All stored data }; -void Queue_Array::enqueue(int ele) { - if (rear == size - 1) { +/** + * @brief Adds new element to the end of the queue + * @param ele to be added to the end of the queue + */ +void Queue_Array::enqueue(const int16_t& ele ) { + if (rear == arr.size() - 1) { std::cout << "\nStack is full"; } else if (front == -1 && rear == -1) { - front = rear = 0; + front = 0; + rear = 0; arr[rear] = ele; - } else if (rear < size) { - rear++; + } else if (rear < arr.size()) { + ++rear; arr[rear] = ele; } } +/** + * @brief Remove element that is located at the first of the queue + * @returns data that is deleted if queue is not empty + */ int Queue_Array::dequeue() { - int d; + int8_t d{0}; if (front == -1) { std::cout << "\nstack is empty "; return 0; } else if (front == rear) { - d = arr[front]; + d = arr.at(front); front = rear = -1; } else { - d = arr[front++]; + d = arr.at(front++); } return d; } -void Queue_Array::display() { +/** + * @brief Utility function to show all elements in the queue + */ +void Queue_Array::display() const { if (front == -1) { std::cout << "\nStack is empty"; } else { - for (int i = front; i <= rear; i++) std::cout << arr[i] << " "; + for (int16_t i{front}; i <= rear; ++i) std::cout << arr.at(i) << " "; } } -int main() { - int op, data; +} // namespace queue_using_array +} // namespace data_structures - Queue_Array ob; + +/** + * @brief Main function + * @details + * Allows the user to add and delete values from the queue. + * Also allows user to display values in the queue. + * @returns 0 on exit + */ +int main() { + int op{0}, data{0}; + data_structures::queue_using_array::Queue_Array ob; std::cout << "\n1. enqueue(Insertion) "; std::cout << "\n2. dequeue(Deletion)"; std::cout << "\n3. Display"; std::cout << "\n4. Exit"; - while (1) { + while (true) { std::cout << "\nEnter your choice "; std::cin >> op; if (op == 1) { @@ -89,4 +132,6 @@ int main() { std::cout << "\nWrong choice "; } } + + return 0; } From a283f2a96f2fc62b887272ceddaee7433f4aaa22 Mon Sep 17 00:00:00 2001 From: Taj Date: Mon, 16 Nov 2020 19:39:52 +0000 Subject: [PATCH 69/69] Feat: added n_choose_r combinatorics algorithm (#1429) * feat: added n_choose_r combinatorial algorithm * fix: some type casting issue * fix: MathJax documentation fix * fix: MathJax documentation fix * fix: MathJax notation fix * fix: header comments Co-authored-by: David Leal * fix: suggested changes to documentation * updating DIRECTORY.md * fix: suggested changes * fix: suggested changes * fix: namespace closing comment Co-authored-by: David Leal * fix: removing a blank line Co-authored-by: David Leal * fix: link issue * fix: removed link * fix: removed newline Co-authored-by: David Leal Co-authored-by: David Leal Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + math/n_choose_r.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 math/n_choose_r.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 955518751..dcf0a6568 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -153,6 +153,7 @@ * [Miller Rabin](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/miller_rabin.cpp) * [Modular Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_exponentiation.cpp) * [Modular Inverse Fermat Little Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_inverse_fermat_little_theorem.cpp) + * [N Choose R](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/n_choose_r.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) * [Prime Factorization](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/prime_factorization.cpp) diff --git a/math/n_choose_r.cpp b/math/n_choose_r.cpp new file mode 100644 index 000000000..fa3287abc --- /dev/null +++ b/math/n_choose_r.cpp @@ -0,0 +1,81 @@ +/** + * @file + * @brief [Combinations](https://en.wikipedia.org/wiki/Combination) n choose r function implementation + * @details + * A very basic and efficient method of calculating + * choosing r from n different choices. + * \f$ \binom{n}{r} = \frac{n!}{r! (n-r)!} \f$ + * + * @author [Tajmeet Singh](https://github.com/tjgurwara99) + */ + +#include /// for io operations +#include /// for assert + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { +/** + * @brief This is the function implementation of \f$ \binom{n}{r} \f$ + * @details + * We are calculating the ans with iterations + * instead of calculating three different factorials. + * Also, we are using the fact that + * \f$ \frac{n!}{r! (n-r)!} = \frac{(n - r + 1) \times \cdots \times n}{1 \times \cdots \times r} \f$ + * @tparam T Only for integer types such as long, int_64 etc + * @param n \f$ n \f$ in \f$ \binom{n}{r} \f$ + * @param r \f$ r \f$ in \f$ \binom{n}{r} \f$ + * @returns ans \f$ \binom{n}{r} \f$ + */ +template +T n_choose_r(T n, T r) { + if(r > n / 2) + r = n - r; // Because of the fact that nCr(n, r) == nCr(n, n - r) + T ans = 1; + for(int i = 1; i <= r; i++) { + ans *= n - r + i; + ans /= i; + } + return ans; +} +} // namespace math + +/** + * @brief Test implementations + * @returns void + */ +static void test() { + // First test on 5 choose 2 + uint8_t t = math::n_choose_r(5, 2); + assert(((void)"10 is the answer but function says otherwise.\n", + t == 10)); + std::cout << "First test passes." << std::endl; + // Second test on 5 choose 3 + t = math::n_choose_r(5, 3); + assert(((void)"10 is the answer but the function says otherwise.\n", + t == 10)); + std::cout << "Second test passes." << std::endl; + // Third test on 3 choose 2 + t = math::n_choose_r(3, 2); + assert(((void)"3 is the answer but the function says otherwise.\n", + t == 3)); + std::cout << "Third test passes." << std::endl; + // Fourth test on 10 choose 4 + t = math::n_choose_r(10, 4); + assert(((void)"210 is the answer but the function says otherwise.\n", + t == 210)); + std::cout << "Fourth test passes." << std::endl; +} + +/** + * @brief Main function + * @param argc commandline argument count (ignored) + * @param argv commandline array of arguments (ignored) + * @returns 0 on exit + */ +int main(int argc, char *argv[]) { + test(); // executing tests + return 0; +}