#include <algorithm>
#include <iostream>
#include <set>
#include <tuple>
#include <vector>
struct Interval
{
double start;
double end;
};
//-----------------------------------------------------------------------------
// Enum to qualify event: Start/End of "segment-line"
enum class EIntervalState
{
Start,
End
};
//-----------------------------------------------------------------------------
// Events used for collision detection
struct Event
{
double pos;
EIntervalState state;
std::size_t id;
};
//-----------------------------------------------------------------------------
// Comparator to use if {1, 2} and {2, 3} should overlap
class LessIncludeLimit
{
public:
bool operator()(const Event& lhs, const Event& rhs) const
{
return std::tie(lhs.pos, lhs.state) < std::tie(rhs.pos, rhs.state);
}
};
//-----------------------------------------------------------------------------
// Comparator to use if {1, 2} and {2, 3} should not overlap
class LessExcludeLimit
{
public:
bool operator()(const Event& lhs, const Event& rhs) const
{
return std::tie(lhs.pos, rhs.state) < std::tie(rhs.pos, lhs.state);
}
};
//-----------------------------------------------------------------------------
std::vector<Event> MakeEvents(const std::vector<Interval>& intervals)
{
std::vector<Event> res;
std::size_t id = 0;
for (const auto& interval : intervals)
{
res.push_back({interval.start, EIntervalState::Start, id});
res.push_back({interval.end, EIntervalState::End, id});
++id;
}
return res;
}
//-----------------------------------------------------------------------------
template <typename Less>
std::vector<std::pair<std::size_t, std::size_t>>
ComputeOverlappingIntervals(std::vector<Event>&& events, Less less)
{
std::sort(events.begin(), events.end(), less);
std::set<std::size_t> activeIds;
std::vector<std::pair<std::size_t, std::size_t>> res;
for (const auto& event : events)
{
switch (event.state)
{
case EIntervalState::Start:
{
for (const auto& id : activeIds)
{
res.emplace_back(std::minmax(event.id, id));
}
activeIds.emplace(event.id);
break;
}
case EIntervalState::End:
{
activeIds.erase(event.id);
break;
}
}
}
return res;
}
//-----------------------------------------------------------------------------
int main()
{
const std::vector<Interval> intervals = {
{1, 3},
{12, 14},
{2, 4},
{13, 15},
{5, 10}
};
for (const auto& p : ComputeOverlappingIntervals(MakeEvents(intervals), LessExcludeLimit{})) {
std::cout << "intervals " << p.first << " and " << p.second << " overlap\n";
}
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDx2ZWN0b3I+CgpzdHJ1Y3QgSW50ZXJ2YWwKewogICAgZG91YmxlIHN0YXJ0OwogICAgZG91YmxlIGVuZDsKfTsKCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gRW51bSB0byBxdWFsaWZ5IGV2ZW50OiBTdGFydC9FbmQgb2YgInNlZ21lbnQtbGluZSIKZW51bSBjbGFzcyBFSW50ZXJ2YWxTdGF0ZQp7CiAgICBTdGFydCwKICAgIEVuZAp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBFdmVudHMgdXNlZCBmb3IgY29sbGlzaW9uIGRldGVjdGlvbgpzdHJ1Y3QgRXZlbnQKewogICAgZG91YmxlIHBvczsKICAgIEVJbnRlcnZhbFN0YXRlIHN0YXRlOwogICAgc3RkOjpzaXplX3QgaWQ7Cn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIENvbXBhcmF0b3IgdG8gdXNlIGlmIHsxLCAyfSBhbmQgezIsIDN9IHNob3VsZCBvdmVybGFwCmNsYXNzIExlc3NJbmNsdWRlTGltaXQKewpwdWJsaWM6CiAgICBib29sIG9wZXJhdG9yKCkoY29uc3QgRXZlbnQmIGxocywgY29uc3QgRXZlbnQmIHJocykgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gc3RkOjp0aWUobGhzLnBvcywgbGhzLnN0YXRlKSA8IHN0ZDo6dGllKHJocy5wb3MsIHJocy5zdGF0ZSk7CiAgICB9Cn07CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIENvbXBhcmF0b3IgdG8gdXNlIGlmIHsxLCAyfSBhbmQgezIsIDN9IHNob3VsZCBub3Qgb3ZlcmxhcApjbGFzcyBMZXNzRXhjbHVkZUxpbWl0CnsKcHVibGljOgogICAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IEV2ZW50JiBsaHMsIGNvbnN0IEV2ZW50JiByaHMpIGNvbnN0CiAgICB7CiAgICAgICAgcmV0dXJuIHN0ZDo6dGllKGxocy5wb3MsIHJocy5zdGF0ZSkgPCBzdGQ6OnRpZShyaHMucG9zLCBsaHMuc3RhdGUpOwogICAgfQp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzdGQ6OnZlY3RvcjxFdmVudD4gTWFrZUV2ZW50cyhjb25zdCBzdGQ6OnZlY3RvcjxJbnRlcnZhbD4mIGludGVydmFscykKewogICAgc3RkOjp2ZWN0b3I8RXZlbnQ+IHJlczsKICAgIHN0ZDo6c2l6ZV90IGlkID0gMDsKICAgIGZvciAoY29uc3QgYXV0byYgaW50ZXJ2YWwgOiBpbnRlcnZhbHMpCiAgICB7CiAgICAgICAgcmVzLnB1c2hfYmFjayh7aW50ZXJ2YWwuc3RhcnQsIEVJbnRlcnZhbFN0YXRlOjpTdGFydCwgaWR9KTsKICAgICAgICByZXMucHVzaF9iYWNrKHtpbnRlcnZhbC5lbmQsIEVJbnRlcnZhbFN0YXRlOjpFbmQsIGlkfSk7CiAgICAgICAgKytpZDsKICAgIH0KICAgIHJldHVybiByZXM7Cn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdGVtcGxhdGUgPHR5cGVuYW1lIExlc3M+CnN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxzdGQ6OnNpemVfdCwgc3RkOjpzaXplX3Q+PgpDb21wdXRlT3ZlcmxhcHBpbmdJbnRlcnZhbHMoc3RkOjp2ZWN0b3I8RXZlbnQ+JiYgZXZlbnRzLCBMZXNzIGxlc3MpCnsKICAgIHN0ZDo6c29ydChldmVudHMuYmVnaW4oKSwgZXZlbnRzLmVuZCgpLCBsZXNzKTsKCiAgICBzdGQ6OnNldDxzdGQ6OnNpemVfdD4gYWN0aXZlSWRzOwogICAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPHN0ZDo6c2l6ZV90LCBzdGQ6OnNpemVfdD4+IHJlczsKCiAgICBmb3IgKGNvbnN0IGF1dG8mIGV2ZW50IDogZXZlbnRzKQogICAgewogICAgICAgIHN3aXRjaCAoZXZlbnQuc3RhdGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEVJbnRlcnZhbFN0YXRlOjpTdGFydDoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChjb25zdCBhdXRvJiBpZCA6IGFjdGl2ZUlkcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXMuZW1wbGFjZV9iYWNrKHN0ZDo6bWlubWF4KGV2ZW50LmlkLCBpZCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYWN0aXZlSWRzLmVtcGxhY2UoZXZlbnQuaWQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBFSW50ZXJ2YWxTdGF0ZTo6RW5kOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhY3RpdmVJZHMuZXJhc2UoZXZlbnQuaWQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzOwp9CgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmludCBtYWluKCkKewogICAgY29uc3Qgc3RkOjp2ZWN0b3I8SW50ZXJ2YWw+IGludGVydmFscyA9IHsKICAgICAgICB7MSwgM30sCiAgICAgICAgICAgICAgICAgICAgICAgezEyLCAxNH0sCiAgICAgICAgICB7MiwgNH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgezEzLCAxNX0sCiAgICAgICAgICAgICAgICAgezUsIDEwfQogICAgfTsKICAgIAogICAgZm9yIChjb25zdCBhdXRvJiBwIDogQ29tcHV0ZU92ZXJsYXBwaW5nSW50ZXJ2YWxzKE1ha2VFdmVudHMoaW50ZXJ2YWxzKSwgTGVzc0V4Y2x1ZGVMaW1pdHt9KSkgewogICAgICAgc3RkOjpjb3V0IDw8ICJpbnRlcnZhbHMgIiA8PCBwLmZpcnN0IDw8ICIgYW5kICIgPDwgcC5zZWNvbmQgPDwgIiBvdmVybGFwXG4iOwogICAgfQogICAgCn0K