Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

テストケース追加(Issue 1017) #1042

Closed
wants to merge 18 commits into from
29 changes: 29 additions & 0 deletions math/gcd_of_gaussian_integers/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <vector>
#include <utility>
#include <stdint.h>
#include <inttypes.h>
#include "testlib.h"

using namespace std;

int main(int argc, char* argv[]) {
setName("compare sequences of tokens");
registerTestlibCmd(argc, argv);

int T = inf.readInt();

for (int t = 0; t < T; ++t) {
int ouf_a = ouf.readInt();
int ouf_b = ouf.readInt();
int ans_a = ans.readInt();
int ans_b = ans.readInt();
bool ok = 0;
for (int i = 0; i < 4; ++i) {
tie(ans_a, ans_b) = make_pair(ans_b, -ans_a);
if (ouf_a == ans_a && ouf_b == ans_b) ok = 1;
}
if (!ok) { quitf(_wa, "wa, gcd is not correct"); }
}
quitf(_ok, "OK");
return 0;
}
69 changes: 69 additions & 0 deletions math/gcd_of_gaussian_integers/gaussian.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include <tuple>

template <typename T, typename U>
T floor(T x, U y) {
return (x > 0 ? x / y : (x - y + 1) / y);
}

template <typename T>
struct Gaussian_Integer {
T x, y;
using G = Gaussian_Integer;

Gaussian_Integer(T x = 0, T y = 0) : x(x), y(y) {}
Gaussian_Integer(pair<T, T> p) : x(p.fi), y(p.se) {}

T norm() const { return x * x + y * y; }
G conjugate() const { return G(x, -y); }

G &operator+=(const G &g) {
x += g.x, y += g.y;
return *this;
}
G &operator-=(const G &g) {
x -= g.x, y -= g.y;
return *this;
}
G &operator*=(const G &g) {
tie(x, y) = make_pair(x * g.x - y * g.y, x * g.y + y * g.x);
return *this;
}
G &operator/=(const G &g) {
*this *= g.conjugate();
T n = g.norm();
x = floor(x + n / 2, n);
y = floor(y + n / 2, n);
return *this;
}
G &operator%=(const G &g) {
auto q = G(*this) / g;
q *= g;
(*this) -= q;
return *this;
}
G operator-() { return G(-x, -y); }
G operator+(const G &g) { return G(*this) += g; }
G operator-(const G &g) { return G(*this) -= g; }
G operator*(const G &g) { return G(*this) *= g; }
G operator/(const G &g) { return G(*this) /= g; }
G operator%(const G &g) { return G(*this) %= g; }
bool operator==(const G &g) { return (x == g.x && y == g.y); }

static G gcd(G a, G b) {
while (b.x != 0 || b.y != 0) {
a %= b;
swap(a, b);
}
return a;
}

// (g,x,y) s.t ax+by=g
static tuple<G, G, G> extgcd(G a, G b) {
if (b.x != 0 || b.y != 0) {
G q = a / b;
auto [g, x, y] = extgcd(b, a - q * b);
return {g, y, x - q * y};
}
return {a, G{1, 0}, G{0, 0}};
}
};
9 changes: 9 additions & 0 deletions math/gcd_of_gaussian_integers/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
8
8 0 6 0
0 0 0 0
0 0 4 8
4 0 6 2
1 2 3 4
1 -2 3 4
1 -3 5 -7
-344235 225420 -33882 162741
30 changes: 30 additions & 0 deletions math/gcd_of_gaussian_integers/gen/fibonacci_like.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <iostream>
#include <vector>
#include <tuple>

#include "../params.h"
#include "random.h"

using namespace std;
using ll = long long;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int T = T_MAX;
printf("%d\n", T);
for (int t = 0; t < T; ++t) {
ll a = 1, b = 0, c = 0, d = 0;
while (1) {
int k = gen.uniform<int>(0, 3);
for (int i = 0; i < k; ++i) { tie(a, b) = make_pair(b, -a); }
ll aa = c + a, bb = d + b, cc = a, dd = b;
if (min<ll>({aa, bb, cc, dd}) < MIN) break;
if (max<ll>({aa, bb, cc, dd}) > MAX) break;
a = aa, b = bb, c = cc, d = dd;
}
printf("%lld %lld %lld %lld\n", a, b, c, d);
}
return 0;
}
38 changes: 38 additions & 0 deletions math/gcd_of_gaussian_integers/gen/large_gcd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <iostream>
#include <vector>
#include <tuple>

