Task: Range consolidation


C++: #include <algorithm>
#include <iostream>
#include <utility>
#include <vector>



template <typename iterator>
void normalize_ranges(iterator begin, iterator end) {
    for (iterator i = begin; i != end; ++i) {
        if (i->second < i->first)
            std::swap(i->first, i->second);
    }
    std::sort(begin, end);
}



template <typename iterator>
iterator merge_ranges(iterator begin, iterator end) {
    iterator out = begin;
    for (iterator i = begin; i != end; ) {
        iterator j = i;
        while (++j != end && j->first <= i->second)
            i->second = std::max(i->second, j->second);
        *out++ = *i;
        i = j;
    }
    return out;
}

template <typename iterator>
iterator consolidate_ranges(iterator begin, iterator end) {
    normalize_ranges(begin, end);
    return merge_ranges(begin, end);
}

template <typename pair>
void print_range(std::ostream& out, const pair& range) {
    out << '[' << range.first << ", " << range.second << ']';
}

template <typename iterator>
void print_ranges(std::ostream& out, iterator begin, iterator end) {
    if (begin != end) {
        print_range(out, *begin++);
        for (; begin != end; ++begin) {
            out << ", ";
            print_range(out, *begin);
        }
    }
}

int main() {
    std::vector<std::pair<double, double>> test_cases[] = {
        { {1.1, 2.2} },
        { {6.1, 7.2}, {7.2, 8.3} },
        { {4, 3}, {2, 1} },
        { {4, 3}, {2, 1}, {-1, -2}, {3.9, 10} },
        { {1, 3}, {-6, -1}, {-4, -5}, {8, 2}, {-6, -6} }
    };
    for (auto&& ranges : test_cases) {
        print_ranges(std::cout, std::begin(ranges), std::end(ranges));
        std::cout << " -> ";
        auto i = consolidate_ranges(std::begin(ranges), std::end(ranges));
        print_ranges(std::cout, std::begin(ranges), i);
        std::cout << '\n';
    }
    return 0;
}


C#: using static System.Math;
using System.Linq;
using System;

public static class RangeConsolidation
{
    public static void Main() {
        foreach (var list in new [] {
            new[] { (1.1, 2.2) }.ToList(),
            new[] { (6.1, 7.2), (7.2, 8.3) }.ToList(),
            new[] { (4d, 3d), (2, 1) }.ToList(),
            new[] { (4d, 3d), (2, 1), (-1, 2), (3.9, 10) }.ToList(),
            new[] { (1d, 3d), (-6, -1), (-4, -5), (8, 2), (-6, -6) }.ToList()
        })
        {
            for (int z = list.Count-1; z >= 1; z--) {
                for (int y = z - 1; y >= 0; y--) {
                    if (Overlap(list[z], list[y])) {
                        list[y] = Consolidate(list[z], list[y]);
                        list.RemoveAt(z);
                        break;
                    }
                }
            }
            Console.WriteLine(string.Join(", ", list.Select(Normalize).OrderBy(range => range.s)));
        }
    }

    private static bool Overlap((double s, double e) left, (double s, double e) right) =>
        Max(left.s, left.e) > Max(right.s, right.e)
        ? Max(right.s, right.e) >= Min(left.s, left.e)
        : Max(left.s, left.e) >= Min(right.s, right.e);

    private static (double s, double e) Consolidate((double s, double e) left, (double s, double e) right) =>
        (Min(Min(left.s, left.e), Min(right.s, right.e)), Max(Max(left.s, left.e), Max(right.s, right.e)));
    
    private static (double s, double e) Normalize((double s, double e) range) =>
        (Min(range.s, range.e), Max(range.s, range.e));
}