Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions math/collatz_conjecture.cpp
Original file line number Diff line number Diff line change
@@ -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 <cassert> /// for assert
#include <iostream> /// for std::cout
#include <vector> /// 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<uint64_t> collatz_sequence(uint64_t n) {
std::vector<uint64_t> 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<uint64_t> 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;
}
72 changes: 72 additions & 0 deletions math/lucas_numbers.cpp
Original file line number Diff line number Diff line change
@@ -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 <cassert> /// for assert
#include <cstdint> /// for uint64_t
#include <iostream> /// 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;
}