aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-01-17 16:53:40 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2025-01-17 16:53:40 +0100
commit6cfb7b4d8e6b0838bfcde290e5fac18f46f18fb4 (patch)
tree9de2aeda48fc63652cb2fe50acd142afe4d854db
parent0b43d984905f07c59e3236d98d4e27409aba3cda (diff)
downloadtaming-cpp-6cfb7b4d8e6b0838bfcde290e5fac18f46f18fb4.tar.gz
taming-cpp-6cfb7b4d8e6b0838bfcde290e5fac18f46f18fb4.zip
Added first two zmodn versions
-rw-r--r--templates/zmodn-1.cpp55
-rw-r--r--templates/zmodn-2.cpp56
2 files changed, 111 insertions, 0 deletions
diff --git a/templates/zmodn-1.cpp b/templates/zmodn-1.cpp
new file mode 100644
index 0000000..a8e26ca
--- /dev/null
+++ b/templates/zmodn-1.cpp
@@ -0,0 +1,55 @@
1#include <iostream>
2#include <optional>
3#include <tuple>
4
5std::tuple<int, int, int> extended_gcd(int a, int b) {
6 if (b == 0) return {a, 1, 0};
7 auto [g, x, y] = extended_gcd(b, a%b);
8 return {g, y, x - y*(a/b)};
9}
10
11template<int N>
12class Zmod {
13public:
14 int value;
15
16 Zmod(int z) : value{(z%N + N) % N} {}
17 int toint() const { return value; }
18
19 Zmod operator+(const Zmod& z) const { return value + z.value; }
20 Zmod operator-(const Zmod& z) const { return value - z.value; }
21 Zmod operator*(const Zmod& z) const { return value * z.value; }
22
23 std::optional<Zmod> inverse() const {
24 auto [g, a, _] = extended_gcd(value, N);
25 return g == 1 ? Zmod(a) : std::optional<Zmod>{};
26 }
27
28 std::optional<Zmod> operator/(const Zmod& d) const {
29 auto i = d.inverse();
30 return i ? (*this) * i.value() : i;
31 }
32
33 std::optional<Zmod> operator/=(const Zmod& d) {
34 auto q = *this / d;
35 return q ? (*this = q.value()) : q;
36 }
37};
38
39int main() {
40 Zmod<57> x(34);
41 Zmod<57> y(11);
42
43 std::cout << "34 * 11 = " << (x * y).value << " (mod 57)" << std::endl;
44
45 if (auto inv = y.inverse(); inv)
46 std::cout << "11 * " << inv.value().value << " = 1 (mod 57)" << std::endl;
47 else
48 std::cout << "11 is not invertible in Z/57Z" << std::endl;
49
50
51 // The following line gives a run-time exception
52 // Zmod<0> z(157);
53
54 return 0;
55}
diff --git a/templates/zmodn-2.cpp b/templates/zmodn-2.cpp
new file mode 100644
index 0000000..f96ef8c
--- /dev/null
+++ b/templates/zmodn-2.cpp
@@ -0,0 +1,56 @@
1#include <iostream>
2#include <optional>
3#include <tuple>
4
5std::tuple<int, int, int> extended_gcd(int a, int b) {
6 if (b == 0) return {a, 1, 0};
7 auto [g, x, y] = extended_gcd(b, a%b);
8 return {g, y, x - y*(a/b)};
9}
10
11template<int N>
12requires (N > 1)
13class Zmod {
14public:
15 int value;
16
17 Zmod(int z) : value{(z%N + N) % N} {}
18 int toint() const { return value; }
19
20 Zmod operator+(const Zmod& z) const { return value + z.value; }
21 Zmod operator-(const Zmod& z) const { return value - z.value; }
22 Zmod operator*(const Zmod& z) const { return value * z.value; }
23
24 std::optional<Zmod> inverse() const {
25 auto [g, a, _] = extended_gcd(value, N);
26 return g == 1 ? Zmod(a) : std::optional<Zmod>{};
27 }
28
29 std::optional<Zmod> operator/(const Zmod& d) const {
30 auto i = d.inverse();
31 return i ? (*this) * i.value() : i;
32 }
33
34 std::optional<Zmod> operator/=(const Zmod& d) {
35 auto q = *this / d;
36 return q ? (*this = q.value()) : q;
37 }
38};
39
40int main() {
41 Zmod<57> x(34);
42 Zmod<57> y(11);
43
44 std::cout << "34 * 11 = " << (x * y).value << " (mod 57)" << std::endl;
45
46 if (auto inv = y.inverse(); inv)
47 std::cout << "11 * " << inv.value().value << " = 1 (mod 57)" << std::endl;
48 else
49 std::cout << "11 is not invertible in Z/57Z" << std::endl;
50
51
52 // Contrary to zmodn-1.cpp, the following line does not compile at all
53 Zmod<0> z(157);
54
55 return 0;
56}

Generated with cgit - Back to sebastiano.tronto.net