diff --git a/tc/test/CMakeLists.txt b/tc/test/CMakeLists.txt index a9776fc..74f7ebf 100644 --- a/tc/test/CMakeLists.txt +++ b/tc/test/CMakeLists.txt @@ -1,39 +1,18 @@ -function(add_simple_test exec arg) - add_test(NAME "${exec}_${arg}" COMMAND ${exec} ${arg}) - set_tests_properties("${exec}_${arg}" PROPERTIES TIMEOUT 5) -endfunction() +include(GoogleTest) add_executable(test_pair_map test_pair_map.cpp) -target_link_libraries(test_pair_map PUBLIC tc) -add_simple_test(test_pair_map populate) -add_simple_test(test_pair_map symmetry) -add_simple_test(test_pair_map fill) -add_simple_test(test_pair_map copy) -add_simple_test(test_pair_map move) -add_simple_test(test_pair_map iterate) -add_simple_test(test_pair_map iterate_ref) -add_simple_test(test_pair_map view) +target_link_libraries(test_pair_map tc GTest::gtest_main) add_executable(test_solve test_solve.cpp) -target_link_libraries(test_solve PUBLIC tc) -add_simple_test(test_solve A) -add_simple_test(test_solve B) -add_simple_test(test_solve D) -add_simple_test(test_solve E) -add_simple_test(test_solve F) -add_simple_test(test_solve G) -add_simple_test(test_solve H) -add_simple_test(test_solve I) -add_simple_test(test_solve T) +target_link_libraries(test_solve tc GTest::gtest_main) set(MIN_DEBUG_CPS 200000) set(MIN_RELEASE_CPS 1000000) -add_executable(test_solve_speed test_solve_speed.cpp) -target_link_libraries(test_solve_speed PUBLIC tc) -target_compile_definitions(test_solve_speed PUBLIC MINIMUM_COS_PER_SEC=$,${MIN_DEBUG_CPS},${MIN_RELEASE_CPS}>) -add_simple_test(test_solve_speed B) -set_tests_properties(test_solve_speed_B PROPERTIES TIMEOUT 60) # B8 is big. -add_simple_test(test_solve_speed E) -set_tests_properties(test_solve_speed_E PROPERTIES TIMEOUT 15) -add_simple_test(test_solve_speed T) -set_tests_properties(test_solve_speed_T PROPERTIES TIMEOUT 10) + +target_compile_definitions( + test_solve PUBLIC + MIN_COS_PER_SEC=$,${MIN_DEBUG_CPS},${MIN_RELEASE_CPS}> +) + +gtest_discover_tests(test_pair_map) +gtest_discover_tests(test_solve) diff --git a/tc/test/test_pair_map.cpp b/tc/test/test_pair_map.cpp index e3302c4..1a79054 100644 --- a/tc/test/test_pair_map.cpp +++ b/tc/test/test_pair_map.cpp @@ -4,219 +4,124 @@ #include -int test_populate() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; +#include +/// helper for comparing against two options +template +testing::AssertionResult AssertEqEither( + const char *val_expr, + const char *o1_expr, + const char *o2_expr, + T val, U o1, V o2 +) { + if ((val == o1) || (val == o2)) { + return testing::AssertionSuccess(); + } + + return testing::AssertionFailure() + << val_expr << " (" << val << ") " << "does not equal " << o1_expr + << " (" << o1 << ") " << "or " << o2_expr << " (" << o2 << ")"; +} + +#define EXPECT_EQ_EITHER(val, o1, o2) EXPECT_PRED_FORMAT3(AssertEqEither, val, o1, o2) + + +/// Naive symmetric pair hash +size_t key(size_t i, size_t j) { + return ((i + j) << 12) ^ i ^ j; +} + +/// factory to build a simple pair_map +tc::pair_map populate(size_t size) { tc::pair_map pm(6); for (int i = 0; i < pm.size(); ++i) { for (int j = i; j < pm.size(); ++j) { - pm(i, j) = f(i, j); + pm(i, j) = key(i, j); } } - for (int i = 0; i < pm.size(); ++i) { - for (int j = 0; j < pm.size(); ++j) { - if (pm(i, j) != (f(i, j))) { - std::cerr << "pm(" << i << ", " << j << ") != " << (f(i, j)) << "" << std::endl; - return EXIT_FAILURE; - } - if (pm(j, i) != (f(i, j))) { - std::cerr << "pm(" << j << ", " << i << ") != " << (f(i, j)) << "" << std::endl; - return EXIT_FAILURE; - } - } - } - - return EXIT_SUCCESS; + return pm; } -int test_symmetry() { - size_t key = 1; - tc::pair_map pm(6); - - for (int i = 0; i < pm.size(); ++i) { - for (int j = i; j < pm.size(); ++j) { - pm(i, j) = key++; - } - } - - for (int i = 0; i < pm.size(); ++i) { - for (int j = 0; j < pm.size(); ++j) { - if (pm(i, j) != pm(j, i)) { - std::cerr << "pm(" << i << ", " << j << ") != pm(" << j << ", " << i << ")" << std::endl; - return EXIT_FAILURE; - } - } - } - - return EXIT_SUCCESS; -} - -int test_fill() { +TEST(pair_map, fill) { tc::pair_map pm(6, 42); for (int i = 0; i < pm.size(); ++i) { for (int j = i; j < pm.size(); ++j) { - if (pm(i, j) != 42) { - std::cerr << "pm(" << i << ", " << j << ") != 42" << std::endl; - return EXIT_FAILURE; - } + EXPECT_EQ(pm(i, j), 42); } } - - return EXIT_SUCCESS; } -int test_copy() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; - - tc::pair_map pm(6); +TEST(pair_map, symmetry) { + auto pm = populate(6); for (int i = 0; i < pm.size(); ++i) { for (int j = i; j < pm.size(); ++j) { - pm(i, j) = f(i, j); + EXPECT_EQ(pm(i, j), key(i, j)); + EXPECT_EQ(pm(j, i), pm(i, j)); } } - - tc::pair_map cp = pm; - - for (int i = 0; i < pm.size(); ++i) { - for (int j = 0; j < pm.size(); ++j) { - if (cp(i, j) != pm(i, j)) { - std::cerr << "cp(" << i << ", " << j << ") (" << cp(i, j) << ") != pm(" << i << ", " << j << ") (" - << pm(i, j) << ")" << std::endl; - return EXIT_FAILURE; - } - } - } - - return EXIT_SUCCESS; } -int test_move() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; +TEST(pair_map, copy) { + auto pm = populate(6); + auto pm_ = pm; - tc::pair_map pm(6); + ASSERT_EQ(pm_.size(), 6); - for (int i = 0; i < pm.size(); ++i) { - for (int j = i; j < pm.size(); ++j) { - pm(i, j) = f(i, j); + for (int i = 0; i < pm_.size(); ++i) { + for (int j = i; j < pm_.size(); ++j) { + EXPECT_EQ(pm_(i, j), pm(i, j)); + EXPECT_EQ(pm_(i, j), key(i, j)); } } - - tc::pair_map cp = std::move(pm); - - for (int i = 0; i < cp.size(); ++i) { - for (int j = 0; j < cp.size(); ++j) { - if (cp(i, j) != (f(i, j))) { - std::cerr << "cp(" << i << ", " << j << ") != " << (f(i, j)) << "" << std::endl; - return EXIT_FAILURE; - } - if (cp(j, i) != (f(i, j))) { - std::cerr << "cp(" << j << ", " << i << ") != " << (f(i, j)) << "" << std::endl; - return EXIT_FAILURE; - } - } - } - - return EXIT_SUCCESS; } -int test_iterate() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; +TEST(pair_map, move) { + auto pm = populate(6); + auto pm_ = std::move(pm); - tc::pair_map pm(6); + ASSERT_EQ(pm_.size(), 6); - for (int i = 0; i < pm.size(); ++i) { - for (int j = i; j < pm.size(); ++j) { - pm(i, j) = f(i, j); + for (int i = 0; i < pm_.size(); ++i) { + for (int j = i; j < pm_.size(); ++j) { + EXPECT_EQ(pm_(i, j), key(i, j)); } } +} + +TEST(pair_map, iterate) { + auto pm = populate(6); size_t count = 0; for (const auto &[i, j, m]: pm) { - if (m != f(i, j)) { - std::cerr << "m (" << m << ") != " << (f(i, j)) << "" << std::endl; - return EXIT_FAILURE; - } + EXPECT_EQ(m, key(i, j)); count++; } - - if (count != 21) { - std::cerr << "count (" << count << ") != " << 21 << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; + EXPECT_EQ(count, 21); } -int test_iterate_ref() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; - - tc::pair_map pm(6); +TEST(pair_map, iterate_ref) { + auto pm = populate(6); for (const auto &[i, j, m]: pm) { - m = f(i, j); + m = 42; } for (const auto &[i, j, m]: pm) { - if (m != f(i, j)) { - std::cerr << "m (" << m << ") != " << f(i, j) << std::endl; - return EXIT_FAILURE; - } + EXPECT_EQ(m, 42); } - - return EXIT_SUCCESS; } -int test_view() { - auto f = [](size_t i, size_t j) { return ((i + j) << 12) ^ i ^ j; }; - - tc::pair_map pm(6); - - for (int i = 0; i < pm.size(); ++i) { - for (int j = i; j < pm.size(); ++j) { - pm(i, j) = f(i, j); - } - } +TEST(pair_map, view) { + auto pm = populate(6); size_t count = 0; for (const auto &[i, j, m]: pm.of(4)) { - if (i != 4 && j != 4) { - std::cerr << i << ", " << j << " != " << 4 << std::endl; - return EXIT_FAILURE; - } + EXPECT_EQ_EITHER(4, i, j); count++; } - - if (count != 6) { - std::cerr << "count (" << count << ") != " << 6 << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - -static std::unordered_map> tests = { - {"populate", test_populate}, - {"symmetry", test_symmetry}, - {"fill", test_fill}, - {"copy", test_copy}, - {"move", test_move}, - {"iterate", test_iterate}, - {"iterate_ref", test_iterate_ref}, - {"view", test_view}, -}; - -int main(int argc, char *argv[]) { - std::vector args(argv + 1, argv + argc); - - auto it = tests.find(args[0]); - if (it == tests.end()) { - std::cerr << "Test not found" << std::endl; - return EXIT_FAILURE; - } - auto test = it->second; - return test(); + EXPECT_EQ(count, pm.size()); } diff --git a/tc/test/test_solve.cpp b/tc/test/test_solve.cpp index 187da0e..9a1b4cc 100644 --- a/tc/test/test_solve.cpp +++ b/tc/test/test_solve.cpp @@ -1,172 +1,187 @@ -#include -#include +#include #include #include #include +#include -int main(int argc, char *argv[]) { - std::string key = argv[1]; +/// helper for testing solve and testing speed +testing::AssertionResult AssertSolveOrder( + const char *group_expr, + const char *sub_gens_expr, + const char *expected_order_expr, + const tc::Group &group, + const std::vector &sub_gens, + tc::Coset expected_order +) { + auto start = std::clock(); + auto cosets = tc::solve(group, sub_gens); + auto end = std::clock(); - std::vector, - size_t - >> groups; + tc::Coset actual_order = cosets.size(); - // See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties - if (key == "A") { - groups = { - {"A(1)", tc::group::A(1), {}, 2}, - {"A(2)", tc::group::A(2), {}, 6}, - {"A(3)", tc::group::A(3), {}, 24}, - {"A(3)", tc::group::A(3), {0}, 12}, - {"A(3)", tc::group::A(3), {0, 1}, 4}, - {"A(3)", tc::group::A(3), {0, 2}, 6}, - {"A(3)", tc::group::A(3), {2}, 12}, - {"A(4)", tc::group::A(4), {}, 120}, - {"A(4)", tc::group::A(4), {0}, 60}, - {"A(4)", tc::group::A(4), {0, 1}, 20}, - {"A(4)", tc::group::A(4), {2}, 60}, - {"A(4)", tc::group::A(4), {0, 2}, 30}, - }; - } - if (key == "B") { - groups = { - {"B(2)", tc::group::B(2), {}, 8}, - {"B(3)", tc::group::B(3), {}, 48}, - {"B(3)", tc::group::B(3), {0}, 24}, - {"B(3)", tc::group::B(3), {0, 2}, 12}, - {"B(4)", tc::group::B(4), {}, 384}, - {"B(4)", tc::group::B(4), {0}, 192}, - {"B(4)", tc::group::B(4), {0, 2}, 96}, - {"B(5)", tc::group::B(5), {}, 3840}, - {"B(5)", tc::group::B(5), {0}, 1920}, - {"B(5)", tc::group::B(5), {0, 2}, 960}, - {"B(5)", tc::group::B(5), {0, 2, 3}, 320}, - {"B(6)", tc::group::B(6), {}, 46080}, - {"B(6)", tc::group::B(6), {0}, 23040}, - {"B(6)", tc::group::B(6), {0, 2}, 11520}, - {"B(6)", tc::group::B(6), {0, 2, 3}, 3840}, - {"B(6)", tc::group::B(6), {0, 2, 3, 5}, 1920}, - }; - } - if (key == "D") { - groups = { - {"D(2)", tc::group::D(2), {}, 4}, - {"D(3)", tc::group::D(3), {}, 24}, - {"D(4)", tc::group::D(4), {}, 192}, - {"D(4)", tc::group::D(4), {0, 1}, 32}, - {"D(4)", tc::group::D(4), {0, 1, 3}, 8}, - {"D(5)", tc::group::D(5), {}, 1920}, - {"D(5)", tc::group::D(5), {0, 1}, 320}, - {"D(5)", tc::group::D(5), {0, 1, 3}, 160}, - {"D(5)", tc::group::D(5), {0, 1, 3, 4}, 40}, - {"D(6)", tc::group::D(6), {}, 23040}, - {"D(6)", tc::group::D(6), {0, 1}, 3840}, - {"D(6)", tc::group::D(6), {0, 1, 3}, 1920}, - {"D(6)", tc::group::D(6), {0, 1, 3, 5}, 480}, - }; - } - if (key == "E") { - groups = { - {"E(3)", tc::group::E(3), {}, 12}, - {"E(4)", tc::group::E(4), {}, 120}, - {"E(4)", tc::group::E(4), {2}, 60}, - {"E(4)", tc::group::E(4), {2, 1}, 20}, - {"E(4)", tc::group::E(4), {2, 1, 3}, 5}, - {"E(5)", tc::group::E(5), {}, 1920}, - {"E(5)", tc::group::E(5), {2}, 960}, - {"E(5)", tc::group::E(5), {2, 1}, 320}, - {"E(5)", tc::group::E(5), {2, 1, 3}, 80}, - {"E(6)", tc::group::E(6), {}, 51840}, - {"E(6)", tc::group::E(6), {2}, 25920}, - {"E(6)", tc::group::E(6), {2, 1}, 8640}, - {"E(6)", tc::group::E(6), {2, 1, 3}, 2160}, - }; - } - if (key == "F") { - groups = { - {"F4()", tc::group::F4(), {}, 1152}, - {"F4()", tc::group::F4(), {0}, 576}, - {"F4()", tc::group::F4(), {0, 2}, 288}, - {"F4()", tc::group::F4(), {1, 3}, 288}, - {"F4()", tc::group::F4(), {1, 2, 3}, 24}, - }; - } - if (key == "G") { - groups = { - {"G2()", tc::group::G2(), {}, 12}, - {"G2()", tc::group::G2(), {0}, 6}, - {"G2()", tc::group::G2(), {1}, 6}, - }; - } - if (key == "H") { - groups = { - {"H(2)", tc::group::H(2), {}, 10}, - {"H(2)", tc::group::H(2), {0}, 5}, - {"H(2)", tc::group::H(2), {1}, 5}, - {"H(3)", tc::group::H(3), {}, 120}, - {"H(3)", tc::group::H(3), {0}, 60}, - {"H(3)", tc::group::H(3), {0, 1}, 12}, - {"H(3)", tc::group::H(3), {0, 2}, 30}, - {"H(3)", tc::group::H(3), {1, 2}, 20}, - {"H(4)", tc::group::H(4), {}, 14400}, - {"H(4)", tc::group::H(4), {0}, 7200}, - {"H(4)", tc::group::H(4), {1}, 7200}, - {"H(4)", tc::group::H(4), {1, 3}, 3600}, - }; - } - if (key == "I") { - groups = { - {"I2(2)", tc::group::I2(2), {}, 4}, - {"I2(3)", tc::group::I2(3), {}, 6}, - {"I2(3)", tc::group::I2(3), {0}, 3}, - {"I2(3)", tc::group::I2(3), {1}, 3}, - {"I2(4)", tc::group::I2(4), {}, 8}, - {"I2(4)", tc::group::I2(4), {0}, 4}, - {"I2(4)", tc::group::I2(4), {1}, 4}, - {"I2(5)", tc::group::I2(5), {}, 10}, - {"I2(5)", tc::group::I2(5), {0}, 5}, - {"I2(5)", tc::group::I2(5), {1}, 5}, - }; - } - if (key == "T") { - groups = { - {"T(3)", tc::group::T(3), {}, 36}, - {"T(4)", tc::group::T(4), {}, 64}, - {"T(400)", tc::group::T(400), {}, 640000}, - {"T(400)", tc::group::T(400), {0}, 320000}, - {"T(400)", tc::group::T(400), {0, 2}, 160000}, - {"T(400, 300)", tc::group::T(400, 300), {}, 480000}, - {"T(400, 300)", tc::group::T(400, 300), {0}, 240000}, - {"T(400, 300)", tc::group::T(400, 300), {0, 2}, 120000}, - }; + auto total_sec = (double) (end - start) / CLOCKS_PER_SEC; + auto cosets_per_sec = (double) actual_order / total_sec; + + bool order_good = actual_order == expected_order; + bool speed_good = cosets_per_sec >= MIN_COS_PER_SEC; + + if (order_good && speed_good) { + return testing::AssertionSuccess(); } - int status = EXIT_SUCCESS; - - for (const auto &[name, group, sub_gens, expected]: groups) { - auto cos = tc::solve(group, sub_gens); - auto actual = cos.size(); - std::cout << name; - if (!sub_gens.empty()) { - std::cout << " / {"; - std::cout << (int) sub_gens[0]; - for (int i = 1; i < sub_gens.size(); ++i) { - std::cout << ", " << (int) sub_gens[i]; - } - std::cout << "}"; - } - std::cout << " : " << actual; - if (expected != actual) { - std::cout << " (Expected " << expected << ")"; - status = EXIT_FAILURE; - } - std::cout << std::endl; + testing::AssertionResult res = testing::AssertionFailure(); + res << group_expr << " / " << sub_gens_expr << " :"; + if (!order_good) { + res << " Gave order " << actual_order << " but expected order " << expected_order << "."; + } + if (!speed_good) { + res << " Solution too slow (" << cosets_per_sec + << " cos/s < " << MIN_COS_PER_SEC << ")."; } - return status; + return res; +} + +using namespace tc::group; + +#define EXPECT_SOLVE_ORDER(group, sub_gens, expected_order) EXPECT_PRED_FORMAT3(AssertSolveOrder, group, sub_gens, expected_order); + +using v = std::vector; + +// See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties + +TEST(solve, A) { + EXPECT_SOLVE_ORDER(A(1), v({}), 2); + EXPECT_SOLVE_ORDER(A(2), v({}), 6); + EXPECT_SOLVE_ORDER(A(3), v({}), 24); + EXPECT_SOLVE_ORDER(A(3), v({0}), 12); + EXPECT_SOLVE_ORDER(A(3), v({0, 1}), 4); + EXPECT_SOLVE_ORDER(A(3), v({0, 2}), 6); + EXPECT_SOLVE_ORDER(A(3), v({2}), 12); + EXPECT_SOLVE_ORDER(A(4), v({}), 120); + EXPECT_SOLVE_ORDER(A(4), v({0}), 60); + EXPECT_SOLVE_ORDER(A(4), v({0, 1}), 20); + EXPECT_SOLVE_ORDER(A(4), v({2}), 60); + EXPECT_SOLVE_ORDER(A(4), v({0, 2}), 30); +} + +TEST(solve, B) { + EXPECT_SOLVE_ORDER(B(2), v({}), 8); + EXPECT_SOLVE_ORDER(B(3), v({}), 48); + EXPECT_SOLVE_ORDER(B(3), v({0}), 24); + EXPECT_SOLVE_ORDER(B(3), v({0, 2}), 12); + EXPECT_SOLVE_ORDER(B(4), v({}), 384); + EXPECT_SOLVE_ORDER(B(4), v({0}), 192); + EXPECT_SOLVE_ORDER(B(4), v({0, 2}), 96); + EXPECT_SOLVE_ORDER(B(5), v({}), 3840); + EXPECT_SOLVE_ORDER(B(5), v({0}), 1920); + EXPECT_SOLVE_ORDER(B(5), v({0, 2}), 960); + EXPECT_SOLVE_ORDER(B(5), v({0, 2, 3}), 320); + EXPECT_SOLVE_ORDER(B(6), v({}), 46080); + EXPECT_SOLVE_ORDER(B(6), v({0}), 23040); + EXPECT_SOLVE_ORDER(B(6), v({0, 2}), 11520); + EXPECT_SOLVE_ORDER(B(6), v({0, 2, 3}), 3840); + EXPECT_SOLVE_ORDER(B(6), v({0, 2, 3, 5}), 1920); +} + +TEST(solve, D) { + EXPECT_SOLVE_ORDER(D(2), v({}), 4); + EXPECT_SOLVE_ORDER(D(3), v({}), 24); + EXPECT_SOLVE_ORDER(D(4), v({}), 192); + EXPECT_SOLVE_ORDER(D(4), v({0, 1}), 32); + EXPECT_SOLVE_ORDER(D(4), v({0, 1, 3}), 8); + EXPECT_SOLVE_ORDER(D(5), v({}), 1920); + EXPECT_SOLVE_ORDER(D(5), v({0, 1}), 320); + EXPECT_SOLVE_ORDER(D(5), v({0, 1, 3}), 160); + EXPECT_SOLVE_ORDER(D(5), v({0, 1, 3, 4}), 40); + EXPECT_SOLVE_ORDER(D(6), v({}), 23040); + EXPECT_SOLVE_ORDER(D(6), v({0, 1}), 3840); + EXPECT_SOLVE_ORDER(D(6), v({0, 1, 3}), 1920); + EXPECT_SOLVE_ORDER(D(6), v({0, 1, 3, 5}), 480); +} + +TEST(solve, E) { + EXPECT_SOLVE_ORDER(E(3), v({}), 12); + EXPECT_SOLVE_ORDER(E(4), v({}), 120); + EXPECT_SOLVE_ORDER(E(4), v({2}), 60); + EXPECT_SOLVE_ORDER(E(4), v({2, 1}), 20); + EXPECT_SOLVE_ORDER(E(4), v({2, 1, 3}), 5); + EXPECT_SOLVE_ORDER(E(5), v({}), 1920); + EXPECT_SOLVE_ORDER(E(5), v({2}), 960); + EXPECT_SOLVE_ORDER(E(5), v({2, 1}), 320); + EXPECT_SOLVE_ORDER(E(5), v({2, 1, 3}), 80); + EXPECT_SOLVE_ORDER(E(6), v({}), 51840); + EXPECT_SOLVE_ORDER(E(6), v({2}), 25920); + EXPECT_SOLVE_ORDER(E(6), v({2, 1}), 8640); + EXPECT_SOLVE_ORDER(E(6), v({2, 1, 3}), 2160); +} + +TEST(solve, F) { + EXPECT_SOLVE_ORDER(F4(), v({}), 1152); + EXPECT_SOLVE_ORDER(F4(), v({0}), 576); + EXPECT_SOLVE_ORDER(F4(), v({0, 2}), 288); + EXPECT_SOLVE_ORDER(F4(), v({1, 3}), 288); + EXPECT_SOLVE_ORDER(F4(), v({1, 2, 3}), 24); +} + +TEST(solve, G) { + EXPECT_SOLVE_ORDER(G2(), v({}), 12); + EXPECT_SOLVE_ORDER(G2(), v({0}), 6); + EXPECT_SOLVE_ORDER(G2(), v({1}), 6); +} + +TEST(solve, H) { + EXPECT_SOLVE_ORDER(H(2), v({}), 10); + EXPECT_SOLVE_ORDER(H(2), v({0}), 5); + EXPECT_SOLVE_ORDER(H(2), v({1}), 5); + EXPECT_SOLVE_ORDER(H(3), v({}), 120); + EXPECT_SOLVE_ORDER(H(3), v({0}), 60); + EXPECT_SOLVE_ORDER(H(3), v({0, 1}), 12); + EXPECT_SOLVE_ORDER(H(3), v({0, 2}), 30); + EXPECT_SOLVE_ORDER(H(3), v({1, 2}), 20); + EXPECT_SOLVE_ORDER(H(4), v({}), 14400); + EXPECT_SOLVE_ORDER(H(4), v({0}), 7200); + EXPECT_SOLVE_ORDER(H(4), v({1}), 7200); + EXPECT_SOLVE_ORDER(H(4), v({1, 3}), 3600); +} + +TEST(solve, I) { + EXPECT_SOLVE_ORDER(I2(2), v({}), 4); + EXPECT_SOLVE_ORDER(I2(3), v({}), 6); + EXPECT_SOLVE_ORDER(I2(3), v({0}), 3); + EXPECT_SOLVE_ORDER(I2(3), v({1}), 3); + EXPECT_SOLVE_ORDER(I2(4), v({}), 8); + EXPECT_SOLVE_ORDER(I2(4), v({0}), 4); + EXPECT_SOLVE_ORDER(I2(4), v({1}), 4); + EXPECT_SOLVE_ORDER(I2(5), v({}), 10); + EXPECT_SOLVE_ORDER(I2(5), v({0}), 5); + EXPECT_SOLVE_ORDER(I2(5), v({1}), 5); +} + +TEST(solve, T) { + EXPECT_SOLVE_ORDER(T(3), v({}), 36); + EXPECT_SOLVE_ORDER(T(4), v({}), 64); + EXPECT_SOLVE_ORDER(T(400), v({}), 640000); + EXPECT_SOLVE_ORDER(T(400), v({0}), 320000); + EXPECT_SOLVE_ORDER(T(400), v({0, 2}), 160000); + EXPECT_SOLVE_ORDER(T(400, 300), v({}), 480000); + EXPECT_SOLVE_ORDER(T(400, 300), v({0}), 240000); + EXPECT_SOLVE_ORDER(T(400, 300), v({0, 2}), 120000); +} + +TEST(solve_large, B) { + EXPECT_SOLVE_ORDER(B(7), v({}), 645120); + EXPECT_SOLVE_ORDER(B(8), v({}), 10321920); +} + +TEST(solve_large, E) { + EXPECT_SOLVE_ORDER(E(6), v({}), 51840); + EXPECT_SOLVE_ORDER(E(7), v({}), 2903040); +} + +TEST(solve_large, T) { + EXPECT_SOLVE_ORDER(T(500), v({}), 1000000); + EXPECT_SOLVE_ORDER(T(1000), v({}), 4000000); } diff --git a/tc/test/test_solve_speed.cpp b/tc/test/test_solve_speed.cpp deleted file mode 100644 index 80319a6..0000000 --- a/tc/test/test_solve_speed.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include - -#include -#include - -int main(int argc, char *argv[]) { - std::string key = argv[1]; - - std::cerr << "Min. cos/s: " << MINIMUM_COS_PER_SEC << std::endl; - std::vector, - size_t - >> groups; - - // See the group orders here https://en.wikipedia.org/wiki/Coxeter_group#Properties - if (key == "B") { - groups = { - {"B(7)", tc::group::B(7), {}, 645120}, - {"B(8)", tc::group::B(8), {}, 10321920}, - }; - } - if (key == "E") { - groups = { - {"E(6)", tc::group::E(6), {}, 51840}, - {"E(7)", tc::group::E(7), {}, 2903040}, - }; - } - if (key == "T") { - groups = { - {"T(500)", tc::group::T(500), {}, 1000000}, - {"T(1000)", tc::group::T(1000), {}, 4000000}, - }; - } - - int status = EXIT_SUCCESS; - - for (const auto &[name, group, sub_gens, expected]: groups) { - auto t0 = clock(); - auto cos = tc::solve(group, sub_gens); - auto t1 = clock(); - auto actual = cos.size(); - - auto sec = (double) (t1 - t0) / CLOCKS_PER_SEC; - auto cos_per_sec = (double) actual / sec; - - if (expected != actual) { - std::cerr << name << " wrong. " << actual << " (" << expected << ")" << std::endl; - status = EXIT_FAILURE; - } - - std::cout << name << " cos/s: " << (size_t) cos_per_sec << std::endl; - if (cos_per_sec < MINIMUM_COS_PER_SEC) { - std::cerr << name << " too slow." << std::endl; - status = EXIT_FAILURE; - } - } - - return status; -}