#include "../params.h"
#include "random.h"

using namespace std;
using ll = long long;

#include "../gaussian.hpp"

using G = Gaussian_Integer<ll>;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

ll LIM1 = 1000;
ll LIM2 = 1000000 / 2;

auto gen_gauss = [&](ll LIM) -> G {
ll x = gen.uniform<int>(-LIM, LIM);
ll y = gen.uniform<int>(-LIM, LIM);
return G{x, y};
};

int T = T_MAX;
printf("%d\n", T);
for (int t = 0; t < T; ++t) {
G g = gen_gauss(LIM2);
G a = gen_gauss(LIM1);
G b = gen_gauss(LIM1);
a *= g, b *= g;
printf("%lld %lld %lld %lld\n", a.x, a.y, b.x, b.y);
}
return 0;
}
24 changes: 24 additions & 0 deletions math/gcd_of_gaussian_integers/gen/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>
#include <vector>
#include <tuple>

#include "../params.h"
#include "random.h"

using namespace std;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);

int T = T_MAX;
printf("%d\n", T);
for (int t = 0; t < T; ++t) {
int a = gen.uniform<int>(MIN, MAX);
int b = gen.uniform<int>(MIN, MAX);
int c = gen.uniform<int>(MIN, MAX);
int d = gen.uniform<int>(MIN, MAX);
printf("%d %d %d %d\n", a, b, c, d);
}
return 0;
}
32 changes: 32 additions & 0 deletions math/gcd_of_gaussian_integers/gen/small.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <iostream>
#include <vector>
#include <tuple>

#include "../params.h"
#include "random.h"

using namespace std;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
// auto gen = Random(seed); つかわない

const int LIM = 10;
vector<tuple<int, int, int, int>> problems;
for (int a = -LIM; a <= LIM; ++a) {
for (int b = -LIM; b <= LIM; ++b) {
for (int c = -LIM; c <= LIM; ++c) {
for (int d = -LIM; d <= LIM; ++d) {
if ((a + b + c + d + seed) % 2 == 0)
problems.emplace_back(a, b, c, d);
}
}
}
}

int t = problems.size();
assert(1 <= t && t <= T_MAX);
printf("%d\n", t);
for (auto& [a, b, c, d]: problems) { printf("%d %d %d %d\n", a, b, c, d); }
return 0;
}
26 changes: 26 additions & 0 deletions math/gcd_of_gaussian_integers/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"example_00.in": "7dc4086ba8bec80ef0442494f94ecc4a3c75c95a254541287dc5cf510505e798",
"example_00.out": "92d60e96fca7f75cecea6765a1f5c6ef19ad8dbdcf8bd143bc68e532d136dde3",
"fibonacci_like_00.in": "ef21064f421a0b2a0315a720191616108a9e0ae88c6497f9dd731236ace1c772",
"fibonacci_like_00.out": "902c656dda476a0a456e7dd4caf007959b880058822049d404db3d8c6ab5d154",
"fibonacci_like_01.in": "c59c734522884d8cf794590b4ed3e3242d0cb6a0eaab2ad5ef106fc0a9d46cf2",
"fibonacci_like_01.out": "628b2d4bf31bd31c1ef8c7742d82d3605f2e28986ed2760e7f5c5e1277f8245b",
"large_gcd_00.in": "d9478f45c4f0190fc3cd3542eb6b1532511435940b5f145568479ab489a98085",
"large_gcd_00.out": "98db471072ba552e365fd63092889aa3db929b72071eabd6a903e5149ad657f7",
"large_gcd_01.in": "14ac6874495297c0018908bdedf7091f99e86321959d7e3bc31930e2b36d9fb8",
"large_gcd_01.out": "2d6dcdbfe2b7ed410e86d8d5bf3938db4dc85bda29ac9f9b2587233b71093b59",
"random_00.in": "6e05b9b9b6b78ab540355def3a15b5b66e46d4eac200f862b76b978e5ca13120",
"random_00.out": "e20fac6eb4c1896334f2b27b4872e3d4ae54160eda5f43b4820d0b0b5d657ccb",
"random_01.in": "dfc10c33c94add6e5634143aecd6e6bf9af5e75980d8d4241a46f2ca005e3415",
"random_01.out": "0d529841ac84c6f6ccebd368f51e31153ebdbe7c5508220f47d309e94744a5ac",
"random_02.in": "a041c3e17d097ebe215e9fd21e92904780812384aafd862f358251b656aa021b",
"random_02.out": "8435c8d791ac6ac2c119d794acecbb744b0fcb96dd6d230f5af352d3fd083099",
"random_03.in": "28eb47c73ecd35f46a5f9fb4b93d225fba69e0f17950eb13db5c6f716abcf0d1",
"random_03.out": "e0f22148a4831745357cded508e63b54883166e52ae5dc73c39fe30a9e5890ad",
"random_04.in": "b6077663099db878634f78b06e4ac5e113057e4e2ed4b8292bc6c2f868952f86",
"random_04.out": "902772158b1abb1aaee812016737848b4f932eb9b5a98f99c534f21f343e5444",
"small_00.in": "3cbe5b6a235266af934850e3d27399a6e9ee4785dbe017f9a8be49bb72d4a52d",
"small_00.out": "62f870f657880fbffa49257dc28ff258fa553744cc6fed47a05ad3463d7af4da",
"small_01.in": "fa819ca05c040e2e8861bb418dfdfa2af2846b5d6d548daf57e03a7a7723b66b",
"small_01.out": "4b1063c4c397b40d8a6733bfd2a232ea128b54605059285c7bc34733711e5b5e"
}
32 changes: 32 additions & 0 deletions math/gcd_of_gaussian_integers/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
title = 'Gcd of Gaussian Integers'
timelimit = 5.0
forum = "https://github.com/yosupo06/library-checker-problems/issues/958"

