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;
}





Java: import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class RangeConsolidation {

    public static void main(String[] args) {
        displayRanges( Arrays.asList(new Range(1.1, 2.2)));
        displayRanges( Arrays.asList(new Range(6.1, 7.2), new Range(7.2, 8.3)));
        displayRanges( Arrays.asList(new Range(4, 3), new Range(2, 1)));
        displayRanges( Arrays.asList(new Range(4, 3), new Range(2, 1), new Range(-1, -2), new Range(3.9, 10)));
        displayRanges( Arrays.asList(new Range(1, 3), new Range(-6, -1), new Range(-4, -5), new Range(8, 2), new Range(-6, -6)));
        displayRanges( Arrays.asList(new Range(1, 1), new Range(1, 1)));
        displayRanges( Arrays.asList(new Range(1, 1), new Range(1, 2)));
        displayRanges( Arrays.asList(new Range(1, 2), new Range(3, 4), new Range(1.5, 3.5), new Range(1.2, 2.5)));
    }
    
    private static final void displayRanges(List<Range> ranges) {
        System.out.printf("ranges = %-70s, colsolidated = %s%n", ranges, Range.consolidate(ranges));
    }
    
    private static final class RangeSorter implements Comparator<Range> {
        @Override
        public int compare(Range o1, Range o2) {
            return (int) (o1.left - o2.left);
        }        
    }

    private static class Range {
        double left;
        double right;
        
        public Range(double left, double right) {
            if ( left <= right ) {
                this.left = left;
                this.right = right;
            }
            else {
                this.left = right;
                this.right = left;
            }
        }
        
        public Range consolidate(Range range) {
            
            if ( this.right < range.left ) {
                return null;
            }
            
            if ( range.right < this.left ) {
                return null;
            }
            
            if ( this.left <= range.left && this.right >= range.right ) {
                return this;
            }
            
            if ( range.left <= this.left && range.right >= this.right ) {
                return range;
            }
            
            if ( this.left <= range.left && this.right <= range.right ) {
                return new Range(this.left, range.right);
            }
            
            if ( this.left >= range.left && this.right >= range.right ) {
                return new Range(range.left, this.right);
            }
            throw new RuntimeException("ERROR:  Logic invalid.");
        }
        
        @Override
        public String toString() {
            return "[" + left + ", " + right + "]";
        }
        
        private static List<Range> consolidate(List<Range> ranges) {
            List<Range> consolidated = new ArrayList<>();
            
            Collections.sort(ranges, new RangeSorter());
            
            for ( Range inRange : ranges ) {
                Range r = null;
                Range conRange = null;
                for ( Range conRangeLoop : consolidated ) {
                    r = inRange.consolidate(conRangeLoop);
                    if (r != null ) {
                        conRange = conRangeLoop;
                        break;
                    }
                }
                if ( r == null ) {
                    consolidated.add(inRange);
                }
                else {
                    consolidated.remove(conRange);
                    consolidated.add(r);                    
                }
            }
            
            Collections.sort(consolidated, new RangeSorter());
            
            return consolidated;
        }
    }

}