diff options
| author | Lucas Schwebler <lucas.schwebler@gmail.com> | 2024-09-08 14:57:14 +0200 |
|---|---|---|
| committer | Lucas Schwebler <lucas.schwebler@gmail.com> | 2024-09-08 14:57:14 +0200 |
| commit | df963645ca0c5d0bed4fb9c02e93233dcfd53dae (patch) | |
| tree | 91afe44c50073d32fc6c4e7b182ca607d8463883 /test/math/minMod.cpp | |
| parent | de2c4df728e62c5761edf7d58a30f3c59d7d4d20 (diff) | |
add min mod (mimumum of linear function modulo m)
Diffstat (limited to 'test/math/minMod.cpp')
| -rw-r--r-- | test/math/minMod.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/test/math/minMod.cpp b/test/math/minMod.cpp new file mode 100644 index 0000000..e49da11 --- /dev/null +++ b/test/math/minMod.cpp @@ -0,0 +1,92 @@ +#include "../util.h" +#include <math/shortModInv.cpp> +#include <math/minMod.cpp> + +ll naiveMinMod(ll n, ll m, ll a, ll b){ + ll ans = m; + for(ll i = 0; i < n; i++){ + ans = min(ans, (a*i+b)%m); + } + return ans; +} + +ll naiveFirstVal(ll a, ll m, ll l, ll r){ + for(ll i = 0; i < m; i++){ + ll v = a*i % m; + if(l <= v && v <= r) return v; + } + return -1; +} + +void stress_test_minMod() { + ll queries = 0; + for (ll i = 0; i < 10'000; i++) { + int n = Random::integer<int>(1, 100); + int m = Random::integer<int>(1, 100); + int a = Random::integer<int>(0, m); + int b = Random::integer<int>(0, m); + ll expected = naiveMinMod(n, m, a, b); + ll got = minMod(n, m, a, b); + if (got != expected) cerr << "got: " << got << ", expected: " << expected << FAIL; + queries++; + } + cerr << "tested queries: " << queries << endl; +} + +void stress_test_firstVal() { + ll queries = 0; + for (ll i = 0; i < 10'000; i++) { + int m = Random::integer<int>(1, 100); + int a = Random::integer<int>(0, m); + int l = Random::integer<int>(0, m); + int r = Random::integer<int>(0, m); + if(l > r) swap(l, r); + ll expected = naiveFirstVal(a, m, l, r); + ll got = firstVal(a, m, l, r); + if (got != expected) cerr << a << " " << m << " " << l << " " << r << "got: " << got << ", expected: " << expected << FAIL; + queries++; + } + cerr << "tested queries: " << queries << endl; +} + +constexpr int N = 1'000'000; +void performance_test_minMod() { + timer t; + hash_t hash = 0; + for (int operations = 0; operations < N; operations++) { + ll n = Random::integer<ll>(1, 1'000'000'000); + ll m = Random::integer<ll>(1, 1'000'000'000); + ll a = Random::integer<ll>(0, m); + ll b = Random::integer<ll>(0, m); + t.start(); + hash += minMod(n, m, a, b); + t.stop(); + } + if (t.time > 750) cerr << "too slow: " << t.time << FAIL; + cerr << "tested performance: " << t.time << "ms (hash: " << hash << ")" << endl; +} + +void performance_test_firstVal() { + timer t; + hash_t hash = 0; + for (int operations = 0; operations < N; operations++) { + ll m = Random::integer<ll>(1, 1'000'000'000); + ll a = Random::integer<ll>(1, m); + ll l = Random::integer<ll>(0, m); + ll r = Random::integer<ll>(0, m); + if(l > r) swap(l, r); + t.start(); + hash += firstVal(a, m, l, r); + t.stop(); + } + if (t.time > 750) cerr << "too slow: " << t.time << FAIL; + cerr << "tested performance: " << t.time << "ms (hash: " << hash << ")" << endl; +} + +int main() { + stress_test_minMod(); + stress_test_firstVal(); + performance_test_minMod(); + performance_test_firstVal(); +} + |