[[tests]]
name = "example.in"
number = 1

[[tests]]
name = "small.cpp"
number = 2

[[tests]]
name = "random.cpp"
number = 5

[[tests]]
name = "fibonacci_like.cpp"
number = 2

[[tests]]
name = "large_gcd.cpp"
number = 2

[[solutions]]
name = "random_correct.cpp"
wrong = false

[params]
T_MAX = 100000
MIN = -1000000000
MAX = 1000000000
29 changes: 29 additions & 0 deletions math/gcd_of_gaussian_integers/sol/correct.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <cstdio>
#include <vector>
#include <cassert>

using namespace std;
using ll = long long;

#include "../gaussian.hpp"

using G = Gaussian_Integer<ll>;

int main() {
int T;
scanf("%d", &T);

for (int t = 0; t < T; ++t) {
ll a1, b1, a2, b2;
scanf("%lld %lld %lld %lld", &a1, &b1, &a2, &b2);
G a(a1, b1);
G b(a2, b2);
auto [g, x, y] = G::extgcd(a, b);
assert(a * x + b * y == g);
assert((g == G{0, 0} && a == G{0, 0}) || (a % g == 0));
assert((g == G{0, 0} && b == G{0, 0}) || (b % g == 0));
printf("%lld %lld\n", g.x, g.y);
}

return 0;
}
32 changes: 32 additions & 0 deletions math/gcd_of_gaussian_integers/sol/random_correct.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <cstdio>
#include <vector>
#include <cassert>

using namespace std;
using ll = long long;

#include "../gaussian.hpp"

using G = Gaussian_Integer<ll>;

int main() {
int T;
scanf("%d", &T);

G I{0, 1};

for (int t = 0; t < T; ++t) {
ll a1, b1, a2, b2;
scanf("%lld %lld %lld %lld", &a1, &b1, &a2, &b2);
G a(a1, b1);
G b(a2, b2);
auto [g, x, y] = G::extgcd(a, b);
assert(a * x + b * y == g);
assert((g == G{0, 0} && a == G{0, 0}) || (a % g == 0));
assert((g == G{0, 0} && b == G{0, 0}) || (b % g == 0));
for (int i = 0; i < t % 4; ++i) { g *= I; }
printf("%lld %lld\n", g.x, g.y);
}

return 0;
}
65 changes: 65 additions & 0 deletions math/gcd_of_gaussian_integers/task.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
## @{keyword.statement}

@{lang.en}
In this problem, $i$ represents the imaginary unit.

