Skip to content

Commit

Permalink
Using Result to save calculation time of root.
Browse files Browse the repository at this point in the history
- Added ResultBase, Result and ResultBool objects.
- getRootFactors uses ResultBool to return the root of the factor along
  with the factor.
- Fixed a bug in multiply that moves more decimal places than needed if
  the input b is a decimal.
  • Loading branch information
ZCG-coder committed May 15, 2024
1 parent bf4840d commit 1a65666
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 28 deletions.
13 changes: 9 additions & 4 deletions include/factors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@

#pragma once

#include "types/result.hpp"

#include <string>
#include <vector>

using namespace steppable::types;

namespace steppable::__internals::numUtils
{
/**
Expand All @@ -40,9 +44,9 @@ namespace steppable::__internals::numUtils
*
* @param[in] _number The number to get the largest root factor of.
* @param[in] base The base of the root.
* @return The largest root factor of the number.
* @return A result object containing the largest root factor of the number.
*/
std::string getRootFactor(const std::string& _number, const std::string& base = "2");
ResultBool getRootFactor(const std::string& _number, const std::string& base = "2");

/**
* @brief Get the greatest root number less than or equal to the given number.
Expand All @@ -66,7 +70,8 @@ namespace steppable::__internals::numUtils
*
* @param[in] _number The number to check.
* @param[in] base The base of the root.
* @return True if the number is a root number, false otherwise.
* @return StatusBool::CALCULATED_SIMPLIFIED_YES if the number is a root number,
* StatusBool::CALCULATED_SIMPLIFIED_NO otherwise.
*/
bool isRoot(const std::string& _number, const std::string& base);
ResultBool isRoot(const std::string& _number, const std::string& base);
} // namespace steppable::__internals::numUtils
42 changes: 35 additions & 7 deletions include/types/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,37 @@ namespace steppable::types
/**
* @brief The status of the calculation.
*/
enum Status
enum class Status
{
CALCULATED_SIMPLIFIED,
CALCULATED_UNSIMPLIFIED,
MATH_ERROR
};

/**
* @brief The result of a calculation.
* @brief The status of a boolean calculation.
*/
class Result
enum class StatusBool
{
CALCULATED_SIMPLIFIED_YES,
CALCULATED_SIMPLIFIED_NO,
CALCULATED_UNSIMPLIFIED_YES,
CALCULATED_UNSIMPLIFIED_NO,
MATH_ERROR
};

/**
* @brief A base class for a result of a calculation. You should use the `Result` and `ResultBool` aliases instead
* of this class, which has the `Status` and `StatusBool` enums as the status type respectively.
*
* @tparam StatusType The type of the status of the calculation.
*/
template<typename StatusType>
class ResultBase
{
private:
/// @brief Whether the calculation is done.
Status done;
StatusType done;

/// @brief The inputs to the calculation.
std::vector<std::string> inputs;
Expand All @@ -58,7 +74,7 @@ namespace steppable::types
std::string out;

public:
Result() = delete;
ResultBase() = delete;

/**
* @brief Constructs a new result object.
Expand All @@ -67,12 +83,24 @@ namespace steppable::types
* @param[in] _out The output of the calculation.
* @param[in] _done A flag indicating how the calculation is done.
*/
Result(const std::vector<std::string>& _inputs, std::string _out, Status _done) :
ResultBase(const std::vector<std::string>& _inputs, std::string _out, StatusType _done) :
done(_done), inputs(_inputs), out(std::move(_out))
{
}

/// @brief Gets how the calculation is done.
Status getStatus() { return done; }
StatusType getStatus() const { return done; }

/// @brief Gets the output of the calculation.
std::string getOutput() const { return out; }

/// @brief Gets the inputs to the calculation.
std::vector<std::string> getInputs() const { return inputs; }
};

/// @brief An alias for a result of a calculation. This represents a calculation with a `Status` status.
using Result = ResultBase<Status>;

/// @brief An alias for a result of a boolean calculation.
using ResultBool = ResultBase<StatusBool>;
} // namespace steppable::types
19 changes: 13 additions & 6 deletions src/factors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
#include "factors.hpp"

#include "fn/basicArithm.hpp"
#include "types/result.hpp"

#include <algorithm>
#include <vector>

using namespace steppable::__internals::arithmetic;
using namespace steppable::types;

namespace steppable::__internals::numUtils
{
Expand All @@ -52,17 +54,20 @@ namespace steppable::__internals::numUtils
return factors;
}

