Skip to content

Commit

Permalink
Added factorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZCG-coder committed Jun 3, 2024
1 parent 14a251e commit 87fc9fb
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ SET(COMPONENTS
power
division
root
factorial
)
# NEW_COMPONENT: PATCH Do NOT remove the previous comment.

Expand Down
10 changes: 10 additions & 0 deletions include/fn/basicArithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ namespace steppable::__internals::arithmetic
*/
std::string rootIntPart(const std::string& _number, const std::string& base);

/**
* @brief Calculates the factorial of a number.
*
* @param _number The number to calculate the factorial of.
* @param steps The number of steps to calculate the factorial.
*
* @return The factorial of the number.
*/
std::string factorial(const std::string& _number, int steps = 2);

/**
* @brief Executes a given predicate function a specified number of times.
*
Expand Down
112 changes: 112 additions & 0 deletions src/factorial/factorial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**************************************************************************************************
* Copyright (c) 2023-2024 NWSOFT *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
**************************************************************************************************/

/**
* @file add.cpp
* @brief This file contains the implementation of the add function, which add two number strings together.
*
* @author Andy Zhang
* @date 9th October 2023
*/

#include "argParse.hpp"
#include "factorialReport.hpp"
#include "fn/basicArithm.hpp"
#include "output.hpp"
#include "util.hpp"

#include <algorithm>
#include <iostream>
#include <string_view>
#include <vector>

using namespace steppable::__internals::numUtils;
using namespace steppable::__internals::utils;
using namespace steppable::__internals::arithmetic;
using namespace steppable::__internals::symbols;
using namespace steppable::output;
using namespace std::literals;

namespace steppable::__internals::arithmetic
{
std::string factorial(const std::string& _number, const int steps)
{
auto number = standardizeNumber(_number);
if (not isInteger(number))
{
// We cannot evaluate integrals yet, so this has to be returned.
// Correct implementation of the gamma function should be
// / +inf
// | z-1 -s
// G(z) = | s e ds ,where z is a non-zero decimal ............ (1)
// |
// / 0
// and factorial is defined as
// n! = n * G(n) ,where n is a non-zero decimal ............ (2)
error("factorial"s, "%s is not an integer."s, number.c_str());
return "0";
}
if (isZeroString(number))
{
if (steps == 2)
return "By definition, 0! = 1";
return "1"; // By definition, 0! = 1
}
// Negative numbers do not have a factorial.
if (number.front() == '-')
{
error("factorial"s, "%s is negative."s, number.c_str());
return "0";
}

// Calculate the factorial of the number
std::string result = "1";
loop(_number, [&](const std::string& i) { result = multiply(result, add(i, "1", 0), 0); });

return reportFactorial(_number, result, steps);
}
} // namespace steppable::__internals::arithmetic

#ifndef NO_MAIN
int main(const int _argc, const char* _argv[])
{
Utf8CodePage _;
ProgramArgs program(_argc, _argv);
program.addPosArg('a', "Number");
program.addKeywordArg("steps", 2, "Amount of steps while calculating the factorial. 0 = No steps, 2 = All steps.");
program.addSwitch("profile", false, "profiling the program");
program.parseArgs();

const int steps = program.getKeywordArgument("steps");
const bool profile = program.getSwitch("profile");
const auto& number = static_cast<std::string>(program.getPosArg(0));

if (profile)
{
TIC(Factorial)
std::cout << "Factorial :\n" << factorial(number, steps) << '\n';
TOC()
}
else
std::cout << factorial(number, steps) << '\n';
}
#endif
48 changes: 48 additions & 0 deletions src/factorial/factorialReport.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**************************************************************************************************
* Copyright (c) 2023-2024 NWSOFT *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
**************************************************************************************************/

#include "factorialReport.hpp"

#include "fn/basicArithm.hpp"
#include "symbols.hpp"

#include <sstream>
#include <string>

using namespace steppable::__internals::arithmetic;
using namespace steppable::__internals::symbols;

std::string reportFactorial(const std::string& number, const std::string& result, int steps)
{
if (steps == 0)
return result;

// In this case, steps == 2 is equivalent to steps == 1.
std::stringstream ss;
loop(number, [&](const auto& item) { ss << add(item, "1", 0) << " " << MULTIPLY << " "; });
auto out = ss.str();

out.erase(out.end() - 3, out.end()); // Remove the last " * "
out += " = " + result;

return out;
}
35 changes: 35 additions & 0 deletions src/factorial/factorialReport.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**************************************************************************************************
* Copyright (c) 2023-2024 NWSOFT *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
**************************************************************************************************/

#pragma once

#include <string>

/**
* @brief Report the factorial calculation.
*
* @param number The number to calculate the factorial of.
* @param result The result of the factorial calculation.
* @param steps The number of steps taken to calculate the factorial.
* @return std::string The report of the factorial calculation.
*/
std::string reportFactorial(const std::string& number, const std::string& result, int steps);
38 changes: 38 additions & 0 deletions tests/testFactorial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**************************************************************************************************
* Copyright (c) 2023-2024 NWSOFT *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
**************************************************************************************************/

#include "colors.hpp"
#include "fn/basicArithm.hpp"
#include "output.hpp"
#include "testing.hpp"
#include "util.hpp"

#include <iomanip>
#include <iostream>

using namespace steppable::__internals::arithmetic;

TEST_START()
SECTION(Factorial)
_.assertIsEqual(factorial("5", 0), "120");
SECTION_END()
TEST_END()

0 comments on commit 87fc9fb

Please sign in to comment.