diff options
Diffstat (limited to 'zmodn.h')
| -rw-r--r-- | zmodn.h | 25 |
1 files changed, 20 insertions, 5 deletions
| @@ -7,16 +7,31 @@ | |||
| 7 | #include <tuple> | 7 | #include <tuple> |
| 8 | #include <type_traits> | 8 | #include <type_traits> |
| 9 | 9 | ||
| 10 | template<typename INT> | 10 | template<typename T> |
| 11 | requires std::is_integral_v<INT> | 11 | concept Integer = requires(T a, T b, int i, std::ostream& os) { |
| 12 | std::tuple<INT, INT, INT> extended_gcd(INT a, INT b) { | 12 | {T(i)}; |
| 13 | |||
| 14 | {a + b} -> std::same_as<T>; | ||
| 15 | {a - b} -> std::same_as<T>; | ||
| 16 | {a * b} -> std::same_as<T>; | ||
| 17 | {a / b} -> std::same_as<T>; | ||
| 18 | {a % b} -> std::same_as<T>; | ||
| 19 | |||
| 20 | {a == b} -> std::same_as<bool>; | ||
| 21 | {a != b} -> std::same_as<bool>; | ||
| 22 | |||
| 23 | {os << a} -> std::same_as<std::ostream&>; | ||
| 24 | }; | ||
| 25 | |||
| 26 | template<Integer T> | ||
| 27 | std::tuple<T, T, T> extended_gcd(T a, T b) { | ||
| 13 | if (b == 0) return {a, 1, 0}; | 28 | if (b == 0) return {a, 1, 0}; |
| 14 | auto [g, x, y] = extended_gcd(b, a%b); | 29 | auto [g, x, y] = extended_gcd(b, a%b); |
| 15 | return {g, y, x - y*(a/b)}; | 30 | return {g, y, x - y*(a/b)}; |
| 16 | } | 31 | } |
| 17 | 32 | ||
| 18 | template<auto N> | 33 | template<Integer auto N> |
| 19 | requires(N > 1) && std::is_integral_v<decltype(N)> | 34 | requires(N > 1) |
| 20 | class Zmod { | 35 | class Zmod { |
| 21 | public: | 36 | public: |
| 22 | Zmod(decltype(N) z) : value{(z%N + N) % N} {} | 37 | Zmod(decltype(N) z) : value{(z%N + N) % N} {} |
