diff --git a/DIRECTORY.md b/DIRECTORY.md index 46cc31d94..9b059be70 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -181,6 +181,7 @@ * [Modular Division](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/modular_division.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 Bonacci](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/n_bonacci.cpp) * [N Choose R](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/n_choose_r.cpp) * [Ncr Modulo P](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/ncr_modulo_p.cpp) * [Number Of Positive Divisors](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/math/number_of_positive_divisors.cpp) diff --git a/math/n_bonacci.cpp b/math/n_bonacci.cpp new file mode 100644 index 000000000..845cad734 --- /dev/null +++ b/math/n_bonacci.cpp @@ -0,0 +1,123 @@ +/** + * @file + * @brief Implementation of the + * [N-bonacci](http://oeis.org/wiki/N-bonacci_numbers) series + * + * @details + * In general, in N-bonacci sequence, + * we generate sum of preceding N numbers from the next term. + * + * For example, a 3-bonacci sequence is the following: + * 0, 0, 1, 1, 2, 4, 7, 13, 24, 44, 81 + * In this code we take N and M as input where M is the number of terms + * to be printed of the N-bonacci series + * + * @author [Swastika Gupta](https://github.com/Swastyy) + */ + +#include /// for std::is_equal, std::swap +#include /// for assert +#include /// for IO operations +#include /// for std::vector + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { +/** + * @namespace n_bonacci + * @brief Functions for the [N-bonacci](http://oeis.org/wiki/N-bonacci_numbers) + * implementation + */ +namespace n_bonacci { +/** + * @brief Finds the N-Bonacci series for the `n` parameter value and `m` + * parameter terms + * @param n is in the N-Bonacci series + * @param m is the number of terms in the N-Bonacci sequence + * @returns the n-bonacci sequence as vector array + */ +std::vector N_bonacci(const uint64_t &n, const uint64_t &m) { + std::vector a(m, 0); // we create an empty array of size m + + a[n - 1] = 1; /// we initialise the (n-1)th term as 1 which is the sum of + /// preceding N zeros + a[n] = 1; /// similarily the sum of preceding N zeros and the (N+1)th 1 is + /// also 1 + for (uint64_t i = n + 1; i < m; i++) { + // this is an optimized solution that works in O(M) time and takes O(M) + // extra space here we use the concept of the sliding window the current + // term can be computed using the given formula + a[i] = 2 * a[i - 1] - a[i - 1 - n]; + } + return a; +} +} // namespace n_bonacci +} // namespace math + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + // n = 1 m = 1 return [1, 1] + std::cout << "1st test"; + std::vector arr1 = math::n_bonacci::N_bonacci( + 1, 1); // first input is the param n and second one is the param m for + // N-bonacci func + std::vector output_array1 = { + 1, 1}; // It is the expected output series of length m + assert(std::equal(std::begin(arr1), std::end(arr1), + std::begin(output_array1))); + std::cout << "passed" << std::endl; + + // n = 5 m = 15 return [0, 0, 0, 0, 1, 1, 2, 4, 8, 16, 31, 61, 120, 236, + // 464] + std::cout << "2nd test"; + std::vector arr2 = math::n_bonacci::N_bonacci( + 5, 15); // first input is the param n and second one is the param m for + // N-bonacci func + std::vector output_array2 = { + 0, 0, 0, 0, 1, 1, 2, 4, + 8, 16, 31, 61, 120, 236, 464}; // It is the expected output series of + // length m + assert(std::equal(std::begin(arr2), std::end(arr2), + std::begin(output_array2))); + std::cout << "passed" << std::endl; + + // n = 6 m = 17 return [0, 0, 0, 0, 0, 1, 1, 2, 4, 8, 16, 32, 63, 125, 248, + // 492, 976] + std::cout << "3rd test"; + std::vector arr3 = math::n_bonacci::N_bonacci( + 6, 17); // first input is the param n and second one is the param m for + // N-bonacci func + std::vector output_array3 = { + 0, 0, 0, 0, 0, 1, 1, 2, 4, + 8, 16, 32, 63, 125, 248, 492, 976}; // It is the expected output series + // of length m + assert(std::equal(std::begin(arr3), std::end(arr3), + std::begin(output_array3))); + std::cout << "passed" << std::endl; + + // n = 56 m = 15 return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + std::cout << "4th test"; + std::vector arr4 = math::n_bonacci::N_bonacci( + 56, 15); // first input is the param n and second one is the param m + // for N-bonacci func + std::vector output_array4 = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; // It is the expected output series of length m + assert(std::equal(std::begin(arr4), std::end(arr4), + std::begin(output_array4))); + std::cout << "passed" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // run self-test implementations + return 0; +}