255 lines
5.1 KiB
C++
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
|