Skip to content

Instantly share code, notes, and snippets.

@ryanlecompte
Last active December 19, 2015 21:08
Show Gist options
  • Save ryanlecompte/6017746 to your computer and use it in GitHub Desktop.
Save ryanlecompte/6017746 to your computer and use it in GitHub Desktop.
Finding the number of "monotonicity flips" in a Seq[Int] in Scala
// Finds the monotonicity breaks in a numerical sequence.
def findMonotonicityBreaks(items: Seq[Int]): Int = {
def comp(op: Symbol, a: Int, b: Int) = if (op == '<=) a <= b else a >= b
def flip(op: Symbol) = if (op == '<=) '>= else '<=
@tailrec
def detect(pairs: Seq[(Int, Int)], op: Symbol, breaks: Int): Int = {
pairs match {
case Seq() => breaks
case Seq((a, b), rest @ _*) if comp(op, a, b) => detect(rest, op, breaks)
case _ => detect(pairs, flip(op), breaks + 1)
}
}
if (items.isEmpty) 0
else {
val pairs = items.zip(items.tail)
pairs.collectFirst {
case (a, b) if a < b => '<=
case (a, b) if a > b => '>=
}.map { op => detect(pairs, op, 0)
}.getOrElse(0)
}
}
// Usage:
scala> findMonotonicityBreaks(Seq.empty[Int])
res21: Int = 0
scala> findMonotonicityBreaks(Seq(0,1,2,3,4,4,4,4,5,6))
res22: Int = 0
scala> findMonotonicityBreaks(Seq(0,1,2,3,3,3,2,1))
res23: Int = 1
scala> findMonotonicityBreaks(Seq(1,2,3,4,5,6,5,4,5,6,7))
res24: Int = 2
scala> findMonotonicityBreaks(Seq(5,4,3,2,1,0))
res25: Int = 0
scala> findMonotonicityBreaks(Seq(7,6,5,4,5,6,5,4,3,2,1))
res26: Int = 2
scala> findMonotonicityBreaks(Seq(1,2,3,3,3,2,1,0))
res27: Int = 1
scala> findMonotonicityBreaks(Seq(1,2,3,4,5,6,5,4,5,6,7,6,5,4,3))
res28: Int = 3
scala> findMonotonicityBreaks(scala.util.Random.shuffle(Vector.range(1, 100000)))
res29: Int = 66498
scala> findMonotonicityBreaks(Seq(5,5,5,4,3,2,1,0))
res30: Int = 0
scala> findMonotonicityBreaks(Seq(5,5,5,4,3,2,1,0,2,3,4,5))
res31: Int = 1
scala> findMonotonicityBreaks(Seq(1,1,1,1,2))
res32: Int = 0
scala> findMonotonicityBreaks(Seq(1,1,1,1,2,1))
res33: Int = 1
@ryanlecompte
Copy link
Author

Great solutions, guys! Aren't Scala collections fun?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment