Answer the question
In order to leave comments, you need to log in
How to get the remaining range after "cutting" parts out of that range?
Hello. There is a scale from 0 to 86400 (in fact, these are seconds received from 0 to 24h).
There is some range on this scale, for example [32400, 54000] (9-15 hours).
This range is the only one.
Ranges of the same kind are “thrown” to it from the outside, which “cut out” some parts of it as well.
Someone may not hit at all, someone may hit completely, some range may completely overlap the target range, and nothing will remain of the target range (there are test cases at the end)
According to the result, 2 pieces will remain from the target range:
This is the result which the function should return -
I wrote a function that works 90% of the time. But 1 case turns the function into incorrectly working.
type TRange = [number, number];
export const getSpaceRanges = (bounds: TRange, intersections: TRange[]) => {
const clonedBounds = clone(bounds);
let correctBounds: TRange[] = [clonedBounds];
if (isEmpty(intersections)) {
return correctBounds;
}
forEach(intersections, (intersection) => {
const [intersectionStart, intersectionEnd] = intersection;
const lastBoundsBlockIndex = correctBounds.length - 1;
const [lastBoundsBlockStart, lastBoundsBlockEnd] = correctBounds[lastBoundsBlockIndex];
if (intersectionStart <= lastBoundsBlockStart && intersectionEnd >= lastBoundsBlockEnd) {
correctBounds = [];
return false;
}
if (intersectionStart <= lastBoundsBlockStart && intersectionEnd <= lastBoundsBlockStart) {
return;
}
if (intersectionStart <= lastBoundsBlockStart && intersectionEnd > lastBoundsBlockStart) {
correctBounds[lastBoundsBlockIndex][0] = intersectionEnd;
return;
}
if (intersectionStart > lastBoundsBlockStart && intersectionEnd < lastBoundsBlockEnd) {
const prevLastBoundsBlockEnd = lastBoundsBlockEnd;
correctBounds[lastBoundsBlockIndex][1] = intersectionStart;
correctBounds.push([intersectionEnd, prevLastBoundsBlockEnd]);
return;
}
if (
(intersectionStart < lastBoundsBlockEnd && intersectionEnd > lastBoundsBlockEnd) ||
(intersectionStart > lastBoundsBlockStart && intersectionEnd === lastBoundsBlockEnd)
) {
correctBounds[lastBoundsBlockIndex][1] = intersectionStart;
return;
}
if (intersectionStart >= lastBoundsBlockEnd) {
return;
}
});
return correctBounds;
};
it("Обрезание трека диапазонами", () => {
const bounds: TRange = [32400, 54000];
expect(getSpaceRanges(bounds, [])).toEqual([bounds]);
expect(getSpaceRanges(bounds, )).toEqual([bounds]);
expect(getSpaceRanges(bounds, )).toEqual([bounds]);
expect(getSpaceRanges(bounds, )).toEqual();
expect(getSpaceRanges(bounds, )).toEqual([]);
expect(getSpaceRanges(bounds, )).toEqual([]);
expect(getSpaceRanges(bounds, )).toEqual([bounds]); // Скорее всего, это невозможно
expect(getSpaceRanges(bounds, )).toEqual();
expect(getSpaceRanges(bounds, )).toEqual([]);
expect(getSpaceRanges(bounds, )).toEqual([]);
expect(getSpaceRanges(bounds, )).toEqual([
[32400, 38000],
[38000, 54000],
]); // Скорее всего, это невозможно, но если возможно, продумать
expect(getSpaceRanges(bounds, )).toEqual([
[32400, 38000],
[52000, 54000],
]);
expect(getSpaceRanges(bounds, )).toEqual();
expect(getSpaceRanges(bounds, )).toEqual();
expect(getSpaceRanges(bounds, )).toEqual([bounds]);
expect(getSpaceRanges(bounds, )).toEqual([bounds]);
expect(getSpaceRanges(bounds, )).toEqual([bounds]);
/** Более сложные случаи */
expect(
getSpaceRanges(bounds, [
[38000, 40000],
[45000, 52000],
])
).toEqual([
[32400, 38000],
[40000, 45000],
[52000, 54000],
]);
expect(
getSpaceRanges(bounds, [
[33000, 45000],
[35000, 48000],
[46000, 52000],
])
).toEqual([
[32400, 33000],
[52000, 54000],
]);
// expect(
// getSpaceRanges(bounds, [
// [35000, 37000],
// [36000, 54000],
// ])
// ).toEqual();
expect(
getSpaceRanges(bounds, [
[5400, 10500],
[35000, 37000],
[56000, 58000],
])
).toEqual([
[32400, 35000],
[37000, 54000],
]);
expect(
getSpaceRanges(bounds, [
[5400, 33000],
[35000, 37000],
[53000, 58000],
])
).toEqual([
[33000, 35000],
[37000, 53000],
]);
});
Answer the question
In order to leave comments, you need to log in
const bounds: TRange = [32400, 54000];
// getSpaceRanges(bounds, [
// [35000, 37000],
// [36000, 54000],
// ])
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question