diff --git a/2019/22.cpp b/2019/22.cpp index 6faae77..de4f07a 100644 --- a/2019/22.cpp +++ b/2019/22.cpp @@ -4,9 +4,9 @@ #include #include -#include - #include +#include +using namespace zmod; using namespace aocpp; template struct overloaded : Ts... { using Ts::operator()...; }; @@ -14,45 +14,6 @@ template overloaded(Ts...) -> overloaded; namespace { -template -class ZMod { - mpz_class value; - -public: - ZMod() : value {} {} - ZMod(long value) : ZMod{mpz_class{value}} {} - ZMod(mpz_class value) { - mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod); - } - - auto operator+(ZMod const& rhs) const -> ZMod { - return {value + rhs.value}; - } - - auto operator-() const -> ZMod { - return {-value}; - } - - auto operator-(ZMod const& rhs) const -> ZMod { - return {value - rhs.value}; - } - - auto operator*(ZMod const& rhs) const -> ZMod { - return {value * rhs.value}; - } - - auto inverse() const -> ZMod { - mpz_class m{Mod}; - ZMod result; - mpz_invert(result.value.get_mpz_t(), value.get_mpz_t(), m.get_mpz_t()); - return result; - } - - auto friend operator<<(std::ostream & out, ZMod const& x) -> std::ostream & { - return out << x.value.get_ui(); -} -}; - template struct LinearFunction { Rep scale; diff --git a/2019/CMakeLists.txt b/2019/CMakeLists.txt index 6a34a30..f67ede9 100644 --- a/2019/CMakeLists.txt +++ b/2019/CMakeLists.txt @@ -50,7 +50,7 @@ add_executable(20 20.cpp) target_link_libraries(20 aocpp) add_executable(22 22.cpp) -target_link_libraries(22 aocpp PkgConfig::GMP) +target_link_libraries(22 aocpp zmod) add_executable(23 23.cpp) target_link_libraries(23 aocpp intcode) diff --git a/CMakeLists.txt b/CMakeLists.txt index 071ae73..5c33833 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,5 +18,6 @@ find_package(PkgConfig) pkg_check_modules(GMP REQUIRED IMPORTED_TARGET gmp) add_subdirectory(lib) +add_subdirectory(zmod) add_subdirectory(intcode) add_subdirectory(2019) diff --git a/zmod/CMakeLists.txt b/zmod/CMakeLists.txt new file mode 100644 index 0000000..faabdd4 --- /dev/null +++ b/zmod/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(zmod INTERFACE) +target_link_libraries(zmod PkgConfig::GMP) +target_include_directories(zmod PUBLIC include) \ No newline at end of file diff --git a/zmod/include/zmod.hpp b/zmod/include/zmod.hpp new file mode 100644 index 0000000..b784e9d --- /dev/null +++ b/zmod/include/zmod.hpp @@ -0,0 +1,50 @@ +#ifndef ZMOD_HPP_ +#define ZMOD_HPP_ + +#include +#include + +namespace zmod { + +template +class ZMod { + mpz_class value; + +public: + ZMod() : value {} {} + ZMod(long value) : ZMod{mpz_class{value}} {} + ZMod(mpz_class value) { + mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod); + } + + auto operator+(ZMod const& rhs) const -> ZMod { + return {value + rhs.value}; + } + + auto operator-() const -> ZMod { + return {-value}; + } + + auto operator-(ZMod const& rhs) const -> ZMod { + return {value - rhs.value}; + } + + auto operator*(ZMod const& rhs) const -> ZMod { + return {value * rhs.value}; + } + + auto inverse() const -> ZMod { + mpz_class m{Mod}; + ZMod result; + mpz_invert(result.value.get_mpz_t(), value.get_mpz_t(), m.get_mpz_t()); + return result; + } + + auto friend operator<<(std::ostream & out, ZMod const& x) -> std::ostream & { + return out << x.value.get_ui(); + } +}; + +} + +#endif \ No newline at end of file diff --git a/zmod/src/zmod.cpp b/zmod/src/zmod.cpp new file mode 100644 index 0000000..2ece585 --- /dev/null +++ b/zmod/src/zmod.cpp @@ -0,0 +1 @@ +#include