111 lines
2.3 KiB
C++
111 lines
2.3 KiB
C++
|
#pragma once
|
||
|
|
||
|
#include <vector>
|
||
|
|
||
|
typedef long long ll;
|
||
|
typedef unsigned long long ull;
|
||
|
|
||
|
template <typename T> struct Coord {
|
||
|
T x, y;
|
||
|
|
||
|
Coord() : Coord(0, 0) {}
|
||
|
|
||
|
Coord(const T x, const T y) {
|
||
|
this->x = x;
|
||
|
this->y = y;
|
||
|
}
|
||
|
|
||
|
Coord<T> operator-() { return {-this->x, -this->y}; }
|
||
|
|
||
|
Coord<T> &operator+=(const Coord<T> &other) {
|
||
|
x += other.x;
|
||
|
y += other.y;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Coord<T> &operator-=(const Coord<T> &other) {
|
||
|
x -= other.x;
|
||
|
y -= other.y;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Coord<T> &operator*=(const T other) {
|
||
|
x *= other;
|
||
|
y *= other;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Coord<T> &operator/=(const T other) {
|
||
|
x /= other;
|
||
|
y /= other;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
std::vector<Coord<T>> nearby(const Coord<T> &cMin, const Coord<T> &cMax) {
|
||
|
std::vector<Coord<T>> ret;
|
||
|
const T xMin = std::max(this->x - 1, cMin.x);
|
||
|
const T xMax = std::min(this->x + 1, cMax.x);
|
||
|
const T yMin = std::max(this->y - 1, cMin.y);
|
||
|
const T yMax = std::min(this->y + 1, cMax.y);
|
||
|
for (T x = xMin; x <= xMax; x++) {
|
||
|
for (T y = yMin; y <= yMax; y++) {
|
||
|
Coord<T> xy(x, y);
|
||
|
if (*this != xy) {
|
||
|
ret.push_back(xy);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
std::vector<Coord<T>> nearby(const Coord<T> &cMax) {
|
||
|
return this->nearby(Coord<T>(), cMax);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <typename T>
|
||
|
Coord<T> operator+(const Coord<T> &lhs, const Coord<T> &rhs) {
|
||
|
Coord<T> result = lhs;
|
||
|
result += rhs;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
Coord<T> operator-(const Coord<T> &lhs, const Coord<T> &rhs) {
|
||
|
Coord<T> result = lhs;
|
||
|
result -= rhs;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
template <typename T> Coord<T> operator*(const Coord<T> &lhs, const T rhs) {
|
||
|
Coord<T> result = lhs;
|
||
|
result *= rhs;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
template <typename T> Coord<T> operator/(const Coord<T> &lhs, const T rhs) {
|
||
|
Coord<T> result = lhs;
|
||
|
result /= rhs;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
inline bool operator==(const Coord<T> &lhs, const Coord<T> &rhs) {
|
||
|
return lhs.x == rhs.x && lhs.y == rhs.y;
|
||
|
}
|
||
|
|
||
|
template <> struct std::hash<Coord<int>> {
|
||
|
std::size_t operator()(const Coord<int> &c) const noexcept {
|
||
|
return (c.x << (sizeof(std::size_t) / 2)) - c.x + c.y;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <> struct std::hash<Coord<ull>> {
|
||
|
std::size_t operator()(const Coord<ull> &c) const noexcept {
|
||
|
return (c.x << (sizeof(std::size_t) / 2)) - c.x + c.y;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
typedef Coord<int> icoord;
|
||
|
typedef Coord<ull> ullcoord;
|