Given Gaussian integers $a_1+b_1i$ and $a_2+b_2i$, find one of their greatest common divisors.

Please refer to the following definitions for Gaussian integers and their greatest common divisors:

- An element of $\mathbb{Z}[i] = \lbrace a+bi\mid a,b\in \mathbb{Z}\rbrace$ is called a Gaussian integer.

- For $x, y \in \mathbb{Z}[i]$, we define $x\mid y$ if there exists a $z$ in $\mathbb{Z}[i]$ such that $y = xz$.

- A Gaussian integer $g$ is a greatest common divisor of $x, y\in \mathbb{Z}[i]$ if, for any $z$ in $\mathbb{Z}[i]$, the condition $z\mid g$ is equivalent to $z\mid x$ and $z\mid y$. Such a $g$ is uniquely determined except for multiples of $\pm 1$ and $\pm i$.

You have $T$ test cases to solve.

@{lang.ja}
この問題において,$i$ は虚数単位を表します.

Gauss 整数 $a_1+b_1i, a_2+b_2i$ が与えられるので,その最大公約数(のひとつ)を求めてください.

Gauss 整数やその最大公約数については以下の定義を参考にしてください.

- $\mathbb{Z}[i] = \lbrace a+bi\mid a,b\in \mathbb{Z} \rbrace$ の元を Gauss 整数という.
- $x,y \in \mathbb{Z}[i]$ に対し,$y=xz$ となる $z \in \mathbb{Z}[i]$ が存在するとき $x\mid y$ であると定義する.
- $g \in \mathbb{Z}[i]$ が $x,y \in \mathbb{Z}[i]$ の最大公約数であるとは,任意の $z\in \mathbb{Z}[i]$ に対して,$z\mid g$ であることと $z\mid x$ かつ $z\mid y$ であることが同値になることをいう.このような $g$ は,$\pm 1$, $\pm i$ 倍の不定性を除き一意に定まる.

$T$ 個のテストケースが与えられるので,それぞれについて答えを求めてください.

@{lang.end}

## @{keyword.constraints}
- $1 \leq T \leq @{param.T_MAX}$
- $@{param.MIN} \leq a_1, b_1, a_2, b_2 \leq @{param.MAX}$

## @{keyword.input}

```
$T$
$a_1$ $b_1$ $a_2$ $b_2$
$\vdots$
$a_1$ $b_1$ $a_2$ $b_2$
```

## @{keyword.output}
@{lang.ja}
$a_1+b_1i$ と $a_2+b_2i$ の最大公約数が $a+bi$ であるとき,$a, b$ を出力してください.
@{lang.en}
When $a+bi$ is a greatest common divisor of $a_1+b_1i$ and $a_2+b_2i$, output $a$ and $b$.
@{lang.end}

```
$a$ $b$
```

## @{keyword.sample}

@{example.example_00}

@{lang.ja}
$1$ つめのテストケースについて,`2 0` の他に,`-2 0`, `0 2`, `0 -2` も正答となります.
@{lang.en}
For the first test case, in addition to `2 0`, the following answers are also correct: `-2 0`, `0 2`, and `0 -2`.
@{lang.end}
24 changes: 24 additions & 0 deletions math/gcd_of_gaussian_integers/verifier.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <iostream>

#include "params.h"
#include "testlib.h"

int main() {
registerValidation();
int T = inf.readInt(1, T_MAX);
inf.readChar('\n');

for (int t = 0; t < T; ++t) {
inf.readInt(MIN, MAX);
inf.readSpace();
inf.readInt(MIN, MAX);
inf.readSpace();
inf.readInt(MIN, MAX);
inf.readSpace();
inf.readInt(MIN, MAX);
inf.readChar('\n');
}

inf.readEof();
return 0;
}
2 changes: 1 addition & 1 deletion math/min_plus_convolution_convex_arbitrary/task.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ $$c_k = \min_{i+j=k} (a_i+b_j)$$
@{lang.ja}
整数列 $a_0, a_1, ..., a_{N - 1}$、$b_0, b_1, ..., b_{M - 1}$ が与えられます。ここで $a$ は凸です。次のように定義される整数列 $c_0, c_1, ..., c_{(N - 1) + (M - 1)}$ を求めてください。

$$c_k = \min_{i+j=k} a_ib_j$$
$$c_k = \min_{i+j=k} (a_i+b_j)$$

