diff --git a/math/collatz_conjecture.cpp b/math/collatz_conjecture.cpp new file mode 100644 index 0000000000..792c773618 --- /dev/null +++ b/math/collatz_conjecture.cpp @@ -0,0 +1,76 @@ +/** + * @file + * @brief Implementation of the Collatz Conjecture sequence. + * @details + * The Collatz Conjecture states that for any positive integer n, + * repeatedly applying the following rules will always eventually reach 1: + * - If n is even: n = n / 2 + * - If n is odd: n = 3n + 1 + * The number of steps taken to reach 1 is called the Collatz sequence length. + * Reference: https://en.wikipedia.org/wiki/Collatz_conjecture + * @author [suhavani23](https://github.com/suhavani23) + * @see fibonacci.cpp, magic_number.cpp + */ + +#include /// for assert +#include /// for std::cout +#include /// for std::vector + +/** + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { + +/** + * @brief Generates the full Collatz sequence starting from n + * @param n the starting positive integer (must be >= 1) + * @returns vector containing the full sequence ending at 1 + */ +std::vector collatz_sequence(uint64_t n) { + std::vector sequence; + while (n != 1) { + sequence.push_back(n); + if (n % 2 == 0) { + n /= 2; + } else { + n = 3 * n + 1; + } + } + sequence.push_back(1); + return sequence; +} + +/** + * @brief Counts the number of steps to reach 1 from n + * @param n the starting positive integer (must be >= 1) + * @returns number of steps taken to reach 1 + */ +uint64_t collatz_steps(uint64_t n) { return collatz_sequence(n).size() - 1; } + +} // namespace math + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + // sequence for 6: 6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1 + std::vector expected = {6, 3, 10, 5, 16, 8, 4, 2, 1}; + assert(math::collatz_sequence(6) == expected); + + assert(math::collatz_steps(1) == 0); // already at 1, zero steps + assert(math::collatz_steps(6) == 8); // 8 steps to reach 1 + assert(math::collatz_steps(27) == 111); // known result + + std::cout << "All tests have successfully passed!\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // run self-test implementations + return 0; +} \ No newline at end of file diff --git a/math/lucas_numbers.cpp b/math/lucas_numbers.cpp new file mode 100644 index 0000000000..ec80bdc381 --- /dev/null +++ b/math/lucas_numbers.cpp @@ -0,0 +1,72 @@ +/** + * @file + * @brief n-th [Lucas + * number](https://en.wikipedia.org/wiki/Lucas_number). + * + * @details + * Iterative implementation to calculate the n-th Lucas number. + * Lucas numbers are similar to Fibonacci numbers but start with 2 and 1. + * \f[\text{lucas}(n) = \text{lucas}(n-1) + \text{lucas}(n-2)\f] + * + * @see fibonacci.cpp, fibonacci_fast.cpp + */ + +#include /// for assert +#include /// for uint64_t +#include /// for IO operations + +/** + * @namespace math + * @brief Math algorithms + */ +namespace math { +/** + * @namespace lucas_numbers + * @brief Functions for Lucas number sequence + */ +namespace lucas_numbers { +/** + * @brief Function to compute the n-th Lucas number + * @param n the index of the Lucas number + * @returns n-th element of the Lucas sequence + */ +uint64_t lucas(uint64_t n) { + if (n == 0) + return 2; + if (n == 1) + return 1; + + uint64_t a = 2, b = 1; + for (uint64_t i = 2; i <= n; i++) { + uint64_t c = a + b; + a = b; + b = c; + } + return b; +} +} // namespace lucas_numbers +} // namespace math + +/** + * @brief Self-test implementation + * @returns `void` + */ +static void test() { + assert(math::lucas_numbers::lucas(0) == 2); + assert(math::lucas_numbers::lucas(1) == 1); + assert(math::lucas_numbers::lucas(2) == 3); + assert(math::lucas_numbers::lucas(3) == 4); + assert(math::lucas_numbers::lucas(4) == 7); + assert(math::lucas_numbers::lucas(5) == 11); + assert(math::lucas_numbers::lucas(6) == 18); + std::cout << "All tests have passed successfully!\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // run self-test implementations + return 0; +} \ No newline at end of file