std::string getRootFactor(const std::string& _number, const std::string& base)
ResultBool getRootFactor(const std::string& _number, const std::string& base)
{
auto factors = getFactors(_number);
// Reverse the factors
std::reverse(factors.begin(), factors.end());
// Get the largest root factor
for (const auto& factor : factors)
if (isRoot(factor, base))
return factor;
{
auto rootResult = isRoot(factor, base);
if (rootResult.getStatus() == StatusBool::CALCULATED_SIMPLIFIED_YES)
return { { _number, base, rootResult.getOutput() }, factor, StatusBool::CALCULATED_SIMPLIFIED_YES };
}
// The number has no root factors
return "1";
return { { _number, base }, "1", StatusBool::CALCULATED_SIMPLIFIED_YES };
}

std::string getGreatestRootNum(const std::string& _number, const std::string& base)
Expand All @@ -77,10 +82,12 @@ namespace steppable::__internals::numUtils
return factors.size() == 2; // Only 1 and the number itself are factors ==> prime!
}

bool isRoot(const std::string& _number, const std::string& base)
ResultBool isRoot(const std::string& _number, const std::string& base)
{
auto iRoot = rootIntPart(_number, base);
auto rootNum = power(iRoot, base, 0);
return compare(rootNum, _number, 0) == "2";
if (compare(rootNum, _number, 0) == "2")
return { { _number, base }, iRoot, StatusBool::CALCULATED_SIMPLIFIED_YES };
return { { _number, base }, "1", StatusBool::CALCULATED_SIMPLIFIED_NO };
}
} // namespace steppable::__internals::numUtils
10 changes: 5 additions & 5 deletions src/multiply/multiply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ namespace steppable::__internals::arithmetic
{
auto a = static_cast<std::string>(_a);
auto b = static_cast<std::string>(_b);
const auto& [splitNumberArray, aIsNegative, bIsNegative] = splitNumber(a, b, false, false);
bool resultIsNegative = false;
const auto& [aInteger, aDecimal, bInteger, bDecimal] = splitNumberArray;
std::stringstream out;
if (isZeroString(a) or isZeroString(b))
{
Expand Down Expand Up @@ -79,20 +82,17 @@ namespace steppable::__internals::arithmetic
{
if (steps == 2)
out << "Since " << a << " is a power of 10, we can move the decimal places to obtain the result.\n";
out << moveDecimalPlaces(b, static_cast<long long>(a.length() - 1));
out << moveDecimalPlaces(b, static_cast<long long>(aInteger.length() - 1));
return out.str();
}
if (isPowerOfTen(b))
{
if (steps == 2)
out << "Since " << b << " is a power of 10, we can move the decimal places to obtain the result.\n";
out << moveDecimalPlaces(a, static_cast<long long>(b.length() - 1));
out << moveDecimalPlaces(a, static_cast<long long>(bInteger.length() - 1));
return out.str();
}

const auto& [splitNumberArray, aIsNegative, bIsNegative] = splitNumber(a, b, false, false);
bool resultIsNegative = false;
const auto& [aInteger, aDecimal, bInteger, bDecimal] = splitNumberArray;
const std::string& aStr = aInteger + aDecimal;
const std::string bStr = bInteger + bDecimal;
std::vector<std::vector<int>> prodDigits;
Expand Down
4 changes: 2 additions & 2 deletions src/root/root.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ namespace steppable::__internals::arithmetic
Surd rootSurd(const std::string& _number, const std::string& base)
{
auto largestRootFactor = numUtils::getRootFactor(_number, base);
auto radicand = roundDown(divide(_number, largestRootFactor, 0, 1));
auto multiplier = rootIntPart(largestRootFactor, base);
auto radicand = roundDown(divide(_number, largestRootFactor.getOutput(), 0, 1));
auto multiplier = largestRootFactor.getInputs()[2];

return { radicand, multiplier };
}
Expand Down
8 changes: 4 additions & 4 deletions tests/testFactors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ _.assertIsEqual(getGreatestRootNum("5"), "4");
SECTION_END()

SECTION(Greatest Root Factor Test)
_.assertIsEqual(getRootFactor("24", "2"), "4");
_.assertIsEqual(getRootFactor("13", "2"), "1");
_.assertIsEqual(getRootFactor("27", "2"), "9");
_.assertIsEqual(getRootFactor("72", "2"), "36");
_.assertIsEqual(getRootFactor("24", "2").getOutput(), "4");
_.assertIsEqual(getRootFactor("13", "2").getOutput(), "1");
_.assertIsEqual(getRootFactor("27", "2").getOutput(), "9");
_.assertIsEqual(getRootFactor("72", "2").getOutput(), "36");
SECTION_END()

TEST_END()

0 comments on commit 1a65666

Please sign in to comment.