@{lang.end}

2 changes: 1 addition & 1 deletion math/min_plus_convolution_convex_convex/task.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ $$c_k = \min_{i+j=k} (a_i+b_j)$$
@{lang.ja}
整数列 $a_0, a_1, ..., a_{N - 1}$、$b_0, b_1, ..., b_{M - 1}$ が与えられます。ここで $a$ と $b$ は凸です。次のように定義される整数列 $c_0, c_1, ..., c_{(N - 1) + (M - 1)}$ を求めてください。

$$c_k = \min_{i+j=k} a_ib_j$$
$$c_k = \min_{i+j=k} (a_i+b_j)$$

@{lang.end}

22 changes: 22 additions & 0 deletions math/tetration_mod/gen/small_ab.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "random.h"
#include <iostream>

using namespace std;
using ll = long long;

int main(int, char* argv[]) {
long long seed = atoll(argv[1]);
auto gen = Random(seed);
int l = 10;
int t = l * l * l;
printf("%d\n", t);
for (int a = 0; a < l; a++) {
for (int b = 0; b < l; b++) {
for (int m = 1; m <= l; m++) {
int mod = gen.uniform(1LL, 1'000'000'000LL);
printf("%d %d %d\n", a, b, mod);
}
}
}
return 0;
}
8 changes: 5 additions & 3 deletions math/tetration_mod/hash.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"2_3_32_00.in": "2201a5eac58b1f044d18bd8e93ac52c296695554d4dc438a71a302ae60a6c31d",
"2_3_32_00.out": "e6c21e8d260fe71882debdb339d2402a2ca7648529bc2303f48649bce0380017",
"example_00.in": "a656c75f3fc4674755fda4c12c7a541e78c2bb6cd877a5820c5966396fdccf73",
"example_00.out": "80277aeae69bba3640d89312d1584c3a6b7c9a1bec1ebbccdf6d56cb52d2277e",
"example_01.in": "a328ed46e2dceb7f04184d61b71f96ebd19a63a6b73835b2a29e9eb8785fd2b0",
"example_01.out": "868ccaf4564d4d45e456fa19f3e9403a5eeeab9c9682d1caa427b34a96214533",
"2_3_32_00.in": "2201a5eac58b1f044d18bd8e93ac52c296695554d4dc438a71a302ae60a6c31d",
"2_3_32_00.out": "e6c21e8d260fe71882debdb339d2402a2ca7648529bc2303f48649bce0380017",
"max_00.in": "cbe52808c641625f958a98505f1723cc2e24869d9ab9e59b82d39a276e89b47b",
"max_00.out": "e36e52f693c336439495df602af57081b7335e39d6696e4c5004fcff412dccde",
"max_01.in": "3d6c908a88a4d8d5edbc9d88cd1997f543205d6ae3af401723fbaaf225eb2671",
@@ -34,5 +34,7 @@
"random_04.in": "55d86c94e704f451ae30384bb76bc7699e3f4a0bb94f9e70012b31640e96827f",
"random_04.out": "42495b3a8975e2edd34f777065353a5fa85eaa14bf67b32264c2631f86260470",
"small_00.in": "670f3cc1d60cb8f36e85a35417b8859bcf458bf447dfa30c0bc58cd20dd433bf",
"small_00.out": "acc9801b0d2f0c83131b9e89bd76eb5fcaee7e193555f59bcbf565fa53eaab0a"
"small_00.out": "acc9801b0d2f0c83131b9e89bd76eb5fcaee7e193555f59bcbf565fa53eaab0a",
"small_ab_00.in": "a46e93fa20c52079fde6f64f73f6768638f57ca7f0287a5ed84310bb7d58e2a0",
"small_ab_00.out": "f8a94948019a087a2dce5eb5489456b816aa24016fd0b12bd078eca939e75a4c"
}
3 changes: 3 additions & 0 deletions math/tetration_mod/info.toml
Original file line number Diff line number Diff line change
@@ -8,6 +8,9 @@ forum = "https://github.com/yosupo06/library-checker-problems/issues/166"
[[tests]]
name = "small.cpp"
number = 1
[[tests]]
name = "small_ab.cpp"
number = 1
[[tests]]
name = "2_3_32.in"
number = 1