#include #include #include #include #include #include #include bool isDevider(std::multiset &v, int n) { for (auto i : v) { if (i % n != 0) return false; } return true; } int findMaxSlow(std::multiset &v) { int f = *(v.begin()); for (size_t i = f; i >= 1; --i) { if (isDevider(v, i)) { return i; } } return 1; } std::vector findSlow(std::ifstream &file) { int lines = 0; file >> lines; char inst = 0; int num = 0; std::multiset v; std::vector out_vec; for (size_t i = 0; i < lines; i++) { file >> inst >> num; if (inst == '+') { v.insert(num); } else { v.erase(v.find(num)); } out_vec.push_back(findMaxSlow(v)); } return out_vec; } int findMaxFast(std::multiset &v) { int gretestCommonDevider = *(v.begin()); for (auto i : v) { if (gretestCommonDevider != 0) { // GCD is deviding averithing and its not deviding the new number find the new devider if (i % gretestCommonDevider != 0) { gretestCommonDevider = std::gcd(gretestCommonDevider, i); // if GCD is one return 1 becouse 1 is min GCD if (gretestCommonDevider == 1) return 1; } } } return gretestCommonDevider; } std::vector findFast(std::ifstream &file) { int lines = 0; file >> lines; char inst = 0; int num = 0; std::multiset v; int devider = 0; std::vector out_vec; out_vec.reserve(lines); file >> inst >> num; v.insert(num); devider = findMaxFast(v); out_vec.push_back(devider); int64_t add = 0; int64_t erase = 0; for (size_t i = 1; i < lines; i++) { file >> inst >> num; if (inst == '+') { // if you add number to the list just check if its devided by GCD if not find new one v.insert(num); if (devider != 0) { if (num % devider != 0) devider = std::gcd(num, devider); } else devider = std::gcd(num, devider); } else { v.erase(v.find(num)); devider = findMaxFast(v); } if (devider == 0) out_vec.push_back(1); else out_vec.push_back(devider); } return out_vec; } #if 0 int main(int argc, char **argv) { if (argc != 3) return 1; int fast = std::stoi(argv[1]); std::ifstream file(argv[2], std::ios::in); if (!file.is_open()) return 1; auto start = std::chrono::high_resolution_clock::now(); std::vector out_vec; if (fast) out_vec = findFast(file); else out_vec = findSlow(file); auto end = std::chrono::high_resolution_clock::now(); auto time = std::chrono::duration_cast(end - start); std::ofstream out_file("out.txt", std::ios::out); if (!out_file.is_open()) return 1; for (auto i : out_vec) { out_file << i << std::endl; } std::cout << time.count() << std::endl; return 0; } #else int main() { std::string directory_path = "sopek_marjetic/"; std::vector files; std::vector files_out; // Iterate over the files in the directory for (const auto &entry : std::filesystem::directory_iterator(directory_path)) { // Check if the entry is a regular file if (std::filesystem::is_regular_file(entry.path())) { if (entry.path().extension() == ".in") files.push_back(entry.path().string()); else if (entry.path().extension() == ".out") files_out.push_back(entry.path().string()); } } std::sort(files.begin(), files.end()); std::sort(files_out.begin(), files_out.end()); printf(" %8s\t %8s\t %8s\t %s\n", "fast", "slow", "ratio", "file"); for (int i = 0; i < files.size(); i++) { std::vector res_vec; std::vector out_vec; int num = 0; std::ifstream out_file(files_out[i], std::ios::in); if (!out_file.is_open()) continue; while (!out_file.eof()) { out_file >> num; out_vec.push_back(num); } std::ifstream file(files[i], std::ios::in); if (!file.is_open()) continue; auto start = std::chrono::high_resolution_clock::now(); res_vec = findFast(file); auto end = std::chrono::high_resolution_clock::now(); auto fast = std::chrono::duration_cast(end - start); for (int i = 0; i < res_vec.size(); i++) { if (res_vec[i] != out_vec[i]) { return 0; } } file.seekg(0, std::ios::beg); auto start1 = std::chrono::high_resolution_clock::now(); res_vec = findSlow(file); auto end1 = std::chrono::high_resolution_clock::now(); auto slow = std::chrono::duration_cast(end1 - start1); for (size_t i = 0; i < res_vec.size(); i++) { if (res_vec[i] != out_vec[i]) { return 0; } } if (fast.count() == 0) fast = std::chrono::milliseconds(1); if (slow.count() == 0) slow = std::chrono::milliseconds(1); float ratio = (float)slow.count() / (float)fast.count(); printf(" %8ld\t %8ld\t %8f\t %s\n", fast.count(), slow.count(), ratio, files[i].c_str()); file.close(); } } #endif