-
Notifications
You must be signed in to change notification settings - Fork 142
/
Copy pathmerge_intervals.scala
39 lines (33 loc) · 1.03 KB
/
merge_intervals.scala
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
object MergeIntervals extends App {
def time[R](block: => R): R = {
val t0 = System.currentTimeMillis()
val result = block // call-by-name
val t1 = System.currentTimeMillis()
println("Elapsed time: " + (t1 - t0) + "ms")
result
}
implicit val orderRanges = Ordering.by {range: Range => range.head}
implicit class RangeOps(a: Range) {
def overlaps(b: Range): Boolean = {
a.last >= b.head
}
def merge(b: Range): Range = {
val start = Math.min(a.head, b.head)
val end = Math.max(a.last, b.last)
start to end
}
}
def mergeIntervals(input: Vector[Range]): Vector[Range] = {
input.sorted.foldLeft[Vector[Range]](Vector())((acc, next) => {
acc match {
case ranges :+ lastRange if lastRange.overlaps(next) => ranges :+ lastRange.merge(next)
case _ => acc :+ next
}
})
}
val input = Vector(1 to 3, 2 to 6, 8 to 10, 8 to 10, 15 to 18)
val output = time {
mergeIntervals(input)
}
assert(output == Vector(1 to 6, 8 to 10, 15 to 18))
}