|
1 | 1 | /**
|
2 | 2 | * @file
|
3 |
| - * @brief [Factorial](https://en.wikipedia.org/wiki/Factorial) calculation using |
4 |
| - * recursion and [memoization](https://en.wikipedia.org/wiki/Memoization) |
| 3 | + * @brief [Factorial](https://en.wikipedia.org/wiki/Factorial) calculation using recursion and [memoization](https://en.wikipedia.org/wiki/Memoization) |
5 | 4 | * @details
|
6 | 5 | * This program computes the factorial of a non-negative integer using recursion
|
7 |
| - * with memoization (top-down dynamic programming). It stores intermediate |
8 |
| - * results to avoid redundant calculations for improved efficiency. |
9 |
| - * |
10 |
| - * Memoization is a form of caching where the result to an expensive function |
11 |
| - * call is stored and returned. Example: Input: n = 5 Output: 120 |
12 |
| - * |
| 6 | + * with memoization (top-down dynamic programming). It stores intermediate results |
| 7 | + * to avoid redundant calculations for improved efficiency. |
| 8 | + * |
| 9 | + * Memoization is a form of caching where the result to an expensive function call |
| 10 | + * is stored and returned. |
| 11 | + * Example: |
| 12 | + * Input: n = 5 |
| 13 | + * Output: 120 |
| 14 | + * |
13 | 15 | * Explanation: 5! = 5 × 4 × 3 × 2 × 1 = 120
|
14 |
| - * |
15 |
| - * The program uses a recursive function which caches computed |
16 |
| - * results in a memo array to avoid recalculating factorials for the same |
17 |
| - * numbers. |
| 16 | + * |
| 17 | + * The program uses a recursive function fact_recursion which caches computed |
| 18 | + * results in a memo array to avoid recalculating factorials for the same numbers. |
18 | 19 | *
|
19 | 20 | * Time Complexity: O(n)
|
20 | 21 | * Space Complexity: O(n)
|
| 22 | + * @author [Vedant Mukhedkar](https://github.com/git5v) |
21 | 23 | */
|
22 | 24 |
|
| 25 | +#include <iostream> // for std::cout |
23 | 26 | #include <cassert> // For test cases
|
| 27 | +#include <array> // For std::array |
24 | 28 | #include <cstdint> // For uint64_t
|
25 |
| -#include <vector> // For std::vector |
26 | 29 |
|
27 |
| -class MemorisedFactorial { |
28 |
| - std::vector<std::uint64_t> known_values = {1}; |
| 30 | +/// Array to store computed factorials for memoization |
| 31 | +std::array<uint64_t, 1000> memo{0}; |
29 | 32 |
|
30 |
| - public: |
31 |
| - /** |
32 |
| - * @note This function was intentionally written as recursive |
33 |
| - * and it does not handle overflows. |
34 |
| - * @returns factorial of n |
35 |
| - */ |
36 |
| - std::uint64_t operator()(std::uint64_t n) { |
37 |
| - if (n >= this->known_values.size()) { |
38 |
| - this->known_values.push_back(n * this->operator()(n - 1)); |
39 |
| - } |
40 |
| - return this->known_values.at(n); |
41 |
| - } |
42 |
| -}; |
| 33 | +/** |
| 34 | + * @namespace math |
| 35 | + * @brief Math algorithms |
| 36 | + */ |
| 37 | +namespace math { |
43 | 38 |
|
44 |
| -void test_MemorisedFactorial_in_order() { |
45 |
| - auto factorial = MemorisedFactorial(); |
46 |
| - assert(factorial(0) == 1); |
47 |
| - assert(factorial(1) == 1); |
48 |
| - assert(factorial(5) == 120); |
49 |
| - assert(factorial(10) == 3628800); |
| 39 | +/** |
| 40 | + * @brief Computes the factorial of a non-negative integer using recursion and memoization. |
| 41 | + * @param n The integer whose factorial is to be computed |
| 42 | + * @returns The factorial of n |
| 43 | + */ |
| 44 | +uint64_t fact_recursion(uint64_t n) { |
| 45 | + if (n == 0) return 1; // Base case: 0! = 1 |
| 46 | + if (memo[n] != 0) return memo[n]; // Return already computed value |
| 47 | + memo[n] = n * fact_recursion(n - 1); // Store and return the computed value |
| 48 | + return memo[n]; |
50 | 49 | }
|
51 | 50 |
|
52 |
| -void test_MemorisedFactorial_no_order() { |
53 |
| - auto factorial = MemorisedFactorial(); |
54 |
| - assert(factorial(10) == 3628800); |
| 51 | +} // namespace math |
| 52 | +/** |
| 53 | + * @brief Self-test implementations for the fact_recursion function. |
| 54 | + * @returns void |
| 55 | + */ |
| 56 | +void test_fact_recursion() { |
| 57 | + // Test cases for factorial computation |
| 58 | + assert(math::fact_recursion(0) == 1); |
| 59 | + assert(math::fact_recursion(1) == 1); |
| 60 | + assert(math::fact_recursion(5) == 120); |
| 61 | + assert(math::fact_recursion(10) == 3628800); |
| 62 | + std::cout << "All test cases passed!\n"; |
55 | 63 | }
|
56 | 64 |
|
57 | 65 | /**
|
58 |
| - * @brief Main function to run tests |
| 66 | + * @brief Main function to run test cases and interact with the user. |
59 | 67 | * @returns 0 on program success
|
60 | 68 | */
|
61 | 69 | int main() {
|
62 |
| - test_MemorisedFactorial_in_order(); |
63 |
| - test_MemorisedFactorial_no_order(); |
| 70 | + // Run test cases |
| 71 | + test_fact_recursion(); |
64 | 72 | return 0;
|
65 | 73 | }
|
0 commit comments