#pragma once
#include <vector>
#include <algorithm>
using std::copy;
using std::vector;
using std::find;
using std::sort;
using std::unique_copy;
using std::distance;
bool Func(int i, int j) {
return (i == j);
}
class Set {
public:
Set() {}
explicit Set(vector<int64_t> v) {
this->Copy(v);
}
Set& operator=(Set other) {
this->Copy(other.Data());
return *this;
}
vector<int64_t> Data() { return this->list; }
void Add(int64_t value) {
if (this->Contains(value)) return;
this->list.push_back(value);
}
void Remove(int64_t value) {
vector<int64_t>::iterator idx = this->Index(value);
while (idx != this->list.end()) {
this->list.erase(idx);
idx = this->Index(value);
}
}
bool Contains(int64_t value) {
if (this->Index(value) == this->list.end())
return true;
return false;
}
Set Union(Set other) {
vector<int64_t> res, second = other.Data();
res.reserve(this->list.size() + second.size());
for (auto k : this->list) {
auto idx = find(res.begin(), res.end(), k);
if (idx != res.end()) continue;
res.push_back(k);
}
for (auto k : second) {
auto idx = find(res.begin(), res.end(), k);
if (idx == res.end()) continue;
res.push_back(k);
}
return Set(res);
}
Set Intersection(Set other) {
vector<int64_t> res;
for (auto k : other.Data())
if (this->Contains(k))
res.push_back(k);
sort(res.begin(), res.end());
return Set(res);
}
Set Difference(Set other) {
vector<int64_t> res;
for (auto k : this->list)
if (!other.Contains(k))
res.push_back(k);
sort(res.begin(), res.end());
return Set(res);
}
Set SymmetricDifference(Set other) {
vector<int64_t> res;
for (auto k : other.Data())
if (!this->Contains(k))
res.push_back(k);
for (auto k : this->list)
if (!other.Contains(k))
res.push_back(k);
sort(res.begin(), res.end());
return Set(res);
}
private:
vector<int64_t> list;
void Copy(vector<int64_t> v) {
for (auto k : v) {
auto idx = find(this->list.begin(), this->list.end(), k);
if (idx != this->list.end()) continue;
this->list.push_back(k);
}
}
vector<int64_t>::iterator Index(int64_t value) {
auto idx = find(this->list.begin(), this->list.end(), value);
return idx;
}
};