Closed interval
(Mylib/Math/closed_interval.cpp)
- View this file on GitHub
- Last update: 2021-04-23 23:44:44+09:00
Operations
一つの閉区間を管理する。
-
is_null()
- 区間が空であるかを判定する。
-
contains(a)
- 区間に点
a
が含まれるかを判定する。
- 区間に点
-
intersect(a, b)
- 区間
a
とb
の共通部分を得る。
- 区間
-
left_expand(a, x)
- 区間
a
の左端をx
だけ伸縮したものを返す。
- 区間
-
right_expand(a, x)
- 区間
a
の右端をx
だけ伸縮したものを返す。
- 区間
Requirements
Notes
Problems
References
Code
#pragma once
#include <algorithm>
#include <iostream>
#include <optional>
#include <utility>
namespace haar_lib {
template <typename T>
struct closed_interval {
std::optional<std::pair<std::optional<T>, std::optional<T>>> value;
closed_interval() {}
closed_interval(std::optional<T> l, std::optional<T> r) : value(std::make_pair(l, r)) {}
friend std::ostream &operator<<(std::ostream &s, const closed_interval<T> &a) {
s << "[";
if (a.value) {
if ((a.value)->first)
s << *((a.value)->first);
else
s << "-∞ ";
s << ",";
if ((a.value)->second)
s << *((a.value)->second);
else
s << "∞ ";
}
s << "]";
return s;
}
bool is_null() const {
return not value;
}
bool contains(T v) const {
if (not value) return false;
if (value->first and v < *(value->first)) return false;
if (value->second and v > *(value->second)) return false;
return true;
}
};
template <typename T>
auto intersect(closed_interval<T> a, closed_interval<T> b) {
if (not a.value or not b.value) return closed_interval<T>();
std::optional<T> l, r;
if ((a.value)->first) {
l = *((a.value)->first);
}
if ((b.value)->first) {
if (l)
l = std::max(*l, *((b.value)->first));
else
l = *((b.value)->first);
}
if ((a.value)->second) {
r = *((a.value)->second);
}
if ((b.value)->second) {
if (r)
r = std::min(*r, *((b.value)->second));
else
r = *((b.value)->second);
}
if (l and r) {
if (*l > *r) {
return closed_interval<T>();
}
}
return closed_interval<T>(l, r);
}
template <typename T>
auto left_expand(closed_interval<T> a, T x) {
if (a.value and (a.value)->first) {
*((a.value)->first) += x;
if ((a.value)->second and *((a.value)->first) > *((a.value)->second)) {
return closed_interval<T>();
}
}
return a;
}
template <typename T>
auto right_expand(closed_interval<T> a, T x) {
if (a.value and (a.value)->second) {
*((a.value)->second) += x;
if ((a.value)->first and *((a.value)->first) > *((a.value)->second)) {
return closed_interval<T>();
}
}
return a;
}
template <typename T>
auto operator+(closed_interval<T> a, T k) {
if (a.value) {
if (a.value->first) a.value->first.value() += k;
if (a.value->second) a.value->second.value() += k;
}
return a;
}
template <typename T>
auto operator-(closed_interval<T> a, T k) {
if (a.value) {
if (a.value->first) a.value->first.value() -= k;
if (a.value->second) a.value->second.value() -= k;
}
return a;
}
template <typename T>
auto operator*(closed_interval<T> a, T k) {
if (a.value) {
if (k < 0) std::swap(a.value->first, a.value->second);
if (a.value->first) a.value->first.value() *= k;
if (a.value->second) a.value->second.value() *= k;
}
return a;
}
} // namespace haar_lib
#line 2 "Mylib/Math/closed_interval.cpp"
#include <algorithm>
#include <iostream>
#include <optional>
#include <utility>
namespace haar_lib {
template <typename T>
struct closed_interval {
std::optional<std::pair<std::optional<T>, std::optional<T>>> value;
closed_interval() {}
closed_interval(std::optional<T> l, std::optional<T> r) : value(std::make_pair(l, r)) {}
friend std::ostream &operator<<(std::ostream &s, const closed_interval<T> &a) {
s << "[";
if (a.value) {
if ((a.value)->first)
s << *((a.value)->first);
else
s << "-∞ ";
s << ",";
if ((a.value)->second)
s << *((a.value)->second);
else
s << "∞ ";
}
s << "]";
return s;
}
bool is_null() const {
return not value;
}
bool contains(T v) const {
if (not value) return false;
if (value->first and v < *(value->first)) return false;
if (value->second and v > *(value->second)) return false;
return true;
}
};
template <typename T>
auto intersect(closed_interval<T> a, closed_interval<T> b) {
if (not a.value or not b.value) return closed_interval<T>();
std::optional<T> l, r;
if ((a.value)->first) {
l = *((a.value)->first);
}
if ((b.value)->first) {
if (l)
l = std::max(*l, *((b.value)->first));
else
l = *((b.value)->first);
}
if ((a.value)->second) {
r = *((a.value)->second);
}
if ((b.value)->second) {
if (r)
r = std::min(*r, *((b.value)->second));
else
r = *((b.value)->second);
}
if (l and r) {
if (*l > *r) {
return closed_interval<T>();
}
}
return closed_interval<T>(l, r);
}
template <typename T>
auto left_expand(closed_interval<T> a, T x) {
if (a.value and (a.value)->first) {
*((a.value)->first) += x;
if ((a.value)->second and *((a.value)->first) > *((a.value)->second)) {
return closed_interval<T>();
}
}
return a;
}
template <typename T>
auto right_expand(closed_interval<T> a, T x) {
if (a.value and (a.value)->second) {
*((a.value)->second) += x;
if ((a.value)->first and *((a.value)->first) > *((a.value)->second)) {
return closed_interval<T>();
}
}
return a;
}
template <typename T>
auto operator+(closed_interval<T> a, T k) {
if (a.value) {
if (a.value->first) a.value->first.value() += k;
if (a.value->second) a.value->second.value() += k;
}
return a;
}
template <typename T>
auto operator-(closed_interval<T> a, T k) {
if (a.value) {
if (a.value->first) a.value->first.value() -= k;
if (a.value->second) a.value->second.value() -= k;
}
return a;
}
template <typename T>
auto operator*(closed_interval<T> a, T k) {
if (a.value) {
if (k < 0) std::swap(a.value->first, a.value->second);
if (a.value->first) a.value->first.value() *= k;
if (a.value->second) a.value->second.value() *= k;
}
return a;
}
} // namespace haar_lib