255 lines
5.1 KiB
C++

#include <iostream>
#include <vector>
#include <set>
#include <fstream>
#include <numeric>
#include <chrono>
#include <filesystem>
bool isDevider(std::multiset<int> &v, int n)
{
for (auto i : v)
{
if (i % n != 0)
return false;
}
return true;
}
int findMaxSlow(std::multiset<int> &v)
{
int f = *(v.begin());
for (size_t i = f; i >= 1; --i)
{
if (isDevider(v, i))
{
return i;
}
}
return 1;
}
std::vector<int> findSlow(std::ifstream &file)
{
int lines = 0;
file >> lines;
char inst = 0;
int num = 0;
std::multiset<int> v;
std::vector<int> 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<int> &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<int> findFast(std::ifstream &file)
{
int lines = 0;
file >> lines;
char inst = 0;
int num = 0;
std::multiset<int> v;
int devider = 0;
std::vector<int> 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<int> 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<std::chrono::milliseconds>(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<std::string> files;
std::vector<std::string> 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<int> res_vec;
std::vector<int> 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<std::chrono::milliseconds>(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<std::chrono::milliseconds>(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