class Interval {
constructor(start, end) {
this.start = start
this.end = end
}
merge(interval2) {
if (this.isOverlapped(interval2)) {
let resultStart, resultEnd
resultStart = this.start <= interval2.start ? this.start : interval2.start
resultEnd = this.end >= interval2.end ? this.end : interval2.end
return [new Interval(resultStart, resultEnd)]
} else {
return this.start <= interval2.start ? [this, interval2] : [interval2, this]
}
}
isOverlapped(interval2) {
let i1, i2
if (this.start <= interval2.start) {
i1 = this
i2 = interval2
} else {
i1 = interval2
i2 = this
}
return i1.end >= i2.start && i1.start <= i2.end
}
get print() {
return `[${this.start}, ${this.end}]`
}
get toArray() {
return [this.start, this.end]
}
}
class Intervals {
constructor() {
this.collection = []
}
add(newInterval) {
if (this.collection.length === 0) {
this.collection.push(newInterval)
return
}
let isMerged = false
this.collection.forEach((existedInterval, index) => {
if (newInterval.isOverlapped(existedInterval)) {
this.collection[index] = existedInterval.merge(newInterval)[0]
isMerged = true
}
})
if (!isMerged) {
this.collection.push(newInterval)
}
}
get print() {
return JSON.stringify(this.collection.map((x) => x.toArray))
}
}
const test = [
[new Interval(1, 2), new Interval(2, 3), true, [[1, 3]]],
[new Interval(2, 3), new Interval(1, 2), true, [[1, 3]]],
[new Interval(2, 4), new Interval(1, 3), true, [[1, 4]]],
[new Interval(1, 3), new Interval(2, 4), true, [[1, 4]]],
[new Interval(2, 4), new Interval(1, 5), true, [[1, 5]]],
[new Interval(1, 2), new Interval(3, 4), false, [[1, 2], [3, 4]]],
[new Interval(3, 4), new Interval(1, 2), false, [[1, 2], [3, 4]]],
[new Interval(15, 18), new Interval(15, 18), false, [[15, 18]]],
]
// test is two intervals overlaps
test.forEach((testData) => {
console.log(`test is overlapped[${testData[0].print}, ${testData[1].print}] - ${testData[0].isOverlapped(testData[1]) == testData[2] ? 'passed' : 'isnt passed'}`)
})
// test two intervals merging
test.forEach((testData) => {
const result = testData[0].merge(testData[1])
console.log(`test merging[${testData[0].print}, ${testData[1].print}] => [${result.map((x) => x.print)}] - ${JSON.stringify(result.map((x) => x.toArray)) == JSON.stringify(testData[3]) ? 'passed' : 'isnt passed'}`)
})
const test2 = [
{
input: [[1, 3], [2, 6], [8, 10], [15, 18]],
expectedResult: [[1, 6], [8, 10], [15, 18]]
},
{
input: [[1, 4], [4, 5]],
expectedResult: [[1, 5]]
},
{
input: [[1, 4], [2, 3]],
expectedResult: [[1, 4]]
},
{
input: [[1, 3], [5, 8], [2, 6]],
expectedResult: [[1, 8]]
},
]
test2.forEach((testData) => {
const result = new Intervals()
testData.input.forEach((testInterval) => result.add(new Interval(...testInterval)))
console.log(result.print)
console.log(`test merging multiple ${JSON.stringify(testData.input)} => ${JSON.stringify(testData.expectedResult)} - ${JSON.stringify(testData.expectedResult) == result.print ? 'passed' : 'isnt passed'}`)
})