Skip to content

Commit 17a5326

Browse files
Renjian-buchairealstealthninjaPanquesito7tjgurwara99
authored
feat: add Iterative Factorial (TheAlgorithms#2453)
* Feat: Iterative factorial * Test: Added tests for iterative factorial * Fix: Added throw when argument exceeds maximum Docs: Updated docs to to explain why maximum is 20 * Feat: iterative_factorial docs: Added documentation to some functions. test: Added exception test. * chore: Fixed formatting * docs: Added documentation, changed examples. * Update math/iterative_factorial.cpp Co-authored-by: realstealthninja <[email protected]> * Update math/iterative_factorial.cpp Co-authored-by: realstealthninja <[email protected]> * Update math/iterative_factorial.cpp Co-authored-by: David Leal <[email protected]> * Update math/iterative_factorial.cpp Co-authored-by: David Leal <[email protected]> * chore: apply suggestions from code review * Update math/iterative_factorial.cpp Co-authored-by: David Leal <[email protected]> * Update math/iterative_factorial.cpp Co-authored-by: Taj <[email protected]> * Fix: Exception test termination bug * Update math/iterative_factorial.cpp Co-authored-by: realstealthninja <[email protected]> * Update math/iterative_factorial.cpp Co-authored-by: realstealthninja <[email protected]> --------- Co-authored-by: realstealthninja <[email protected]> Co-authored-by: David Leal <[email protected]> Co-authored-by: Taj <[email protected]>
1 parent 25b9e0a commit 17a5326

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

math/iterative_factorial.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* @file
3+
* @brief Iterative implementation of
4+
* [Factorial](https://en.wikipedia.org/wiki/Factorial)
5+
*
6+
* @author [Renjian-buchai](https://github.com/Renjian-buchai)
7+
*
8+
* @details Calculates factorial iteratively.
9+
* \f[n! = n\times(n-1)\times(n-2)\times(n-3)\times\ldots\times3\times2\times1
10+
* = n\times(n-1)!\f]
11+
* for example:
12+
* \f$4! = 4\times3! = 4\times3\times2\times1 = 24\f$
13+
*
14+
* @example
15+
*
16+
* 5! = 5 * 4 * 3 * 2 * 1
17+
*
18+
* Recursive implementation of factorial pseudocode:
19+
*
20+
* function factorial(n):
21+
* if n == 1:
22+
* return 1
23+
* else:
24+
* return factorial(n-1)
25+
*
26+
*/
27+
28+
#include <cassert> /// for assert
29+
#include <cstdint> /// for integral types
30+
#include <exception> /// for std::invalid_argument
31+
#include <iostream> /// for std::cout
32+
33+
/**
34+
* @namespace
35+
* @brief Mathematical algorithms
36+
*/
37+
namespace math {
38+
39+
/**
40+
* @brief Calculates the factorial iteratively.
41+
* @param n Nth factorial.
42+
* @return Factorial.
43+
* @note 0! = 1.
44+
* @warning Maximum=20 because there are no 128-bit integers in C++. 21!
45+
* returns 1.419e+19, which is not 21! but (21! % UINT64_MAX).
46+
*/
47+
uint64_t iterativeFactorial(uint8_t n) {
48+
if (n > 20) {
49+
throw new std::invalid_argument("Maximum n value is 20");
50+
}
51+
52+
// 1 because it is the identity number of multiplication.
53+
uint64_t accumulator = 1;
54+
55+
while (n > 1) {
56+
accumulator *= n;
57+
--n;
58+
}
59+
60+
return accumulator;
61+
}
62+
63+
} // namespace math
64+
65+
/**
66+
* @brief Self-test implementations to test iterativeFactorial function.
67+
* @note There is 1 special case: 0! = 1.
68+
*/
69+
static void test() {
70+
// Special case test
71+
std::cout << "Exception case test \n"
72+
"Input: 0 \n"
73+
"Expected output: 1 \n\n";
74+
assert(math::iterativeFactorial(0) == 1);
75+
76+
// Base case
77+
std::cout << "Base case test \n"
78+
"Input: 1 \n"
79+
"Expected output: 1 \n\n";
80+
assert(math::iterativeFactorial(1) == 1);
81+
82+
// Small case
83+
std::cout << "Small number case test \n"
84+
"Input: 5 \n"
85+
"Expected output: 120 \n\n";
86+
assert(math::iterativeFactorial(5) == 120);
87+
88+
// Medium case
89+
std::cout << "Medium number case test \n"
90+
"Input: 10 \n"
91+
"Expected output: 3628800 \n\n";
92+
assert(math::iterativeFactorial(10) == 3628800);
93+
94+
// Maximum case
95+
std::cout << "Maximum case test \n"
96+
"Input: 20 \n"
97+
"Expected output: 2432902008176640000\n\n";
98+
assert(math::iterativeFactorial(20) == 2432902008176640000);
99+
100+
// Exception test
101+
std::cout << "Exception test \n"
102+
"Input: 21 \n"
103+
"Expected output: Exception thrown \n";
104+
try {
105+
math::iterativeFactorial(21);
106+
} catch (std::invalid_argument* e) {
107+
std::cout << "Exception thrown successfully \nContent: " << e->what()
108+
<< "\n";
109+
}
110+
111+
std::cout << "All tests have passed successfully.\n";
112+
}
113+
114+
/**
115+
* @brief Main function
116+
* @returns 0 on exit
117+
*/
118+
int main() {
119+
test(); // Run self-test implementation
120+
return 0;
121+
}

0 commit comments

Comments
 (0)