hampusohlsson / intersecting-ranges

Find the intersection of N intervals
MIT License
8 stars 2 forks source link

Unexpected result from intersecting ranges #4

Open mattes3 opened 6 years ago

mattes3 commented 6 years ago

I have tried this:

const intersectingRanges = require("intersecting-ranges");

const colors = [
    [0, 8, { color: 'red' }],
    [10, 14, { color: 'brown' }],
    [16, 24, { color: 'blue' }],
    [20, 29, { color: 'yellow' }]
];

const result = intersectingRanges(colors, { withData: true, omitEmpty: false });

console.log('result', result);

As a result, I get

result [ [ 20, 24, { color: 'yellow' } ] ]

However, I expected more because I have set omitEmpty=false. And: Is it possible to merge the colors into an array like [ [ 20, 24, { color: ['blue', 'yellow'] } ] ] because both colors were present in the original intervals?

By the way: Can you help me solve the original problem here? https://stackoverflow.com/questions/52555253/how-do-intersect-intervals-in-javascript

hampusohlsson commented 5 years ago

Hey @mattes3

The way the Marzullo intersection algorithm works is by adding "layers" of intersections, and sending back the result at the maximum depth. The omitEmpty flag only dictates whether to send back the original intervals if there are no overlaps at all.

So in your example, your intervals looks like this:

        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 262 27 28 29 
Layer 1 |---------------|   |------------|    |------------------------|
Layer 2                                                   |----------------------------|

Result                                                    |------------|

As you can see here, there's a max of 2 layers, and the algorithm spits out the ranges at that layer (20,24). If you add another overlapping interval at that layer, the result becomes:

        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 262 27 28 29 
Layer 1 |---------------|   |------------|    |------------------------|
Layer 2             |-----|                               |----------------------------|

Result              |---|                                 |------------|

However, as soon as you add another overlap that adds another layer to the number of intersections, only that layer will be returned.

        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 262 27 28 29 
Layer 1 |---------------|   |------------|    |------------------------|
Layer 2             |-----|                               |----------------------------|
Layer 3                                                |------|

Result                                                    |---|

Unfortunately I don't have time to improve the library with the additional features you're asking for. The source code is pretty small, so if you want to help out, PRs are welcome!