This commit is contained in:
Eric Mertens 2022-11-12 15:38:52 -08:00
parent 18583a1f58
commit f073d2d826
6 changed files with 58 additions and 42 deletions

View File

@ -4,9 +4,9 @@
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <gmpxx.h>
#include <aocpp/Startup.hpp> #include <aocpp/Startup.hpp>
#include <zmod.hpp>
using namespace zmod;
using namespace aocpp; using namespace aocpp;
template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
@ -14,45 +14,6 @@ template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
namespace { namespace {
template <unsigned long Mod>
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<Mod> const& x) -> std::ostream & {
return out << x.value.get_ui();
}
};
template <typename Rep> template <typename Rep>
struct LinearFunction { struct LinearFunction {
Rep scale; Rep scale;

View File

@ -50,7 +50,7 @@ add_executable(20 20.cpp)
target_link_libraries(20 aocpp) target_link_libraries(20 aocpp)
add_executable(22 22.cpp) add_executable(22 22.cpp)
target_link_libraries(22 aocpp PkgConfig::GMP) target_link_libraries(22 aocpp zmod)
add_executable(23 23.cpp) add_executable(23 23.cpp)
target_link_libraries(23 aocpp intcode) target_link_libraries(23 aocpp intcode)

View File

@ -18,5 +18,6 @@ find_package(PkgConfig)
pkg_check_modules(GMP REQUIRED IMPORTED_TARGET gmp) pkg_check_modules(GMP REQUIRED IMPORTED_TARGET gmp)
add_subdirectory(lib) add_subdirectory(lib)
add_subdirectory(zmod)
add_subdirectory(intcode) add_subdirectory(intcode)
add_subdirectory(2019) add_subdirectory(2019)

3
zmod/CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
add_library(zmod INTERFACE)
target_link_libraries(zmod PkgConfig::GMP)
target_include_directories(zmod PUBLIC include)

50
zmod/include/zmod.hpp Normal file
View File

@ -0,0 +1,50 @@
#ifndef ZMOD_HPP_
#define ZMOD_HPP_
#include <iostream>
#include <gmpxx.h>
namespace zmod {
template <unsigned long Mod>
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<Mod> const& x) -> std::ostream & {
return out << x.value.get_ui();
}
};
}
#endif

1
zmod/src/zmod.cpp Normal file
View File

@ -0,0 +1 @@
#include <zmod.hpp>