#include #include #include #include #include namespace { struct range_t { int from; int to; range_t(int from, int to) : from(from), to(to) {} void extend() { to++; } int size() const { return to - from + 1; } bool prefixes(int x) const { return x == to + 1; } }; std::ostream &operator<<(std::ostream &stream, const range_t &range) { if (range.size() >= 3) { stream << range.from << "-" << range.to; } else { stream << range.from; for (int i = range.from + 1; i <= range.to; i++) { stream << "," << i; } } return stream; } } // namespace std::string range_extraction(std::vector args) { if (args.empty()) { return ""; } std::vector ranges; for (int x : args) { if (ranges.size() && ranges.back().prefixes(x)) { ranges.back().extend(); } else { ranges.emplace_back(x, x); } } std::stringstream out; auto it = ranges.cbegin(); out << (*it); for (++it; it != ranges.cend(); ++it) { out << "," << (*it); } return out.str(); } int main() { assert(range_extraction({-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20}) == "-6,-3-1,3-5,7-11,14,15,17-20"); assert(range_extraction({-3, -2, -1, 2, 10, 15, 16, 18, 19, 20}) == "-3--1,2,10,15,16,18-20"); }