#ifndef AOCPP_DIVMOD_HPP_ #define AOCPP_DIVMOD_HPP_ #include #include "../doctest.h" namespace aocpp { template auto DivMod(T dividend, T divisor) -> std::pair { 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 auto Mod(T dividend, T divisor) -> T { return DivMod(dividend, divisor).second; } template auto Div(T dividend, T divisor) -> T { return DivMod(dividend, divisor).first; } TEST_SUITE("divmod.hpp") { TEST_CASE("DivMod behavior") { CHECK(DivMod(2,5) == std::make_pair(0,2)); CHECK(DivMod(-2,5) == std::make_pair(-1,3)); CHECK(DivMod(2,-5) == std::make_pair(-1,-3)); CHECK(DivMod(-2,-5) == std::make_pair(0,-2)); CHECK(DivMod(-5,-5) == std::make_pair(1,0)); CHECK(DivMod(-5,5) == std::make_pair(-1,0)); CHECK(DivMod(5,-5) == std::make_pair(-1,0)); CHECK(DivMod(-5,-5) == std::make_pair(1,0)); } } } #endif