Skip to content

Instantly share code, notes, and snippets.

@benhutchison
Created April 23, 2015 06:18
Show Gist options
  • Save benhutchison/9a1b6d891211ea18d699 to your computer and use it in GitHub Desktop.
Save benhutchison/9a1b6d891211ea18d699 to your computer and use it in GitHub Desktop.
Property-based test of Queue.cycle(n: Int)
package com.github.benhutchison.richutil
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification
import org.scalacheck.Arbitrary
import spire.math.Natural
class QueueUtilSpec extends Specification with ScalaCheck {
import collection.immutable.Queue
import ScalacheckIntegration._
implicit def queueGen = QueueUtil.dist[Int](5)
import QueueUtil._
import IntUtil._
import NaturalUtil._
{Queue(1, 2, 3).cycle(0.toNat).mustEqual(Queue(1, 2, 3))}.eg
{Queue(1, 2, 3).cycle().mustEqual(Queue(2, 3, 1))}.eg
{Queue(1, 2, 3).cycle(1.toNat).mustEqual(Queue(2, 3, 1))}.eg
{Queue(1, 2, 3).cycle(2.toNat).mustEqual(Queue(3, 1, 2))}.eg
{Queue(1, 2, 3).cycle(3.toNat).mustEqual(Queue(1, 2, 3))}.eg
{Queue(1, 2, 3).cycle(4.toNat).mustEqual(Queue(2, 3, 1))}.eg
{Queue.empty[Any].cycle(1.toNat).mustEqual(Queue.empty[Any])}.eg
{Queue(1).cycle(2.toNat).mustEqual(Queue(1))}.eg
"cycling a queue 'q' by 'n' is equivalent to: q.drop(n % q.size) ++ q.take(n % q.size) " !
prop { (q: Queue[Int], n: Natural) => (q.size > 0) ==> {
val sz = q.size
val (take, drop) = q.splitAt((n % sz.toNat).toInt)
q.cycle(n) == Queue((drop ++ take):_*)
}}
}
package com.github.benhutchison.richutil
import collection.immutable.Queue
import util.Random
import spire.random.{Generator, Dist}
import spire.math.Natural
import scala.collection.mutable.ArrayBuffer
trait QueueUtil {
implicit def queueOps[T](q: Queue[T]) = new QueueOps(q)
def dist[T](size: Int)(implicit ts: Dist[T]) = new Dist[Queue[T]] {
def apply(gen: Generator): Queue[T] = Queue(ts.toIterator(gen).take(gen.nextInt(size + 1)).toSeq:_*)
}
}
object QueueUtil extends QueueUtil
class QueueOps[T](val q: Queue[T]) extends AnyVal {
import IntUtil._
def cycle(amount: Natural = 1.toNat): Queue[T] = {
if (amount == 0 || q.isEmpty)
q
else {
var q2: Queue[T] = q
var i = amount
while (i > 0) {
@unchecked val (front: T, deq: Queue[T]) = q2.dequeue
q2 = deq.enqueue(front)
i -= 1.toNat
}
q2
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment