Task: Range consolidation

C: #include <stdio.h>
#include <stdlib.h>

typedef struct range_tag {
    double low;
    double high;
} range_t;

void normalize_range(range_t* range) {
    if (range->high < range->low) {
        double tmp = range->low;
        range->low = range->high;
        range->high = tmp;
    }
}

int range_compare(const void* p1, const void* p2) {
    const range_t* r1 = p1;
    const range_t* r2 = p2;
    if (r1->low < r2->low)
        return -1;
    if (r1->low > r2->low)
        return 1;
    if (r1->high < r2->high)
        return -1;
    if (r1->high > r2->high)
        return 1;
    return 0;
}

void normalize_ranges(range_t* ranges, size_t count) {
    for (size_t i = 0; i < count; ++i)
        normalize_range(&ranges[i]);
    qsort(ranges, count, sizeof(range_t), range_compare);
}



size_t consolidate_ranges(range_t* ranges, size_t count) {
    normalize_ranges(ranges, count);
    size_t out_index = 0;
    for (size_t i = 0; i < count; ) {
        size_t j = i;
        while (++j < count && ranges[j].low <= ranges[i].high) {
            if (ranges[i].high < ranges[j].high)
                ranges[i].high = ranges[j].high;
        }
        ranges[out_index++] = ranges[i];
        i = j;
    }
    return out_index;
}

void print_range(const range_t* range) {
    printf("[%g, %g]", range->low, range->high);
}

void print_ranges(const range_t* ranges, size_t count) {
    if (count == 0)
        return;
    print_range(&ranges[0]);
    for (size_t i = 1; i < count; ++i) {
        printf(", ");
        print_range(&ranges[i]);
    }
}

void test_consolidate_ranges(range_t* ranges, size_t count) {
    print_ranges(ranges, count);
    printf(" -> ");
    count = consolidate_ranges(ranges, count);
    print_ranges(ranges, count);
    printf("\n");
}

#define LENGTHOF(a) sizeof(a)/sizeof(a[0])

int main() {
    range_t test1[] = { {1.1, 2.2} };
    range_t test2[] = { {6.1, 7.2}, {7.2, 8.3} };
    range_t test3[] = { {4, 3}, {2, 1} };
    range_t test4[] = { {4, 3}, {2, 1}, {-1, -2}, {3.9, 10} };
    range_t test5[] = { {1, 3}, {-6, -1}, {-4, -5}, {8, 2}, {-6, -6} };
    test_consolidate_ranges(test1, LENGTHOF(test1));
    test_consolidate_ranges(test2, LENGTHOF(test2));
    test_consolidate_ranges(test3, LENGTHOF(test3));
    test_consolidate_ranges(test4, LENGTHOF(test4));
    test_consolidate_ranges(test5, LENGTHOF(test5));
    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));
}