Files
eduplan-cpp-eltex/diag/tasks/05_lis/test_lis.cpp
T

48 lines
2.3 KiB
C++

#include <cstdio>
#include <vector>
#include <random>
#include <chrono>
#include <algorithm>
#include "solution.cpp"
static int failures = 0;
#define CHECK(cond, name) do { if (cond) std::printf("ok %s\n", name); \
else { std::printf("FAIL %s (line %d)\n", name, __LINE__); ++failures; } } while (0)
int main() {
CHECK(lis_length({}) == 0, "пустая -> 0");
CHECK(lis_length({5}) == 1, "один элемент -> 1");
CHECK(lis_length({1, 2, 3}) == 3, "возрастающая -> вся длина");
CHECK(lis_length({3, 2, 1}) == 1, "убывающая -> 1");
CHECK(lis_length({10, 9, 2, 5, 3, 7, 101, 18}) == 4, "классика -> 4");
CHECK(lis_length({7, 7, 7}) == 1, "равные элементы -> строго возрастающая длина 1");
CHECK(lis_length({0, 1, 0, 3, 2, 3}) == 4, "лекод-пример -> 4");
CHECK(lis_length({2, 2, 2, 3}) == 2, "дубли + рост -> 2");
CHECK(lis_length({-5, -4, -3, -2}) == 4, "отрицательные -> 4");
// производительность: худший случай для наивного DP
{
std::vector<int> big(100000);
for (int i = 0; i < 100000; ++i) big[i] = i;
auto t0 = std::chrono::steady_clock::now();
int r = lis_length(big);
double sec = std::chrono::duration<double>(std::chrono::steady_clock::now() - t0).count();
std::printf(" (100k возрастающих: result=%d, time=%.3fs)\n", r, sec);
CHECK(r == 100000, "100k возрастающих -> 100000");
CHECK(sec < 2.0, "100k за < 2 c (требуется O(n log n))");
}
{
std::mt19937 rng(12345);
std::vector<int> big(100000);
for (auto& x : big) x = int(rng() % 100000);
auto t0 = std::chrono::steady_clock::now();
int r = lis_length(big);
double sec = std::chrono::duration<double>(std::chrono::steady_clock::now() - t0).count();
std::printf(" (100k случайных: result=%d, time=%.3fs)\n", r, sec);
CHECK(r > 300 && r < 800, "100k случайных: результат в разумном диапазоне");
CHECK(sec < 2.0, "100k случайных за < 2 c");
}
std::printf(failures ? "\nFAILURES: %d\n" : "\nALL PASS\n", failures);
return failures ? 1 : 0;
}