#include <unordered_set>
struct Point {
int X;
int Y;
Point() : X(0), Y(0) {};
Point(const int& x, const int& y) : X(x), Y(y) {};
Point(const Point& other){
X = other.X;
Y = other.Y;
};
Point& operator=(const Point& other) {
X = other.X;
Y = other.Y;
return *this;
};
bool operator==(const Point& other) {
if (X == other.X && Y == other.Y)
return true;
return false;
};
bool operator<(const Point& other) {
if (X < other.X )
return true;
else if (X == other.X && Y == other.Y)
return true;
return false;
};
// this could be moved in to std::hash<Point>::operator()
size_t operator()(const Point& pointToHash) const noexcept {
size_t hash = pointToHash.X + 10 * pointToHash.Y;
return hash;
};
};
namespace std {
template<> struct hash<Point>
{
std::size_t operator()(const Point& p) const noexcept
{
return p(p);
}
};
}
int main()
{
// no need to specify the hasher if std::hash<Point> exists
std::unordered_set<Point> p;
return 0;
}
CiNpbmNsdWRlIDx1bm9yZGVyZWRfc2V0PgoKc3RydWN0IFBvaW50IHsKICAgIGludCBYOwogICAgaW50IFk7CgogICAgUG9pbnQoKSA6IFgoMCksIFkoMCkge307CiAgICBQb2ludChjb25zdCBpbnQmIHgsIGNvbnN0IGludCYgeSkgOiBYKHgpLCBZKHkpIHt9OwogICAgUG9pbnQoY29uc3QgUG9pbnQmIG90aGVyKXsKICAgICAgICBYID0gb3RoZXIuWDsKICAgICAgICBZID0gb3RoZXIuWTsKICAgIH07CgogICAgUG9pbnQmIG9wZXJhdG9yPShjb25zdCBQb2ludCYgb3RoZXIpIHsKICAgICAgICBYID0gb3RoZXIuWDsKICAgICAgICBZID0gb3RoZXIuWTsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9OwoKICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBQb2ludCYgb3RoZXIpIHsKICAgICAgICBpZiAoWCA9PSBvdGhlci5YICYmIFkgPT0gb3RoZXIuWSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKCiAgICBib29sIG9wZXJhdG9yPChjb25zdCBQb2ludCYgb3RoZXIpIHsKICAgICAgICBpZiAoWCA8IG90aGVyLlggKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICBlbHNlIGlmIChYID09IG90aGVyLlggJiYgWSA9PSBvdGhlci5ZKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKCgkvLyB0aGlzIGNvdWxkIGJlIG1vdmVkIGluIHRvIHN0ZDo6aGFzaDxQb2ludD46Om9wZXJhdG9yKCkKICAgIHNpemVfdCBvcGVyYXRvcigpKGNvbnN0IFBvaW50JiBwb2ludFRvSGFzaCkgY29uc3Qgbm9leGNlcHQgewogICAgICAgIHNpemVfdCBoYXNoID0gcG9pbnRUb0hhc2guWCArIDEwICogcG9pbnRUb0hhc2guWTsKICAgICAgICByZXR1cm4gaGFzaDsKICAgIH07Cgp9OwoKbmFtZXNwYWNlIHN0ZCB7Cgl0ZW1wbGF0ZTw+IHN0cnVjdCBoYXNoPFBvaW50PgoJewoJCXN0ZDo6c2l6ZV90CW9wZXJhdG9yKCkoY29uc3QgUG9pbnQmIHApIGNvbnN0IG5vZXhjZXB0CgkJewoJCQlyZXR1cm4gcChwKTsKCQl9Cgl9Owp9CgppbnQgbWFpbigpCnsKICAgIC8vIG5vIG5lZWQgdG8gc3BlY2lmeSB0aGUgaGFzaGVyIGlmIHN0ZDo6aGFzaDxQb2ludD4gZXhpc3RzCglzdGQ6OnVub3JkZXJlZF9zZXQ8UG9pbnQ+IHA7CglyZXR1cm4gMDsKfQ==