aocpp/lib/include/aocpp/DivMod.hpp
2023-01-19 21:15:23 -08:00

51 lines
1.1 KiB
C++

#ifndef AOCPP_DIVMOD_HPP_
#define AOCPP_DIVMOD_HPP_
#include <tuple>
#include "../doctest.h"
namespace aocpp {
template <typename T>
auto DivMod(T dividend, T divisor) -> std::pair<T, T>
{
auto const quotient = dividend / divisor;
auto const remainder = dividend % divisor;
if (remainder == 0 || (remainder > 0) == (divisor > 0)) {
return {quotient, remainder};
} else {
return {quotient - 1, remainder + divisor};
}
}
template <typename T>
auto Mod(T dividend, T divisor) -> T
{
return DivMod(dividend, divisor).second;
}
template <typename T>
auto Div(T dividend, T divisor) -> T
{
return DivMod(dividend, divisor).first;
}
TEST_SUITE("divmod.hpp") {
TEST_CASE("DivMod behavior") {
CHECK(DivMod<int>(2,5) == std::make_pair(0,2));
CHECK(DivMod<int>(-2,5) == std::make_pair(-1,3));
CHECK(DivMod<int>(2,-5) == std::make_pair(-1,-3));
CHECK(DivMod<int>(-2,-5) == std::make_pair(0,-2));
CHECK(DivMod<int>(-5,-5) == std::make_pair(1,0));
CHECK(DivMod<int>(-5,5) == std::make_pair(-1,0));
CHECK(DivMod<int>(5,-5) == std::make_pair(-1,0));
CHECK(DivMod<int>(-5,-5) == std::make_pair(1,0));
}
}
}
#endif