Skip to content

Instantly share code, notes, and snippets.

@lancearlaus
Last active January 13, 2016 15:50
Show Gist options
  • Save lancearlaus/c9a07ec8151af97801de to your computer and use it in GitHub Desktop.
Save lancearlaus/c9a07ec8151af97801de to your computer and use it in GitHub Desktop.
Sample code to find the windowed max in a series of numbers
import org.scalatest.{Matchers, WordSpec}
object SeqOps {
// Adds windowing operations to sequences
implicit class WindowOps[A](val seq: Seq[A]) extends AnyVal {
def windowedMax[T, X](window: T)(t: A => T, x: A => X)(implicit numeric: Numeric[T], ordering: Ordering[X]): Seq[A] =
seq.tail.scanLeft(Seq(seq.head)) { case (s, cur) =>
val tmin = numeric.minus(t(cur), window)
val nonExpired = s.dropWhile(e => numeric.lteq(t(e), tmin))
val greater = nonExpired.takeWhile(e => ordering.gt(x(e), x(cur)))
greater :+ cur
}.map(_.head)
}
}
class GeminiProbSpec extends WordSpec with Matchers {
import SeqOps._
case class Element(t: Int, x: Int)
"windowedMax" should {
"find max in ascending sequence" in {
val input = (0 to 5).map(i => Element(i, i)).toSeq
val expected = (0 to 5).map(i => Element(i, i)).toSeq
input.windowedMax(3)(_.t, _.x) shouldBe expected
}
"find max in descending sequence" in {
val input = (10 to 0 by -1).map(i => Element(10 - i, i)).toSeq
val expected = Seq.fill(3)(Element(0, 10)) ++ (1 to 8).map(i => Element(i, 10 - i))
input.windowedMax(3)(_.t, _.x) shouldBe expected
}
// TODO: Test cyclic and repetitive data sets
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment