Skip to content

Instantly share code, notes, and snippets.

@codeck
Forked from Centaur/it.scala
Last active January 2, 2016 13:38
Show Gist options
  • Save codeck/8311102 to your computer and use it in GitHub Desktop.
Save codeck/8311102 to your computer and use it in GitHub Desktop.
val arg1 = Iterator(2, 3, 4, 8, 9, 12, 14, 17)
val arg2 = Iterator(1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 17)
//??(arg1, arg2)=> Iterator((2, 4), (8, 9), (12, 12),(14, 17))
case class CeRange(start:Int, end:Option[Int]) {
def passed(br: Int) = {
end.map(br < _).getOrElse(true)
}
}
def mkRanges(substrate:Iterator[Int]):Iterator[CeRange] = {
val bufit = substrate.buffered
Iterator.continually(bufit.hasNext).takeWhile(identity).map(_ => {
val x = bufit.next()
if (bufit.hasNext) CeRange(x, Some(bufit.head))
else CeRange(x, None)
})
}
def breakRanges(origin: Iterator[CeRange],
breaks:Iterator[Int]):Iterator[CeRange] = {
val bufbreaks = breaks.buffered
origin.map(r => {
Iterator.continually(bufbreaks.hasNext).takeWhile(_ && bufbreaks.head <= r.start).foreach(_ =>bufbreaks.next)
if (bufbreaks.hasNext && r.passed(bufbreaks.head)) {
r.copy(end = Some(bufbreaks.next()))
}
else r
})
}
def mergeRanges(origin: Iterator[CeRange]):Iterator[CeRange] = {
val bufit = origin.buffered
Iterator.continually(bufit.hasNext).takeWhile(identity).map(_ => bufit.next).
scanLeft(Right(CeRange(0, None)):Either[CeRange, CeRange])(
(record, curr) => {
if (bufit.hasNext && bufit.head.start == curr.end.get) Left({
record.left.toOption.map(_.copy(end = curr.end)).getOrElse(curr)
})
else Right(
record.left.toOption.map(identity).getOrElse(CeRange(curr.start, Some(curr.start)))
)
}).drop(1).collect{case Right(r) => r}
}
mergeRanges(breakRanges(mkRanges(arg1), arg2)).foreach(println)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment