summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYidi <noob999noob999@gmail.com>2024-09-06 18:03:19 +0200
committerYidi <noob999noob999@gmail.com>2024-09-06 18:03:19 +0200
commit77997253fb0978c2f45b73982eb0926756747882 (patch)
tree40761bf5145d55fb0c8239f492c44cd3a1f08cb1
parent5c297e9939981a35b2782ff7b4f92859216fcca3 (diff)
more tests
-rw-r--r--content/other/pbs.cpp2
-rw-r--r--test/other/pbs.cpp103
-rw-r--r--test/other/pbs.cpp.awk8
-rwxr-xr-xtest/test.sh1
4 files changed, 113 insertions, 1 deletions
diff --git a/content/other/pbs.cpp b/content/other/pbs.cpp
index 6cf872a..e6ef07d 100644
--- a/content/other/pbs.cpp
+++ b/content/other/pbs.cpp
@@ -1,5 +1,5 @@
// Q = # of queries, bucket sort is sometimes faster
-vector<int> low(Q, 0), high(Q, MAX_OPERATIONS + 1);
+vector<int> low(Q, -1), high(Q, MAX_OPERATIONS);
while (true) {
vector<pair<int, int>> focus;
for (int i = 0; i < Q; i++) {
diff --git a/test/other/pbs.cpp b/test/other/pbs.cpp
new file mode 100644
index 0000000..ba3b9d0
--- /dev/null
+++ b/test/other/pbs.cpp
@@ -0,0 +1,103 @@
+#include "../util.h"
+
+struct Union {
+ vector<int> a;
+
+ Union(int n) : a(n, -1) {}
+
+ int find(int i) {
+ return a[i] < 0 ? i : a[i] = find(a[i]);
+ }
+
+ void join(int i, int j) {
+ i = find(i), j = find(j);
+ if (i == j) return;
+ a[j] = i;
+ }
+
+ bool same(int i, int j) {
+ return find(i) == find(j);
+ }
+};
+
+int n;
+Union un(0);
+void reset() {
+ un = Union(n);
+}
+
+vector<pair<int, int>> edges;
+void do_step(int i) {
+ auto [u, v] = edges[i];
+ un.join(u, v);
+}
+
+vector<pair<int, int>> queries;
+bool test(int i) {
+ auto [u, v] = queries[i];
+ return un.same(u, v);
+}
+
+#include <other/pbs.cpp>
+void stress_test() {
+ for (int it = 0; it < 100'000; it++) {
+ n = Random::integer(2, 31);
+ int Q = Random::integer(2, 31);
+ int MAX_OPERATIONS = n-1;
+
+ edges.clear();
+ for (int i=1; i<n; i++) {
+ edges.emplace_back(Random::integer(0, i), i);
+ }
+ shuffle(all(edges), Random::rng);
+ queries.clear();
+ for (int i=0; i<Q; i++) {
+ auto x = Random::distinct(2, n);
+ queries.emplace_back(x[0], x[1]);
+ }
+ vector<int> ans = pbs(Q, MAX_OPERATIONS);
+
+ vector<int> correct(Q, -1);
+ Union un2(n);
+ for (int j=0; j<MAX_OPERATIONS; j++) {
+ un2.join(edges[j].first, edges[j].second);
+ for (int k=0; k<Q; k++) if (correct[k] == -1) {
+ if (un2.same(queries[k].first, queries[k].second)) {
+ correct[k] = j;
+ }
+ }
+ }
+
+ if (ans != correct) cerr << "Failed stress test" << FAIL;
+ }
+}
+
+void performance_test() {
+ n = 300'000;
+ constexpr int Q = 300'000;
+ int MAX_OPERATIONS = n-1;
+ edges.clear();
+ for (int i=1; i<n; i++) {
+ edges.emplace_back(Random::integer(0, i), i);
+ }
+ shuffle(all(edges), Random::rng);
+ queries.clear();
+ for (int i=0; i<Q; i++) {
+ auto x = Random::distinct(2, n);
+ queries.emplace_back(x[0], x[1]);
+ }
+
+ timer t;
+ t.start();
+ vector<int> ans = pbs(Q, MAX_OPERATIONS);
+ t.stop();
+ ll hash = accumulate(all(ans), 0LL);
+
+ if (t.time > 700) cerr << "too slow: " << t.time << FAIL;
+ cerr << "tested performance: " << t.time << "ms (hash: " << hash << ")" << endl;
+}
+
+int main() {
+ stress_test();
+ performance_test();
+}
diff --git a/test/other/pbs.cpp.awk b/test/other/pbs.cpp.awk
new file mode 100644
index 0000000..3084ebd
--- /dev/null
+++ b/test/other/pbs.cpp.awk
@@ -0,0 +1,8 @@
+BEGIN { print "vector<int> pbs(int Q, int MAX_OPERATIONS) {" }
+{
+ sub(/\/\* requirement already fulfilled \*\//, "test(i)")
+ sub(/\/\/ simulation step/, "do_step(step);")
+ sub(/\/\/ reset simulation/, "reset();")
+}
+{ print }
+END { print "return high; }" }
diff --git a/test/test.sh b/test/test.sh
index 3cb5c9c..e4eecee 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -6,6 +6,7 @@ export MALLOC_PERTURB_="$((2#01011001))"
declare -A cppstandard
cppstandard["string/suffixArray.cpp"]="gnu++20"
+cppstandard["other/pbs.cpp"]="gnu++20"
seedmacro=""
process_awk() {