diff --git a/.github/workflows/cpplint_modified_files.yml b/.github/workflows/cpplint_modified_files.yml index 8de6a5e41..a5aa6a652 100644 --- a/.github/workflows/cpplint_modified_files.yml +++ b/.github/workflows/cpplint_modified_files.yml @@ -37,7 +37,8 @@ jobs: sys.exit(0) print("cpplint:") - subprocess.run(["cpplint", "--filter=-legal/copyright"] + cpp_files, check=True, text=True) + for cpp_file in cpp_files: + subprocess.run(["cpplint", "--filter=-legal/copyright", cpp_file], check=True, text=True) print("g++:") # compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split()) diff --git a/DIRECTORY.md b/DIRECTORY.md index d627af28c..51e840ef4 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -109,8 +109,13 @@ * [Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/factorial.cpp) * [Fast Power](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fast_power.cpp) * [Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/fibonacci.cpp) + * [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) * [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) + * [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) * [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) @@ -119,6 +124,7 @@ * [Primes Up To Billion](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/primes_up_to_billion.cpp) * [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) ## Operations On Datastructures * [Array Left Rotation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/operations_on_datastructures/Array%20Left%20Rotation.cpp) @@ -137,23 +143,16 @@ * [Decimal To Hexadecimal](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/decimal_to_hexadecimal.cpp) * [Decimal To Roman Numeral](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/decimal_to_roman_numeral.cpp) * [Fast Interger Input](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fast_interger_input.cpp) - * [Fibonacci Fast](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fibonacci_fast.cpp) - * [Fibonacci Large](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/fibonacci_large.cpp) - * [Gcd Of N Numbers](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/gcd_of_n_numbers.cpp) * [Happy Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/happy_number.cpp) - * [Large Factorial](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/large_factorial.cpp) - * [Large Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/large_number.h) * [Matrix Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/matrix_exponentiation.cpp) * [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/palindrome_of_number.cpp) * [Paranthesis Matching](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/paranthesis_matching.cpp) * [Pascal Triangle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/pascal_triangle.cpp) * [Primality Test](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/primality_test.cpp) - * [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sieve_of_Eratosthenes.cpp) - * [Smallest-Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest-circle.cpp) + * [Smallest Circle](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/smallest_circle.cpp) * [Sparse Matrix](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/sparse_matrix.cpp) * [Spiral Print](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/spiral_print.cpp) * [Stairs Pattern](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/stairs_pattern.cpp) - * [String Fibonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/string_fibonacci.cpp) * [Tower Of Hanoi](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/tower_of_hanoi.cpp) * [Vector Important Functions](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/others/vector_important_functions.cpp) diff --git a/data_structure/doubly_linked_list.cpp b/data_structure/doubly_linked_list.cpp index 17ea2983a..4fc38abfc 100644 --- a/data_structure/doubly_linked_list.cpp +++ b/data_structure/doubly_linked_list.cpp @@ -61,6 +61,7 @@ void double_linked_list::remove(int x) { t->prev->next = t->next; t->next->prev = t->prev; } + delete t; } void double_linked_list::search(int x) { diff --git a/math/fibonacci.cpp b/math/fibonacci.cpp index 1a5f4afb4..e15cfc0cc 100644 --- a/math/fibonacci.cpp +++ b/math/fibonacci.cpp @@ -5,6 +5,8 @@ * Calculate the the value on Fibonacci's sequence given an * integer as input. * \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f] + * + * @see fibonacci_large.cpp, fibonacci_fast.cpp, string_fibonacci.cpp */ #include #include @@ -15,7 +17,8 @@ int fibonacci(unsigned int n) { /* If the input is 0 or 1 just return the same This will set the first 2 values of the sequence */ - if (n <= 1) return n; + if (n <= 1) + return n; /* Add the last 2 values of the sequence to get next */ return fibonacci(n - 1) + fibonacci(n - 2); diff --git a/math/fibonacci_fast.cpp b/math/fibonacci_fast.cpp new file mode 100644 index 000000000..dc59742b8 --- /dev/null +++ b/math/fibonacci_fast.cpp @@ -0,0 +1,52 @@ +/** + * @file + * @brief Faster computation of Fibonacci series + * + * An efficient way to calculate nth fibonacci number faster and simpler than + * \f$O(n\log n)\f$ method of matrix exponentiation This works by using both + * recursion and dynamic programming. as 93rd fibonacci exceeds 19 digits, which + * cannot be stored in a single long long variable, we can only use it till 92nd + * fibonacci we can use it for 10000th fibonacci etc, if we implement + * bigintegers. This algorithm works with the fact that nth fibonacci can easily + * found if we have already found n/2th or (n+1)/2th fibonacci It is a property + * of fibonacci similar to matrix exponentiation. + * + * @see fibonacci_large.cpp, fibonacci.cpp + */ + +#include +#include +#include + +/** maximum number that can be computed - The result after 93 cannot be stored + * in a `uint64_t` data type. */ +const uint64_t MAX = 93; + +/** Array of computed fibonacci numbers */ +uint64_t f[MAX] = {0}; + +/** Algorithm */ +uint64_t fib(uint64_t n) { + if (n == 0) + return 0; + if (n == 1 || n == 2) + return (f[n] = 1); + + if (f[n]) + return f[n]; + + uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2; + + f[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1)) + : (2 * fib(k - 1) + fib(k)) * fib(k); + return f[n]; +} + +/** Main function */ +int main() { + // Main Function + for (uint64_t i = 1; i < 93; i++) { + std::cout << i << " th fibonacci number is " << fib(i) << std::endl; + } + return 0; +} diff --git a/others/fibonacci_large.cpp b/math/fibonacci_large.cpp similarity index 91% rename from others/fibonacci_large.cpp rename to math/fibonacci_large.cpp index 6f36702a2..d9dbff799 100644 --- a/others/fibonacci_large.cpp +++ b/math/fibonacci_large.cpp @@ -1,11 +1,14 @@ /** - * Computes N^th Fibonacci number given as + * @file + * @brief Computes N^th Fibonacci number given as * input argument. Uses custom build arbitrary integers library * to perform additions and other operations. * * Took 0.608246 seconds to compute 50,000^th Fibonacci * number that contains 10450 digits! - **/ + * + * @see fibonacci.cpp, fibonacci_fast.cpp, string_fibonacci.cpp + */ #include #include @@ -13,6 +16,10 @@ #include "./large_number.h" +/** Compute fibonacci numbers using the relation + * \f[f(n)=f(n-1)+f(n-2)\f] + * and returns the result as a large_number type. + */ large_number fib(uint64_t n) { large_number f0(1); large_number f1(1); diff --git a/math/gcd_iterative_euclidean.cpp b/math/gcd_iterative_euclidean.cpp index 61fb640a3..2c0651ad7 100644 --- a/math/gcd_iterative_euclidean.cpp +++ b/math/gcd_iterative_euclidean.cpp @@ -4,7 +4,7 @@ * *iterative form* of * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) * - * @see gcd_recursive_euclidean.cpp + * @see gcd_recursive_euclidean.cpp, gcd_of_n_numbers.cpp */ #include #include diff --git a/math/gcd_of_n_numbers.cpp b/math/gcd_of_n_numbers.cpp new file mode 100644 index 000000000..92968ff12 --- /dev/null +++ b/math/gcd_of_n_numbers.cpp @@ -0,0 +1,41 @@ +/** + * @file + * @brief This program aims at calculating the GCD of n numbers by division + * method + * + * @see gcd_iterative_euclidean.cpp, gcd_recursive_euclidean.cpp + */ +#include + +/** Compute GCD using division algorithm + * + * @param[in] a array of integers to compute GCD for + * @param[in] n number of integers in array `a` + */ +int gcd(int *a, int n) { + int j = 1; // to access all elements of the array starting from 1 + int gcd = a[0]; + while (j < n) { + if (a[j] % gcd == 0) // value of gcd is as needed so far + j++; // so we check for next element + else + gcd = a[j] % gcd; // calculating GCD by division method + } + return gcd; +} + +/** Main function */ +int main() { + int n; + std::cout << "Enter value of n:" << std::endl; + std::cin >> n; + int *a = new int[n]; + int i; + std::cout << "Enter the n numbers:" << std::endl; + for (i = 0; i < n; i++) std::cin >> a[i]; + + std::cout << "GCD of entered n numbers:" << gcd(a, n) << std::endl; + + delete[] a; + return 0; +} diff --git a/math/gcd_recursive_euclidean.cpp b/math/gcd_recursive_euclidean.cpp index 3a1ca6e66..2a3d2183c 100644 --- a/math/gcd_recursive_euclidean.cpp +++ b/math/gcd_recursive_euclidean.cpp @@ -4,7 +4,7 @@ * *recursive form* of * [Euclidean algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) * - * @see gcd_iterative_euclidean.cpp + * @see gcd_iterative_euclidean.cpp, gcd_of_n_numbers.cpp */ #include @@ -21,14 +21,18 @@ int gcd(int num1, int num2) { } // Everything divides 0 - if (num1 == 0) return num2; - if (num2 == 0) return num1; + if (num1 == 0) + return num2; + if (num2 == 0) + return num1; // base case - if (num1 == num2) return num1; + if (num1 == num2) + return num1; // a is greater - if (num1 > num2) return gcd(num1 - num2, num2); + if (num1 > num2) + return gcd(num1 - num2, num2); return gcd(num1, num2 - num1); } diff --git a/others/large_factorial.cpp b/math/large_factorial.cpp similarity index 100% rename from others/large_factorial.cpp rename to math/large_factorial.cpp diff --git a/others/large_number.h b/math/large_number.h similarity index 100% rename from others/large_number.h rename to math/large_number.h diff --git a/math/string_fibonacci.cpp b/math/string_fibonacci.cpp new file mode 100644 index 000000000..eb9b6d7e1 --- /dev/null +++ b/math/string_fibonacci.cpp @@ -0,0 +1,89 @@ +/** + * @file + * @brief This Programme returns the Nth fibonacci as a string. + * + * The method used is manual addition with carry and placing it in a string + * which is called string addition This makes it have no bounds or limits + * + * @see fibonacci_large.cpp, fibonacci_fast.cpp, fibonacci.cpp + */ + +#include +#ifdef _MSC_VER +#include // use this for MS Visual C +#else +#include // otherwise +#endif + +/** + * function to add two string numbers + * \param [in] a first number in string to add + * \param [in] b second number in string to add + * \returns sum as a std::string + */ +std::string add(std::string a, std::string b) { + std::string temp = ""; + + // carry flag + int carry = 0; + + // fills up with zeros + while (a.length() < b.length()) { + a = "0" + a; + } + + // fills up with zeros + while (b.length() < a.length()) { + b = "0" + b; + } + + // adds the numbers a and b + for (int i = a.length() - 1; i >= 0; i--) { + char val = static_cast(((a[i] - 48) + (b[i] - 48)) + 48 + carry); + if (val > 57) { + carry = 1; + val -= 10; + } else { + carry = 0; + } + temp = val + temp; + } + + // processes the carry flag + if (carry == 1) { + temp = "1" + temp; + } + + // removes leading zeros. + while (temp[0] == '0' && temp.length() > 1) { + temp = temp.substr(1); + } + + return temp; +} + +/** Fibonacci iterator + * \param [in] n n^th Fibonacci number + */ +void fib_Accurate(uint64_t n) { + std::string tmp = ""; + std::string fibMinus1 = "1"; + std::string fibMinus2 = "0"; + for (uint64_t i = 0; i < n; i++) { + tmp = add(fibMinus1, fibMinus2); + fibMinus2 = fibMinus1; + fibMinus1 = tmp; + } + std::cout << fibMinus2; +} + +/** main function */ +int main() { + int n; + std::cout << "Enter whatever number N you want to find the fibonacci of\n"; + std::cin >> n; + std::cout << n << " th Fibonacci is \n"; + fib_Accurate(n); + + return 0; +} diff --git a/others/buzz_number.cpp b/others/buzz_number.cpp index f31038aad..ed9fc5f28 100644 --- a/others/buzz_number.cpp +++ b/others/buzz_number.cpp @@ -1,17 +1,20 @@ -//A buzz number is a number that is either divisble by 7 or has last digit as 7. +/** + * @file + * @brief A buzz number is a number that is either divisible by 7 or has last + * digit as 7. + */ #include -using namespace std; -int main() -{ - int n, t; - cin >> t; - while (t--) - { - cin >> n; - if ((n % 7 == 0) || (n % 10 == 7)) - cout << n << " is a buzz number" << endl; - else - cout << n << " is not a buzz number" << endl; - } - return 0; + +/** main function */ +int main() { + int n, t; + std::cin >> t; + while (t--) { + std::cin >> n; + if ((n % 7 == 0) || (n % 10 == 7)) + std::cout << n << " is a buzz number" << std::endl; + else + std::cout << n << " is not a buzz number" << std::endl; + } + return 0; } diff --git a/others/decimal_to_binary.cpp b/others/decimal_to_binary.cpp index 4e2119ebc..11ce064a5 100644 --- a/others/decimal_to_binary.cpp +++ b/others/decimal_to_binary.cpp @@ -1,25 +1,55 @@ -// This function convert decimal to binary number -// +/** + * @file + * @brief Function to convert decimal number to binary representation + */ #include -using namespace std; -int main() -{ - int number; - cout << "Enter a number:"; - cin >> number; - int remainder, binary = 0, var = 1; +/** + * This method converts the bit representation and stores it as a decimal + * number. + */ +void method1(int number) { + int remainder, binary = 0, var = 1; - do - { - remainder = number % 2; - number = number / 2; - binary = binary + (remainder * var); - var = var * 10; - - } while (number > 0); - cout << "the binary is :"; - cout << binary; - cout << endl; - return 0; + do { + remainder = number % 2; + number = number / 2; + binary = binary + (remainder * var); + var = var * 10; + } while (number > 0); + std::cout << "Method 1 : " << binary << std::endl; +} + +/** + * This method stores each bit value from LSB to MSB and then prints them back + * from MSB to LSB + */ +void method2(int number) { + int num_bits = 0; + char bit_string[50]; + + do { + bool bit = number & 0x01; // get last bit + if (bit) + bit_string[num_bits++] = '1'; + else + bit_string[num_bits++] = '0'; + number >>= 1; // right shift bit 1 bit + } while (number > 0); + + std::cout << "Method 2 : "; + while (num_bits >= 0) + std::cout << bit_string[num_bits--]; // print from MSB to LSB + std::cout << std::endl; +} + +int main() { + int number; + std::cout << "Enter a number:"; + std::cin >> number; + + method1(number); + method2(number); + + return 0; } diff --git a/others/decimal_to_hexadecimal.cpp b/others/decimal_to_hexadecimal.cpp index 705f21ba4..a3e544f49 100644 --- a/others/decimal_to_hexadecimal.cpp +++ b/others/decimal_to_hexadecimal.cpp @@ -1,28 +1,34 @@ +/** + * @file + * @brief Convert decimal number to hexadecimal representation + */ + #include -using namespace std; +/** + * Main program + */ +int main(void) { + int valueToConvert = 0; // Holds user input + int hexArray[8]; // Contains hex values backwards + int i = 0; // counter + char HexValues[] = "0123456789ABCDEF"; -int main(void) -{ - int valueToConvert = 0; //Holds user input - int hexArray[8]; //Contains hex values backwards - int i = 0; //counter - char HexValues[] = "0123456789ABCDEF"; + std::cout << "Enter a Decimal Value" + << std::endl; // Displays request to stdout + std::cin >> + valueToConvert; // Stores value into valueToConvert via user input - cout << "Enter a Decimal Value" << endl; //Displays request to stdout - cin >> valueToConvert; //Stores value into valueToConvert via user input + while (valueToConvert > 15) { // Dec to Hex Algorithm + hexArray[i++] = valueToConvert % 16; // Gets remainder + valueToConvert /= 16; + // valueToConvert >>= 4; // This will divide by 2^4=16 and is faster + } + hexArray[i] = valueToConvert; // Gets last value - while (valueToConvert > 15) - { //Dec to Hex Algorithm - hexArray[i++] = valueToConvert % 16; //Gets remainder - valueToConvert /= 16; - } - hexArray[i] = valueToConvert; //Gets last value + std::cout << "Hex Value: "; + while (i >= 0) std::cout << HexValues[hexArray[i--]]; - cout << "Hex Value: "; - while (i >= 0) - cout << HexValues[hexArray[i--]]; - - cout << endl; - return 0; + std::cout << std::endl; + return 0; } diff --git a/others/decimal_to_roman_numeral.cpp b/others/decimal_to_roman_numeral.cpp index 0372e8003..6bd1be395 100644 --- a/others/decimal_to_roman_numeral.cpp +++ b/others/decimal_to_roman_numeral.cpp @@ -1,97 +1,76 @@ -//This Programme Converts a given decimal number in the range [0,4000) -//to both Lower case and Upper case Roman Numeral +/** + * @file + * @brief This Programme Converts a given decimal number in the range [0,4000) + * to both Lower case and Upper case Roman Numeral + */ #include #include -#include +#include #include -using namespace std; -//This functions fills a string with character c, n times and returns it -string fill(char c, int n) -{ - string s = ""; - while (n--) - s += c; +/** This functions fills a string with character c, n times and returns it + * @note This can probably be replace by `memcpy` function. + */ +std::string fill(char c, int n) { + std::string s = ""; + while (n--) s += c; return s; } -//to convert to lowercase Roman Numeral -// the function works recursively -string tolowerRoman(int n) -{ - if (n < 4) - return fill('i', n); - if (n < 6) - return fill('i', 5 - n) + "v"; - if (n < 9) - return string("v") + fill('i', n - 5); - if (n < 11) - return fill('i', 10 - n) + "x"; - if (n < 40) - return fill('x', n / 10) + tolowerRoman(n % 10); - if (n < 60) - return fill('x', 5 - n / 10) + 'l' + tolowerRoman(n % 10); +/** to convert to lowercase Roman Numeral + * the function works recursively + */ +std::string tolowerRoman(int n) { + if (n < 4) return fill('i', n); + if (n < 6) return fill('i', 5 - n) + "v"; + if (n < 9) return std::string("v") + fill('i', n - 5); + if (n < 11) return fill('i', 10 - n) + "x"; + if (n < 40) return fill('x', n / 10) + tolowerRoman(n % 10); + if (n < 60) return fill('x', 5 - n / 10) + 'l' + tolowerRoman(n % 10); if (n < 90) - return string("l") + fill('x', n / 10 - 5) + tolowerRoman(n % 10); - if (n < 110) - return fill('x', 10 - n / 10) + "c" + tolowerRoman(n % 10); - if (n < 400) - return fill('c', n / 100) + tolowerRoman(n % 100); - if (n < 600) - return fill('c', 5 - n / 100) + 'd' + tolowerRoman(n % 100); + return std::string("l") + fill('x', n / 10 - 5) + tolowerRoman(n % 10); + if (n < 110) return fill('x', 10 - n / 10) + "c" + tolowerRoman(n % 10); + if (n < 400) return fill('c', n / 100) + tolowerRoman(n % 100); + if (n < 600) return fill('c', 5 - n / 100) + 'd' + tolowerRoman(n % 100); if (n < 900) - return string("d") + fill('c', n / 100 - 5) + tolowerRoman(n % 100); - if (n < 1100) - return fill('c', 10 - n / 100) + "m" + tolowerRoman(n % 100); - if (n < 4000) - return fill('m', n / 1000) + tolowerRoman(n % 1000); + return std::string("d") + fill('c', n / 100 - 5) + + tolowerRoman(n % 100); + if (n < 1100) return fill('c', 10 - n / 100) + "m" + tolowerRoman(n % 100); + if (n < 4000) return fill('m', n / 1000) + tolowerRoman(n % 1000); return "?"; } -//to convert to uppercase Roman Numeral -// the function works recursively -string toupperRoman(int n) -{ - if (n < 4) - return fill('I', n); - if (n < 6) - return fill('I', 5 - n) + "V"; - if (n < 9) - return string("V") + fill('I', n - 5); - if (n < 11) - return fill('I', 10 - n) + "X"; - if (n < 40) - return fill('X', n / 10) + toupperRoman(n % 10); - if (n < 60) - return fill('X', 5 - n / 10) + 'L' + toupperRoman(n % 10); +/** to convert to uppercase Roman Numeral + * the function works recursively + */ +std::string toupperRoman(int n) { + if (n < 4) return fill('I', n); + if (n < 6) return fill('I', 5 - n) + "V"; + if (n < 9) return std::string("V") + fill('I', n - 5); + if (n < 11) return fill('I', 10 - n) + "X"; + if (n < 40) return fill('X', n / 10) + toupperRoman(n % 10); + if (n < 60) return fill('X', 5 - n / 10) + 'L' + toupperRoman(n % 10); if (n < 90) - return string("L") + fill('X', n / 10 - 5) + toupperRoman(n % 10); - if (n < 110) - return fill('X', 10 - n / 10) + "C" + toupperRoman(n % 10); - if (n < 400) - return fill('C', n / 100) + toupperRoman(n % 100); - if (n < 600) - return fill('C', 5 - n / 100) + 'D' + toupperRoman(n % 100); + return std::string("L") + fill('X', n / 10 - 5) + toupperRoman(n % 10); + if (n < 110) return fill('X', 10 - n / 10) + "C" + toupperRoman(n % 10); + if (n < 400) return fill('C', n / 100) + toupperRoman(n % 100); + if (n < 600) return fill('C', 5 - n / 100) + 'D' + toupperRoman(n % 100); if (n < 900) - return string("D") + fill('C', n / 100 - 5) + toupperRoman(n % 100); - if (n < 1100) - return fill('C', 10 - n / 100) + "M" + toupperRoman(n % 100); - if (n < 4000) - return fill('M', n / 1000) + toupperRoman(n % 1000); + return std::string("D") + fill('C', n / 100 - 5) + + toupperRoman(n % 100); + if (n < 1100) return fill('C', 10 - n / 100) + "M" + toupperRoman(n % 100); + if (n < 4000) return fill('M', n / 1000) + toupperRoman(n % 1000); return "?"; } -//main function - -int main() -{ - +/** main function */ +int main() { int n; - cout << "\t\tRoman numbers converter\n\n"; - cout << "Type in decimal number between 0 up to 4000 (exclusive): "; - cin >> n; - cout << n << " in Upper Roman Numerals is " << toupperRoman(n) << "\n"; - cout << n << " in Lower Roman Numerals is " << tolowerRoman(n) << "\n"; + std::cout << "\t\tRoman numbers converter\n\n"; + std::cout << "Type in decimal number between 0 up to 4000 (exclusive): "; + std::cin >> n; + std::cout << n << " in Upper Roman Numerals is " << toupperRoman(n) << "\n"; + std::cout << n << " in Lower Roman Numerals is " << tolowerRoman(n) << "\n"; return 0; } diff --git a/others/fast_interger_input.cpp b/others/fast_interger_input.cpp index 3358fc8bb..5e7bcb99d 100644 --- a/others/fast_interger_input.cpp +++ b/others/fast_interger_input.cpp @@ -1,7 +1,15 @@ -// Read integers in the fastest way in c plus plus -#include +/** + * @file + * @brief Read integers from stdin continuously as they are entered without + * waiting for the `\n` character + */ +#include + +/** Function to read the number from stdin. The function reads input until a non + * numeric character is entered. + */ void fastinput(int *number) { -// variable to indicate sign of input integer + // variable to indicate sign of input integer bool negative = false; register int c; *number = 0; @@ -19,18 +27,17 @@ void fastinput(int *number) { // Keep on extracting characters if they are integers // i.e ASCII Value lies from '0'(48) to '9' (57) for (; (c > 47 && c < 58); c = std::getchar()) - *number = *number *10 + c - 48; + *number = *number * 10 + c - 48; // if scanned input has a negative sign, negate the // value of the input number - if (negative) - *(number) *= -1; + if (negative) *(number) *= -1; } -// Function Call +/** Main function */ int main() { int number; fastinput(&number); - std::cout << number << "\n"; + std::cout << number << std::endl; return 0; } diff --git a/others/fibonacci_fast.cpp b/others/fibonacci_fast.cpp deleted file mode 100644 index a0b83b640..000000000 --- a/others/fibonacci_fast.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// An efficient way to calculate nth fibonacci number faster and simpler than -// O(nlogn) method of matrix exponentiation This works by using both recursion -// and dynamic programming. as 93rd fibonacci exceeds 19 digits, which cannot be -// stored in a single long long variable, we can only use it till 92nd fibonacci -// we can use it for 10000th fibonacci etc, if we implement bigintegers. -// This algorithm works with the fact that nth fibonacci can easily found if we -// have already found n/2th or (n+1)/2th fibonacci It is a property of fibonacci -// similar to matrix exponentiation. - -#include -#include -#include - -const uint64_t MAX = 93; - -uint64_t f[MAX] = {0}; - -uint64_t fib(uint64_t n) { - if (n == 0) return 0; - if (n == 1 || n == 2) return (f[n] = 1); - - if (f[n]) return f[n]; - - uint64_t k = (n % 2 != 0) ? (n + 1) / 2 : n / 2; - - f[n] = (n % 2 != 0) ? (fib(k) * fib(k) + fib(k - 1) * fib(k - 1)) - : (2 * fib(k - 1) + fib(k)) * fib(k); - return f[n]; -} - -int main() { - // Main Function - for (uint64_t i = 1; i < 93; i++) { - std::cout << i << " th fibonacci number is " << fib(i) << "\n"; - } - return 0; -} diff --git a/others/gcd_of_n_numbers.cpp b/others/gcd_of_n_numbers.cpp deleted file mode 100644 index 37e82173a..000000000 --- a/others/gcd_of_n_numbers.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// This program aims at calculating the GCD of n numbers by division method -#include - -int main() { - int n; - std::cout << "Enter value of n:" << std::endl; - std::cin >> n; - int *a = new int[n]; - int i, j, gcd; - std::cout << "Enter the n numbers:" << std::endl; - for (i = 0; i < n; i++) std::cin >> a[i]; - j = 1; // to access all elements of the array starting from 1 - gcd = a[0]; - while (j < n) { - if (a[j] % gcd == 0) // value of gcd is as needed so far - j++; // so we check for next element - else - gcd = a[j] % gcd; // calculating GCD by division method - } - std::cout << "GCD of entered n numbers:" << gcd; - delete[] a; - return 0; -} diff --git a/others/happy_number.cpp b/others/happy_number.cpp index 7d25a1bbd..dacb2b8c4 100644 --- a/others/happy_number.cpp +++ b/others/happy_number.cpp @@ -1,28 +1,39 @@ -/* A happy number is a number whose sum of digits is calculated until the sum is a single digit, - and this sum turns out to be 1 */ - -// Copyright 2019 TheAlgorithms contributors +/** + * A [happy number](https://en.wikipedia.org/wiki/Happy_number) is a decimal + * number whose sum of digits is calculated until the sum is a single digit, and + * this sum turns out to be 1. + */ #include -int main() { - int n, k, s = 0, d; - std::cout << "Enter a number:"; - std::cin >> n; - s = 0; - k = n; - while (k > 9) { - while (k != 0) { - d = k % 10; - s += d; - k /= 10; +/** + * Checks if a decimal number is a happy number + * \returns true if happy else false + */ +template +bool is_happy(T n) { + T s = 0; // stores sum of digits + while (n > 9) { // while number is > 9, there are more than 1 digit + while (n != 0) { // get digit + T d = n % 10; + s += d; + n /= 10; + } + n = s; + s = 0; } - k = s; - s = 0; - } - if (k == 1) - std::cout << n << " is a happy number" << std::endl; - else - std::cout << n << " is not a happy number" << std::endl; - return 0; + return (n == 1) ? true : false; // true if k == 1 +} + +/** Main function */ +int main() { + int n; + std::cout << "Enter a number:"; + std::cin >> n; + + if (is_happy(n)) + std::cout << n << " is a happy number" << std::endl; + else + std::cout << n << " is not a happy number" << std::endl; + return 0; } diff --git a/others/matrix_exponentiation.cpp b/others/matrix_exponentiation.cpp index f9b4997e9..d44d22593 100644 --- a/others/matrix_exponentiation.cpp +++ b/others/matrix_exponentiation.cpp @@ -1,20 +1,24 @@ -/* -Matrix Exponentiation. +/** +@file +@brief Matrix Exponentiation. + The problem can be solved with DP but constraints are high. -ai = bi (for i <= k) -ai = c1*ai-1 + c2*ai-2 + ... + ck*ai-k (for i > k) -Taking the example of Fibonacci series, K=2 -b1 = 1, b2=1 -c1 = 1, c2=1 -a = 0 1 1 2 .... -This way you can find the 10^18 fibonacci number%MOD. +
\f$a_i = b_i\f$ (for \f$i <= k\f$) +
\f$a_i = c_1 a_{i-1} + c_2 a_{i-2} + ... + c_k a_{i-k}\f$ (for \f$i > k\f$) +
Taking the example of Fibonacci series, \f$k=2\f$ +
\f$b_1 = 1,\; b_2=1\f$ +
\f$c_1 = 1,\; c_2=1\f$ +
\f$a = \begin{bmatrix}0& 1& 1& 2& \ldots\end{bmatrix}\f$ +
This way you can find the \f$10^{18}\f$ fibonacci number%MOD. I have given a general way to use it. The program takes the input of B and C matrix. + Steps for Matrix Expo 1. Create vector F1 : which is the copy of B. 2. Create transpose matrix (Learn more about it on the internet) -3. Perform T^(n-1) [transpose matrix to the power n-1] -4. Multiply with F to get the last matrix of size (1xk). +3. Perform \f$T^{n-1}\f$ [transpose matrix to the power n-1] +4. Multiply with F to get the last matrix of size (1\f$\times\f$k). + The first element of this matrix is the required result. */ @@ -25,16 +29,36 @@ using std::cin; using std::cout; using std::vector; +/*! shorthand definition for `int64_t` */ #define ll int64_t -#define endl '\n' + +/*! shorthand definition for `std::endl` */ +#define endl std::endl + +/*! shorthand definition for `int64_t` */ #define pb push_back #define MOD 1000000007 -ll ab(ll x) { return x > 0LL ? x : -x; } + +/** returns absolute value */ +inline ll ab(ll x) { return x > 0LL ? x : -x; } + +/** global variable k + * @todo @stepfencurryxiao add documetnation + */ ll k; + +/** global vector variables + * @todo @stepfencurryxiao add documetnation + */ vector a, b, c; -// To multiply 2 matrix -vector> multiply(vector> A, vector> B) { +/** To multiply 2 matrices + * \param [in] A matrix 1 of size (m\f$\times\f$n) + * \param [in] B \p matrix 2 of size (p\f$\times\f$q)\n\note \f$p=n\f$ + * \result matrix of dimension (m\f$\times\f$q) + */ +vector> multiply(const vector> &A, + const vector> &B) { vector> C(k + 1, vector(k + 1)); for (ll i = 1; i <= k; i++) { for (ll j = 1; j <= k; j++) { @@ -46,9 +70,15 @@ vector> multiply(vector> A, vector> B) { return C; } -// computing power of a matrix -vector> power(vector> A, ll p) { - if (p == 1) return A; +/** computing integer power of a matrix using recursive multiplication. + * @note A must be a square matrix for this algorithm. + * \param [in] A base matrix + * \param [in] p exponent + * \return matrix of same dimension as A + */ +vector> power(const vector> &A, ll p) { + if (p == 1) + return A; if (p % 2 == 1) { return multiply(A, power(A, p - 1)); } else { @@ -57,10 +87,15 @@ vector> power(vector> A, ll p) { } } -// main function +/*! Wrapper for Fibonacci + * \param[in] n \f$n^\text{th}\f$ Fibonacci number + * \return \f$n^\text{th}\f$ Fibonacci number + */ ll ans(ll n) { - if (n == 0) return 0; - if (n <= k) return b[n - 1]; + if (n == 0) + return 0; + if (n <= k) + return b[n - 1]; // F1 vector F1(k + 1); for (ll i = 1; i <= k; i++) F1[i] = b[i - 1]; @@ -90,8 +125,7 @@ ll ans(ll n) { return res; } -// 1 1 2 3 5 - +/** Main function */ int main() { cin.tie(0); cout.tie(0); diff --git a/others/palindrome_of_number.cpp b/others/palindrome_of_number.cpp index 621b09ab6..66401ff96 100644 --- a/others/palindrome_of_number.cpp +++ b/others/palindrome_of_number.cpp @@ -1,3 +1,10 @@ +/** + * @file + * @brief Check if a number is + * [palindrome](https://en.wikipedia.org/wiki/Palindrome) or not. + * + * This program cheats by using the STL library's std::reverse function. + */ #include #include @@ -8,17 +15,18 @@ #include #endif +/** Main function */ int main() { int num; std::cout << "Enter number = "; std::cin >> num; - std::string s1 = std::to_string(num); + std::string s1 = std::to_string(num); // convert number to string std::string s2 = s1; - reverse(s1.begin(), s1.end()); + std::reverse(s1.begin(), s1.end()); // reverse the string - if (s1 == s2) + if (s1 == s2) // check if reverse and original string are identical std::cout << "true"; else std::cout << "false"; diff --git a/others/paranthesis_matching.cpp b/others/paranthesis_matching.cpp index d2bb4d39c..ef5da6e47 100644 --- a/others/paranthesis_matching.cpp +++ b/others/paranthesis_matching.cpp @@ -1,76 +1,75 @@ +/** + * @file + * @brief Perform paranthesis matching. \note Do not know the application of + * this, however. + * @note Implementation is C-type and does not utilize the C++ constructs + * @todo implement as a C++ class + */ #include -#include - -using namespace std; +#ifdef _MSC_VER +#include // Visual Studio C requires this include +#else +#include +#endif +/** check number */ #define MAX 100 -// -------------- stack -------------- - +//! @{-------------- stack -------------- +//! global stack char stack[MAX]; + +//! pointer to track stack index int top = -1; -void push(char ch) -{ - stack[++top] = ch; +//! push byte to stack variable +void push(char ch) { stack[++top] = ch; } + +//! pop a byte out of stack variable +char pop() { return stack[top--]; } + +//! @}-------------- end stack ----------- + +/** return opening paranthesis corresponding to the close paranthesis + * @param[in] ch closed paranthesis character + */ +char opening(char ch) { + switch (ch) { + case '}': + return '{'; + case ']': + return '['; + case ')': + return '('; + case '>': + return '<'; + } + return '\0'; } -char pop() -{ - return stack[top--]; -} - -// -------------- end stack ----------- - -char opening(char ch) -{ - switch (ch) - { - case '}': - return '{'; - case ']': - return '['; - case ')': - return '('; - case '>': - return '<'; - } -} - -int main() -{ - - string exp; - int valid = 1, i = 0; - cout << "Enter The Expression : "; - cin >> exp; - - while (valid == 1 && i < exp.length()) - { - if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[' || exp[i] == '<') - { - push(exp[i]); - } - else if (top >= 0 && stack[top] == opening(exp[i])) - { - pop(); - } - else - { - valid = 0; - } - i++; - } - - // makes sure the stack is empty after processsing (above) - if (valid == 1 && top == -1) - { - cout << "\nCorrect Expression"; - } - else - { - cout << "\nWrong Expression"; - } - - return 0; +int main() { + std::string exp; + int valid = 1, i = 0; + std::cout << "Enter The Expression : "; + std::cin >> exp; + + while (valid == 1 && i < exp.length()) { + if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[' || exp[i] == '<') { + push(exp[i]); + } else if (top >= 0 && stack[top] == opening(exp[i])) { + pop(); + } else { + valid = 0; + } + i++; + } + + // makes sure the stack is empty after processsing (above) + if (valid == 1 && top == -1) { + std::cout << "\nCorrect Expression"; + } else { + std::cout << "\nWrong Expression"; + } + + return 0; } diff --git a/others/pascal_triangle.cpp b/others/pascal_triangle.cpp index 063a6666a..4ea58f3f1 100644 --- a/others/pascal_triangle.cpp +++ b/others/pascal_triangle.cpp @@ -1,19 +1,38 @@ +/** + * @file + * @brief Pascal's triangle implementation + */ +#ifdef _MSC_VER +#include // required for Visual C +#else #include +#endif +#include #include +/** + * Print the triangle + * \param [in] arr 2D-array containing Pascal numbers + * \param [in] n depth of Pascal triangle to print + */ void show_pascal(int **arr, int n) { - // pint Pascal's Triangle for (int i = 0; i < n; ++i) { for (int j = 0; j < n + i; ++j) { if (arr[i][j] == 0) - std::cout << " "; + std::cout << std::setw(4) << " "; else - std::cout << arr[i][j]; + std::cout << std::setw(4) << arr[i][j]; } std::cout << std::endl; } } +/** + * Print the triangle + * \param [in,out] arr array containing Pascal numbers + * \param [in] n depth of Pascal triangle to print + * \result arr pointer returned + */ int **pascal_triangle(int **arr, int n) { for (int i = 0; i < n; ++i) { for (int j = n - i - 1; j < n + i; ++j) { @@ -27,6 +46,9 @@ int **pascal_triangle(int **arr, int n) { return arr; } +/** + * main function + */ int main() { int n = 0; diff --git a/others/primality_test.cpp b/others/primality_test.cpp index ce8fc1706..faec6589c 100644 --- a/others/primality_test.cpp +++ b/others/primality_test.cpp @@ -1,32 +1,42 @@ +/** + * @file + * @brief [Primality test](https://en.wikipedia.org/wiki/Primality_test) + * implementation. + * + * A simple and efficient implementation of a function to test if a number is + * prime, based on the fact that + * > Every Prime number, except 2 and 3, are of the form \f$6k\pm1\f$ for + * > integer values of k. + * This gives a 3x speed improvement. + */ #include -using namespace std; -//A simple and efficient implementation of a function to test if a number is prime, based on the fact that -//Every Prime number, except 2 and 3 are of the form 6*k+1 or 6*k-1 for integer values of k. +/** Check if a number is prime + * \param[in] number number to check + * \returns true if prime else false + */ +bool IsPrime(int number) { + if (((!(number & 1)) && number != 2) || (number < 2) || + (number % 3 == 0 && number != 3)) + return false; -bool IsPrime(int number) -{ - if (((!(number & 1)) && number != 2) || (number < 2) || (number % 3 == 0 && number != 3)) - return false; - - for (int k = 1; 36 * k * k - 12 * k < number; ++k) - { - if ((number % (6 * k + 1) == 0) || (number % (6 * k - 1) == 0)) - return false; - } - return true; + for (int k = 1; 36 * k * k - 12 * k < number; ++k) { + if ((number % (6 * k + 1) == 0) || (number % (6 * k - 1) == 0)) + return false; + } + return true; } -int main() -{ - //Main Function - cout << "Enter the value of n to check if Prime\n"; - int n; - cin >> n; - if (IsPrime(n)) - cout << n << " is Prime" << endl; - else - cout << n << " is not Prime" << endl; +/** main function */ +int main() { + // Main Function + std::cout << "Enter the value of n to check if Prime\n"; + int n; + std::cin >> n; + if (IsPrime(n)) + std::cout << n << " is Prime" << std::endl; + else + std::cout << n << " is not Prime" << std::endl; - return 0; + return 0; } diff --git a/others/sieve_of_Eratosthenes.cpp b/others/sieve_of_Eratosthenes.cpp deleted file mode 100644 index e87ad4983..000000000 --- a/others/sieve_of_Eratosthenes.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Sieve of Eratosthenes is an algorithm to find the primes - * that is between 2 to N (as defined in main). - * - * Time Complexity : O(N) - * Space Complexity : O(N) - */ - -#include -using namespace std; - -#define MAX 10000000 - -int primes[MAX]; - -/* - * This is the function that finds the primes and eliminates - * the multiples. - */ -void sieve(int N) -{ - primes[0] = 1; - primes[1] = 1; - for (int i = 2; i <= N; i++) - { - if (primes[i] == 1) - continue; - for (int j = i + i; j <= N; j += i) - primes[j] = 1; - } -} - -/* - * This function prints out the primes to STDOUT - */ -void print(int N) -{ - for (int i = 0; i <= N; i++) - if (primes[i] == 0) - cout << i << ' '; - cout << '\n'; -} - -/* - * NOTE: This function is important for the - * initialization of the array. - */ -void init() -{ - for (int i = 0; i < MAX; i++) - primes[i] = 0; -} - -int main() -{ - int N = 100; - init(); - sieve(N); - print(N); -} diff --git a/others/smallest-circle.cpp b/others/smallest-circle.cpp deleted file mode 100644 index 48437cd86..000000000 --- a/others/smallest-circle.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include -#include -#include - -using namespace std; - -struct Point -{ - double x, y; - Point(double a = 0.0, double b = 0.0) - { - x = a; - y = b; - } -}; - -double LenghtLine(Point A, Point B) -{ - return sqrt(abs((B.x - A.x) * (B.x - A.x)) + abs((B.y - A.y) * (B.y - A.y))); -} - -double TriangleArea(Point A, Point B, Point C) -{ - double a = LenghtLine(A, B); - double b = LenghtLine(B, C); - double c = LenghtLine(C, A); - double p = (a + b + c) / 2; - return sqrt(p * (p - a) * (p - b) * (p - c)); -} - -bool PointInCircle(vector &P, Point Center, double R) -{ - for (size_t i = 0; i < P.size(); i++) - { - if (LenghtLine(P[i], Center) > R) - return false; - } - return true; -} - -double circle(vector P) -{ - double minR = INT8_MAX; - double R; - Point C; - Point minC; - for (size_t i = 0; i < P.size() - 2; i++) - for (size_t j = i + 1; j < P.size(); j++) - for (size_t k = j + 1; k < P.size(); k++) - { - C.x = -0.5 * ((P[i].y * (P[j].x * P[j].x + P[j].y * P[j].y - P[k].x * P[k].x - P[k].y * P[k].y) + P[j].y * (P[k].x * P[k].x + P[k].y * P[k].y - P[i].x * P[i].x - P[i].y * P[i].y) + P[k].y * (P[i].x * P[i].x + P[i].y * P[i].y - P[j].x * P[j].x - P[j].y * P[j].y)) / (P[i].x * (P[j].y - P[k].y) + P[j].x * (P[k].y - P[i].y) + P[k].x * (P[i].y - P[j].y))); - C.y = 0.5 * ((P[i].x * (P[j].x * P[j].x + P[j].y * P[j].y - P[k].x * P[k].x - P[k].y * P[k].y) + P[j].x * (P[k].x * P[k].x + P[k].y * P[k].y - P[i].x * P[i].x - P[i].y * P[i].y) + P[k].x * (P[i].x * P[i].x + P[i].y * P[i].y - P[j].x * P[j].x - P[j].y * P[j].y)) / (P[i].x * (P[j].y - P[k].y) + P[j].x * (P[k].y - P[i].y) + P[k].x * (P[i].y - P[j].y))); - R = (LenghtLine(P[i], P[j]) * LenghtLine(P[j], P[k]) * LenghtLine(P[k], P[i])) / (4 * TriangleArea(P[i], P[j], P[k])); - if (!PointInCircle(P, C, R)) - { - continue; - } - if (R <= minR) - { - minR = R; - minC = C; - } - } - for (size_t i = 0; i < P.size() - 1; i++) - for (size_t j = i + 1; j < P.size(); j++) - { - C.x = (P[i].x + P[j].x) / 2; - C.y = (P[i].y + P[j].y) / 2; - R = LenghtLine(C, P[i]); - if (!PointInCircle(P, C, R)) - { - continue; - } - if (R <= minR) - { - minR = R; - minC = C; - } - } - cout << minC.x << " " << minC.y << endl; - return minR; -} - -void test() -{ - vector Pv(5); - Pv.push_back(Point(0, 0)); - Pv.push_back(Point(1, 3)); - Pv.push_back(Point(4, 1)); - Pv.push_back(Point(5, 4)); - Pv.push_back(Point(3, -2)); - cout << circle(Pv) << endl; -} - -void test2() -{ - vector Pv(4); - Pv.push_back(Point(0, 0)); - Pv.push_back(Point(0, 2)); - Pv.push_back(Point(2, 2)); - Pv.push_back(Point(2, 0)); - cout << circle(Pv) << endl; -} - -void test3() -{ - vector Pv(3); - Pv.push_back(Point(0.5, 1)); - Pv.push_back(Point(3.5, 3)); - Pv.push_back(Point(2.5, 0)); - cout << circle(Pv) << endl; -} -int main() -{ - test(); - cout << endl; - test2(); - cout << endl; - test3(); - return 0; -} diff --git a/others/smallest_circle.cpp b/others/smallest_circle.cpp new file mode 100644 index 000000000..9ee4353eb --- /dev/null +++ b/others/smallest_circle.cpp @@ -0,0 +1,205 @@ +/** + * @file + * @brief Get centre and radius of the + * [smallest circle](https://en.wikipedia.org/wiki/Smallest-circle_problem) + * that circumscribes given set of points. + * + * @see [other + * implementation](https://www.nayuki.io/page/smallest-enclosing-circle) + */ +#include +#include +#include + +/** Define a point */ +struct Point { + double x, /**< abscissa */ + y; /**< ordinate */ + + /** construct a point + * \param [in] a absicca (default = 0.0) + * \param [in] b ordinate (default = 0.0) + */ + explicit Point(double a = 0.f, double b = 0.f) { + x = a; + y = b; + } +}; + +/** Compute the Euclidian distance between two points \f$A\equiv(x_1,y_1)\f$ and + * \f$B\equiv(x_2,y_2)\f$ using the formula: + * \f[d=\sqrt{\left(x_1-x_2\right)^2+\left(y_1-y_2\right)^2}\f] + * + * \param [in] A point A + * \param [in] B point B + * \return ditance + */ +double LenghtLine(const Point &A, const Point &B) { + double dx = B.x - A.x; + double dy = B.y - A.y; + return std::sqrt((dx * dx) + (dy * dy)); +} + +/** + * Compute the area of triangle formed by three points using [Heron's + * formula](https://en.wikipedia.org/wiki/Heron%27s_formula). + * If the lengths of the sides of the triangle are \f$a,\,b,\,c\f$ and + * \f$s=\displaystyle\frac{a+b+c}{2}\f$ is the semi-perimeter then the area is + * given by \f[A=\sqrt{s(s-a)(s-b)(s-c)}\f] + * \param [in] A vertex A + * \param [in] B vertex B + * \param [in] C vertex C + * \returns area of triangle + */ +double TriangleArea(const Point &A, const Point &B, const Point &C) { + double a = LenghtLine(A, B); + double b = LenghtLine(B, C); + double c = LenghtLine(C, A); + double p = (a + b + c) / 2; + return std::sqrt(p * (p - a) * (p - b) * (p - c)); +} + +/** + * Check if a set of points lie within given circle. This is true if the + * distance of all the points from the centre of the circle is less than the + * radius of the circle + * \param [in] P set of points to check + * \param [in] Center coordinates to centre of the circle + * \param [in] R radius of the circle + * \returns True if P lies on or within the circle + * \returns False if P lies outside the circle + */ +bool PointInCircle(const std::vector &P, const Point &Center, double R) { + for (size_t i = 0; i < P.size(); i++) { + if (LenghtLine(P[i], Center) > R) + return false; + } + return true; +} + +/** + * Find the centre and radius of a circle enclosing a set of points.\n + * The function returns the radius of the circle and prints the coordinated of + * the centre of the circle. + * \param [in] P vector of points + * \returns radius of the circle + */ +double circle(const std::vector &P) { + double minR = INFINITY; + double R; + Point C; + Point minC; + + /* This code is invalid and does not give correct result for TEST 3 */ + // for each point in the list + for (size_t i = 0; i < P.size() - 2; i++) + // for every subsequent point in the list + for (size_t j = i + 1; j < P.size(); j++) + // for every subsequent point in the list + for (size_t k = j + 1; k < P.size(); k++) { + // here, we now have picked three points from the given set of + // points that we can use + // viz., P[i], P[j] and P[k] + C.x = -0.5 * ((P[i].y * (P[j].x * P[j].x + P[j].y * P[j].y - + P[k].x * P[k].x - P[k].y * P[k].y) + + P[j].y * (P[k].x * P[k].x + P[k].y * P[k].y - + P[i].x * P[i].x - P[i].y * P[i].y) + + P[k].y * (P[i].x * P[i].x + P[i].y * P[i].y - + P[j].x * P[j].x - P[j].y * P[j].y)) / + (P[i].x * (P[j].y - P[k].y) + + P[j].x * (P[k].y - P[i].y) + + P[k].x * (P[i].y - P[j].y))); + C.y = 0.5 * ((P[i].x * (P[j].x * P[j].x + P[j].y * P[j].y - + P[k].x * P[k].x - P[k].y * P[k].y) + + P[j].x * (P[k].x * P[k].x + P[k].y * P[k].y - + P[i].x * P[i].x - P[i].y * P[i].y) + + P[k].x * (P[i].x * P[i].x + P[i].y * P[i].y - + P[j].x * P[j].x - P[j].y * P[j].y)) / + (P[i].x * (P[j].y - P[k].y) + + P[j].x * (P[k].y - P[i].y) + + P[k].x * (P[i].y - P[j].y))); + R = (LenghtLine(P[i], P[j]) * LenghtLine(P[j], P[k]) * + LenghtLine(P[k], P[i])) / + (4 * TriangleArea(P[i], P[j], P[k])); + if (!PointInCircle(P, C, R)) { + continue; + } + if (R <= minR) { + minR = R; + minC = C; + } + } + + // for each point in the list + for (size_t i = 0; i < P.size() - 1; i++) + // for every subsequent point in the list + for (size_t j = i + 1; j < P.size(); j++) { + // check for diameterically opposite points + C.x = (P[i].x + P[j].x) / 2; + C.y = (P[i].y + P[j].y) / 2; + R = LenghtLine(C, P[i]); + if (!PointInCircle(P, C, R)) { + continue; + } + if (R <= minR) { + minR = R; + minC = C; + } + } + std::cout << minC.x << " " << minC.y << std::endl; + return minR; +} + +/** Test case: result should be: + * \n Circle with + * \n radius 3.318493136080724 + * \n centre at (3.0454545454545454, 1.3181818181818181) + */ +void test() { + std::vector Pv; + Pv.push_back(Point(0, 0)); + Pv.push_back(Point(5, 4)); + Pv.push_back(Point(1, 3)); + Pv.push_back(Point(4, 1)); + Pv.push_back(Point(3, -2)); + std::cout << circle(Pv) << std::endl; +} + +/** Test case: result should be: + * \n Circle with + * \n radius 1.4142135623730951 + * \n centre at (1.0, 1.0) + */ +void test2() { + std::vector Pv; + Pv.push_back(Point(0, 0)); + Pv.push_back(Point(0, 2)); + Pv.push_back(Point(2, 2)); + Pv.push_back(Point(2, 0)); + std::cout << circle(Pv) << std::endl; +} + +/** Test case: result should be: + * \n Circle with + * \n radius 1.821078397711709 + * \n centre at (2.142857142857143, 1.7857142857142856) + * @todo This test fails + */ +void test3() { + std::vector Pv; + Pv.push_back(Point(0.5, 1)); + Pv.push_back(Point(3.5, 3)); + Pv.push_back(Point(2.5, 0)); + Pv.push_back(Point(2, 1.5)); + std::cout << circle(Pv) << std::endl; +} + +/** Main program */ +int main() { + test(); + std::cout << std::endl; + test2(); + std::cout << std::endl; + test3(); + return 0; +} diff --git a/others/sparse_matrix.cpp b/others/sparse_matrix.cpp index d9878fda4..a358f0da4 100644 --- a/others/sparse_matrix.cpp +++ b/others/sparse_matrix.cpp @@ -1,10 +1,11 @@ /** @file * A sparse matrix is a matrix which has number of zeroes greater than - * \f$\frac{m*n}{2}\f$, where m and n are the dimensions of the matrix. + * \f$\frac{m\times n}{2}\f$, where m and n are the dimensions of the matrix. */ #include +/** main function */ int main() { int m, n; int counterZeros = 0; @@ -30,7 +31,8 @@ int main() { // counts the zero's for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { - if (a[i][j] == 0) counterZeros++; // Counting number of zeroes + if (a[i][j] == 0) + counterZeros++; // Counting number of zeroes } } diff --git a/others/spiral_print.cpp b/others/spiral_print.cpp index e6e6899ef..02dc3183a 100644 --- a/others/spiral_print.cpp +++ b/others/spiral_print.cpp @@ -1,78 +1,81 @@ +/** + * @file + * @brief Print the elements of a matrix traversing it spirally + */ #include -using namespace std; - -void genArray(int a[][10], int r, int c) -{ +/** Arrange sequence of numbers from '1' in a matrix form + * \param [out] a matrix to fill + * \param [in] r number of rows + * \param [in] c number of columns + */ +void genArray(int **a, int r, int c) { int value = 1; - for (int i = 0; i < r; i++) - { - for (int j = 0; j < c; j++) - { + for (int i = 0; i < r; i++) { + for (int j = 0; j < c; j++) { a[i][j] = value; - cout << a[i][j] << " "; + std::cout << a[i][j] << " "; value++; } - cout << endl; + std::cout << std::endl; } } -void spiralPrint(int a[][10], int r, int c) -{ +/** Traverse the matrix spirally and print the sequence of elements + * \param [in] a matrix to read from + * \param [in] r number of rows + * \param [in] c number of columns + */ +void spiralPrint(int **a, int r, int c) { int startRow = 0, endRow = r - 1; int startCol = 0, endCol = c - 1; int cnt = 0; - while (startRow <= endRow && startCol <= endCol) - { - - ///Print start row - for (int i = startCol; i <= endCol; i++, cnt++) - { - cout << a[startRow][i] << " "; + while (startRow <= endRow && startCol <= endCol) { + /// Print start row + for (int i = startCol; i <= endCol; i++, cnt++) { + std::cout << a[startRow][i] << " "; } startRow++; - ///Print the end col - for (int i = startRow; i <= endRow; i++, cnt++) - { - cout << a[i][endCol] << " "; + /// Print the end col + for (int i = startRow; i <= endRow; i++, cnt++) { + std::cout << a[i][endCol] << " "; } endCol--; - ///Print the end row - if (cnt == r * c) - { + /// Print the end row + if (cnt == r * c) { break; } - for (int i = endCol; i >= startCol; i--, cnt++) - { - cout << a[endRow][i] << " "; + for (int i = endCol; i >= startCol; i--, cnt++) { + std::cout << a[endRow][i] << " "; } endRow--; - ///Print the start Col - if (cnt == r * c) - { + /// Print the start Col + if (cnt == r * c) { break; } - for (int i = endRow; i >= startRow; i--, cnt++) - { - cout << a[i][startCol] << " "; + for (int i = endRow; i >= startRow; i--, cnt++) { + std::cout << a[i][startCol] << " "; } startCol++; } } -int main() -{ - int a[10][10]; - +/** main function */ +int main() { int r, c; - cin >> r >> c; + std::cin >> r >> c; + int **a = new int *[r]; + for (int i = 0; i < r; i++) a[i] = new int[c]; + genArray(a, r, c); spiralPrint(a, r, c); + for (int i = 0; i < r; i++) delete[] a[i]; + delete[] a; return 0; } diff --git a/others/stairs_pattern.cpp b/others/stairs_pattern.cpp index 281446a2f..a3b8b0a44 100644 --- a/others/stairs_pattern.cpp +++ b/others/stairs_pattern.cpp @@ -1,31 +1,35 @@ -/* -This program is use to print the following pattern - ** - ** - **** - **** - ****** - ****** -******** -******** -where number of pairs line is given by user +/** + * @file +@brief This program is use to print the following pattern
+   \*\*
+   \*\*
+  \*\*\*\*
+  \*\*\*\*
+ \*\*\*\*\*\*
+ \*\*\*\*\*\*
+\*\*\*\*\*\*\*\*
+********
+where number of pairs line is given by user */ -#include +#include + +/** main function */ int main() { -int l, st = 2, x, r, z, n, sp; -std::cout << "enter Index "; -std::cin >> x; -z = x; -for (r = 1; r <= x; r++) { -z = z - 1; -for (n = 1; n <= 2; n++) { -for (sp = 1; sp <= z; sp++) { -std::cout << " "; + int l, st = 2, x, r, z, n, sp; + std::cout << "enter Index "; + std::cin >> x; + z = x; + for (r = 1; r <= x; r++) { + z = z - 1; + for (n = 1; n <= 2; n++) { + for (sp = 1; sp <= z; sp++) { + std::cout << " "; + } + for (l = 1; l <= st; l++) { + std::cout << "*"; + } + std::cout << std::endl; + } + st = st + 2; + } } -for (l = 1; l <= st; l++) { -std::cout << "*"; -} -std::cout <<"\n"; -} -st = st + 2; -}} diff --git a/others/string_fibonacci.cpp b/others/string_fibonacci.cpp deleted file mode 100644 index e5475eec9..000000000 --- a/others/string_fibonacci.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//This Programme returns the Nth fibonacci as a string. -//The method used is manual addition with carry and placing it in a string which is called string addition -//This makes it have no bounds or limits - -#include -#include - -using namespace std; - -string add(string a, string b) -{ - string temp = ""; - - // carry flag - int carry = 0; - - // fills up with zeros - while ((int)a.length() < (int)b.length()) - { - a = "0" + a; - } - - // fills up with zeros - while ((int)b.length() < (int)a.length()) - { - b = "0" + b; - } - - // adds the numbers a and b - for (int i = a.length() - 1; i >= 0; i--) - { - char val = (char)(((a[i] - 48) + (b[i] - 48)) + 48 + carry); - if (val > 57) - { - carry = 1; - val -= 10; - } - else - { - carry = 0; - } - temp = val + temp; - } - - // processes the carry flag - if (carry == 1) - { - temp = "1" + temp; - } - - // removes leading zeros. - while (temp[0] == '0' && temp.length() > 1) - { - temp = temp.substr(1); - } - - return temp; -} - -void fib_Accurate(long long n) -{ - string tmp = ""; - string fibMinus1 = "1"; - string fibMinus2 = "0"; - for (long long i = 0; i < n; i++) - { - tmp = add(fibMinus1, fibMinus2); - fibMinus2 = fibMinus1; - fibMinus1 = tmp; - } - cout << fibMinus2; -} - -int main() -{ - int n; - cout << "Enter whatever number N you want to find the fibonacci of\n"; - cin >> n; - cout << n << " th Fibonacci is \n"; - fib_Accurate(n); - - return 0; -} diff --git a/others/tower_of_hanoi.cpp b/others/tower_of_hanoi.cpp index 5783d6a98..323b2e424 100644 --- a/others/tower_of_hanoi.cpp +++ b/others/tower_of_hanoi.cpp @@ -1,73 +1,85 @@ +/** + * @file + * @brief Solve the [Tower of + * Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) problem. + */ #include -using namespace std; -struct tower -{ - int values[10]; - int top; -} F, U, T; +/** + * Define the state of tower + */ +struct tower { + //! Values in the tower + int values[10]; + //! top tower ID + int top; +}; -void show() -{ - cout << "\n\n\tF : "; - for (int i = 0; i < F.top; i++) - { - cout << F.values[i] << "\t"; - } - cout << "\n\tU : "; - for (int i = 0; i < U.top; i++) - { - cout << U.values[i] << "\t"; - } - cout << "\n\tT : "; - for (int i = 0; i < T.top; i++) - { - cout << T.values[i] << "\t"; - } +/** Display the towers */ +void show(const struct tower *const F, const struct tower *const T, + const struct tower *const U) { + std::cout << "\n\n\tF : "; + for (int i = 0; i < F->top; i++) { + std::cout << F->values[i] << "\t"; + } + std::cout << "\n\tU : "; + for (int i = 0; i < U->top; i++) { + std::cout << U->values[i] << "\t"; + } + std::cout << "\n\tT : "; + for (int i = 0; i < T->top; i++) { + std::cout << T->values[i] << "\t"; + } } -void mov(tower &From, tower &To) -{ - --From.top; - To.values[To.top] = From.values[From.top]; - ++To.top; +/** Move one disc from one tower to another + * \param [in,out] From tower to move disk *from* + * \param [in,out] To tower to move disk *to* + */ +void mov(tower *From, tower *To) { + --From->top; + To->values[To->top] = From->values[From->top]; + ++To->top; } -void TH(int n, tower &From, tower &Using, tower &To) -{ - - if (n == 1) - { - mov(From, To); - show(); - } - else - { - TH(n - 1, From, To, Using); - mov(From, To); - show(); - TH(n - 1, Using, From, To); - } +/** + * Recursive algorithm to solve the puzzle + * \param [in] n starting number of disks + * \param [in,out] From tower to move disks from + * \param [in,out] Using temporary tower for the puzzle + * \param [in,out] To tower to move disk to + */ +void TH(int n, tower *From, tower *Using, tower *To) { + if (n == 1) { + mov(From, To); + show(From, To, Using); + } else { + TH(n - 1, From, To, Using); + mov(From, To); + show(From, To, Using); + TH(n - 1, Using, From, To); + } } -int main() -{ - F.top = 0; - U.top = 0; - T.top = 0; +/** Main function */ +int main() { + struct tower F, U, T; - int no; + F.top = 0; + U.top = 0; + T.top = 0; - cout << "\nEnter number of discs : "; - cin >> no; + int no; - for (int i = no; i > 0; i--) - { - F.values[F.top++] = i; - }; + std::cout << "\nEnter number of discs : "; + std::cin >> no; - show(); - TH(no, F, U, T); + for (int i = no; i > 0; i--) { + F.values[F.top++] = i; + } - return 0; + show(&F, &T, &U); + TH(no, &F, &U, &T); + + return 0; } diff --git a/others/vector_important_functions.cpp b/others/vector_important_functions.cpp index e0a70eeda..d23ff9c97 100644 --- a/others/vector_important_functions.cpp +++ b/others/vector_important_functions.cpp @@ -1,45 +1,43 @@ -// A C++ program to demonstrate working of sort(), -// reverse() +/** + * @file + * @brief A C++ program to demonstrate working of std::sort(), std::reverse() + */ #include #include +#include // For accumulate operation #include -#include //For accumulate operation -using namespace std; -int main() -{ - // Initializing vector with array values - int arr[] = {10, 20, 5, 23 ,42 , 15}; - int n = sizeof(arr)/sizeof(arr[0]); - vector vect(arr, arr+n); +/** Main function */ +int main() { + // Initializing vector with array values + int arr[] = {10, 20, 5, 23, 42, 15}; + int n = sizeof(arr) / sizeof(arr[0]); + std::vector vect(arr, arr + n); - cout << "Vector is: "; - for (int i=0; i #include +/** + * This function takes last element as pivot, places + * the pivot element at its correct position in sorted + * array, and places all smaller (smaller than pivot) + * to left of pivot and all greater elements to right + * of pivot + * + */ + int partition(int arr[], int low, int high) { - int pivot = arr[high]; // pivot + int pivot = arr[high]; // taking the last element as pivot int i = (low - 1); // Index of smaller element for (int j = low; j < high; j++) { @@ -21,20 +53,27 @@ int partition(int arr[], int low, int high) { return (i + 1); } +/** + * The main function that implements QuickSort + * arr[] --> Array to be sorted, + * low --> Starting index, + * high --> Ending index + */ void quickSort(int arr[], int low, int high) { if (low < high) { int p = partition(arr, low, high); - quickSort(arr, low, p - 1); quickSort(arr, p + 1, high); } } +// prints the array after sorting void show(int arr[], int size) { - for (int i = 0; i < size; i++) std::cout << arr[i] << "\n"; + for (int i = 0; i < size; i++) std::cout << arr[i] << " "; + std::cout << "\n"; } -// Driver program to test above functions +/** Driver program to test above functions */ int main() { int size; std::cout << "\nEnter the number of elements : ";