|
1 | 1 | /**
|
2 | 2 | * @file
|
3 | | - * @brief [Factorial](https://en.wikipedia.org/wiki/Factorial) calculation using recursion and [memoization](https://en.wikipedia.org/wiki/Memoization) |
| 3 | + * @brief [Factorial](https://en.wikipedia.org/wiki/Factorial) calculation using |
| 4 | + * recursion and [memoization](https://en.wikipedia.org/wiki/Memoization) |
4 | 5 | * @details
|
5 | 6 | * This program computes the factorial of a non-negative integer using recursion
|
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 | | - * |
| 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 | + * |
15 | 13 | * Explanation: 5! = 5 ×ばつかける 4 ×ばつかける 3 ×ばつかける 2 ×ばつかける 1 =わ 120
|
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. |
| 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. |
19 | 18 | *
|
20 | 19 | * Time Complexity: O(n)
|
21 | 20 | * Space Complexity: O(n)
|
22 | | - * @author [Vedant Mukhedkar](https://github.com/git5v) |
23 | 21 | */
|
24 | 22 |
|
25 | | -#include <iostream> // for std::cout |
26 | 23 | #include <cassert> // For test cases
|
27 | | -#include <array> // For std::array |
28 | 24 | #include <cstdint> // For uint64_t
|
| 25 | +#include <vector> // For std::vector |
29 | 26 |
|
30 | | -/// Array to store computed factorials for memoization |
31 | | -std::array<uint64_t, 1000> memo{0}; |
| 27 | +classMemorisedFactorial { |
| 28 | +std::vector<std::uint64_t> known_values = {1}; |
32 | 29 |
|
33 | | -/** |
34 | | - * @namespace math |
35 | | - * @brief Math algorithms |
36 | | - */ |
37 | | -namespace math { |
| 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 | +}; |
38 | 43 |
|
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]; |
| 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); |
49 | 50 | }
|
50 | 51 |
|
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"; |
| 52 | +void test_MemorisedFactorial_no_order() { |
| 53 | + auto factorial = MemorisedFactorial(); |
| 54 | + assert(factorial(10) == 3628800); |
63 | 55 | }
|
64 | 56 |
|
65 | 57 | /**
|
66 | | - * @brief Main function to run test cases and interact with the user. |
| 58 | + * @brief Main function to run tests |
67 | 59 | * @returns 0 on program success
|
68 | 60 | */
|
69 | 61 | int main() {
|
70 | | - // Run test cases |
71 | | - test_fact_recursion(); |
| 62 | + test_MemorisedFactorial_in_order(); |
| 63 | + test_MemorisedFactorial_no_order(); |
72 | 64 | return 0;
|
73 | 65 | }
|
0 commit comments