Merge branch 'TheAlgorithms:master' into master

This commit is contained in:
Muhammad Junaid Khalid
2024-10-09 19:31:36 +05:00
committed by GitHub
2 changed files with 196 additions and 47 deletions

View File

@@ -1,68 +1,65 @@
/**
* @file
* @brief Generate fibonacci sequence
* @brief n-th [Fibonacci
* number](https://en.wikipedia.org/wiki/Fibonacci_sequence).
*
* Calculate the the value on Fibonacci's sequence given an
* integer as input.
* @details
* Naive recursive implementation to calculate the n-th Fibonacci number.
* \f[\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)\f]
*
* @see fibonacci_large.cpp, fibonacci_fast.cpp, string_fibonacci.cpp
*/
#include <cassert>
#include <iostream>
#include <cassert> /// for assert
#include <iostream> /// for IO operations
/**
* Recursively compute sequences
* @param n input
* @returns n-th element of the Fbinacci's sequence
* @namespace math
* @brief Math algorithms
*/
namespace math {
/**
* @namespace fibonacci
* @brief Functions for Fibonacci sequence
*/
namespace fibonacci {
/**
* @brief Function to compute the n-th Fibonacci number
* @param n the index of the Fibonacci number
* @returns n-th element of the Fibonacci's sequence
*/
uint64_t fibonacci(uint64_t n) {
/* If the input is 0 or 1 just return the same
This will set the first 2 values of the sequence */
// If the input is 0 or 1 just return the same (Base Case)
// This will set the first 2 values of the sequence
if (n <= 1) {
return n;
}
/* Add the last 2 values of the sequence to get next */
// Add the preceding 2 values of the sequence to get next
return fibonacci(n - 1) + fibonacci(n - 2);
}
} // namespace fibonacci
} // namespace math
/**
* @brief Self-test implementation
* @returns `void`
*/
static void test() {
assert(math::fibonacci::fibonacci(0) == 0);
assert(math::fibonacci::fibonacci(1) == 1);
assert(math::fibonacci::fibonacci(2) == 1);
assert(math::fibonacci::fibonacci(3) == 2);
assert(math::fibonacci::fibonacci(4) == 3);
assert(math::fibonacci::fibonacci(15) == 610);
assert(math::fibonacci::fibonacci(20) == 6765);
std::cout << "All tests have passed successfully!\n";
}
/**
* Function for testing the fibonacci() function with a few
* test cases and assert statement.
* @returns `void`
*/
static void test() {
uint64_t test_case_1 = fibonacci(0);
assert(test_case_1 == 0);
std::cout << "Passed Test 1!" << std::endl;
uint64_t test_case_2 = fibonacci(1);
assert(test_case_2 == 1);
std::cout << "Passed Test 2!" << std::endl;
uint64_t test_case_3 = fibonacci(2);
assert(test_case_3 == 1);
std::cout << "Passed Test 3!" << std::endl;
uint64_t test_case_4 = fibonacci(3);
assert(test_case_4 == 2);
std::cout << "Passed Test 4!" << std::endl;
uint64_t test_case_5 = fibonacci(4);
assert(test_case_5 == 3);
std::cout << "Passed Test 5!" << std::endl;
uint64_t test_case_6 = fibonacci(15);
assert(test_case_6 == 610);
std::cout << "Passed Test 6!" << std::endl << std::endl;
}
/// Main function
* @brief Main function
* @returns 0 on exit
*/
int main() {
test();
int n = 0;
std::cin >> n;
assert(n >= 0);
std::cout << "F(" << n << ")= " << fibonacci(n) << std::endl;
test(); // run self-test implementations
return 0;
}

View File

@@ -0,0 +1,152 @@
/**
* @file
* @brief Insertion Sort Algorithm
* @author [Dhanush S](https://github.com/Fandroid745)
*
* @details
* Insertion sort is a simple sorting algorithm that builds the final
* sorted array one element at a time. It is much less efficient compared
* to other sorting algorithms like heap sort, merge sort, or quick sort.
*
* However, it has several advantages:
* - Easy to implement.
* - Efficient for small data sets.
* - More efficient than other O(n²) algorithms like selection sort or bubble sort.
* - Stable: it does not change the relative order of elements with equal keys.
*
* Insertion sort works similarly to how people sort playing cards in their hands.
* The algorithm iterates through the list and inserts each element into its correct
* position in the sorted portion of the array.
*
* The time complexity of the algorithm is \f$O(n^2)\f$, and in some cases, it
* can be \f$O(n)\f$.
*
* Example execution:
* 1. Start with the array [4, 3, 2, 5, 1].
* 2. Insert 3 in its correct position: [3, 4, 2, 5, 1].
* 3. Insert 2: [2, 3, 4, 5, 1].
* 4. Continue this until the array is sorted: [1, 2, 3, 4, 5].
*/
#include <algorithm> /// for std::is_sorted
#include <cassert> /// for assert function in testing
#include <iostream> /// for std::cout and std::endl
#include <vector> /// for using std::vector
/**
* @namespace sorting
* @brief Contains sorting algorithms
*/
namespace sorting {
/**
* @brief Insertion Sort Function
*
* @tparam T Type of the array elements
* @param[in,out] arr Array to be sorted
* @param n Size of the array
*/
template <typename T>
void insertionSort(T *arr, int n) {
for (int i = 1; i < n; i++) {
T temp = arr[i];
int j = i - 1;
while (j >= 0 && temp < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
/**
* @brief Insertion Sort for a vector
*
* @tparam T Type of the vector elements
* @param [in,out] arr Pointer to the vector to be sorted
*/
template <typename T>
void insertionSort(std::vector<T> *arr) {
size_t n = arr->size();
for (size_t i = 1; i < n; i++) {
T temp = arr->at(i);
int32_t j = i - 1;
while (j >= 0 && temp < arr->at(j)) {
arr->at(j + 1) = arr->at(j);
j--;
}
arr->at(j + 1) = temp;
}
}
} // namespace sorting
/**
* @brief Helper function to create a random array
*
* @tparam T Type of the array elements
* @param arr Array to fill (must be pre-allocated)
* @param N Number of elements in the array
*/
template <typename T>
static void create_random_array(T *arr, int N) {
while (N--) {
double r = (std::rand() % 10000 - 5000) / 100.f;
arr[N] = static_cast<T>(r);
}
}
/**
* @brief self test implementation
* @return void
*/
static void tests() {
int arr1[10] = {78, 34, 35, 6, 34, 56, 3, 56, 2, 4};
std::cout << "Test 1... ";
sorting::insertionSort(arr1, 10);
assert(std::is_sorted(arr1, arr1 + 10));
std::cout << "passed" << std::endl;
int arr2[5] = {5, -3, 7, -2, 1};
std::cout << "Test 2... ";
sorting::insertionSort(arr2, 5);
assert(std::is_sorted(arr2, arr2 + 5));
std::cout << "passed" << std::endl;
float arr3[5] = {5.6, -3.1, -3.0, -2.1, 1.8};
std::cout << "Test 3... ";
sorting::insertionSort(arr3, 5);
assert(std::is_sorted(arr3, arr3 + 5));
std::cout << "passed" << std::endl;
std::vector<float> arr4({5.6, -3.1, -3.0, -2.1, 1.8});
std::cout << "Test 4... ";
sorting::insertionSort(&arr4);
assert(std::is_sorted(std::begin(arr4), std::end(arr4)));
std::cout << "passed" << std::endl;
int arr5[50];
std::cout << "Test 5... ";
create_random_array(arr5, 50);
sorting::insertionSort(arr5, 50);
assert(std::is_sorted(arr5, arr5 + 50));
std::cout << "passed" << std::endl;
float arr6[50];
std::cout << "Test 6... ";
create_random_array(arr6, 50);
sorting::insertionSort(arr6, 50);
assert(std::is_sorted(arr6, arr6 + 50));
std::cout << "passed" << std::endl;
}
/**
* @brief Main function
* @return 0 on successful exit.
*/
int main() {
tests(); /// run self test implementations
return 0;
}