Created
March 12, 2017 05:24
-
-
Save deyindra/3e76ecc7e8857614819cfd4f23de98a1 to your computer and use it in GitHub Desktop.
Custom Random Generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.idey.scala.generator | |
import scala.util.Random | |
/** | |
* Generator Trait for any Random object generator if any types | |
* @tparam T type of any [[scala.Any]] | |
*/ | |
trait Generator[+T] { | |
self => | |
def generate : T | |
def map[S](f: T=>S): Generator[S] = new Generator[S] { | |
def generate:S = f(self.generate) | |
} | |
def flatMap[S](f: T=>Generator[S]): Generator[S] = new Generator[S] { | |
def generate:S = f(self.generate).generate | |
} | |
} | |
/** | |
* Random Integers generator return integer value based on [[Random]] | |
*/ | |
object Integers extends Generator[Int]{ | |
override def generate: Int = { | |
new Random().nextInt() | |
} | |
} | |
/** | |
* Random Boolean generator randomly generate either true or false base on [[Integers]] provide the integer is greater | |
* than 0 | |
* | |
*/ | |
object Booleans extends Generator[Boolean]{ | |
override def generate: Boolean = { | |
(Integers map {x => x >0}).generate | |
} | |
} | |
/** | |
* Always return a +ve integer between low and high (low inclusive) | |
* @param lo lower boundary | |
* @param hi higher boundary | |
* @see [[Integers]] | |
*/ | |
case class IntervalRandomInteger(lo : Int, hi : Int) extends Generator[Int] { | |
override def generate: Int = { | |
require(lo >=0 ) | |
require(hi > lo ) | |
(Integers map {x => if (x > 0 ) lo + x%(hi - lo) else lo + (-x)%(hi - lo)}).generate | |
} | |
} | |
/** | |
* Always return the same value | |
* @param x type of T | |
* @tparam T type of any [[scala.Any]] | |
*/ | |
case class Singleton[T](x : T) extends Generator[T]{ | |
override def generate: T = x | |
} | |
/** | |
* Return any single value randomly from the seq | |
* @param xs [[scala.Seq]] of type T | |
* @tparam T type of any [[scala.Any]] | |
*/ | |
case class ChooseOneGenerator[T](xs:T*) extends Generator[T]{ | |
override def generate: T = { | |
(IntervalRandomInteger(0, xs.length) map {x=>xs(x)}).generate | |
} | |
} | |
/** | |
* Return random [[scala.List]] of type T by selected values from xs | |
* @param xs [[scala.Seq]] of type T | |
* @tparam T type of any [[scala.Any]] | |
*/ | |
case class RandomListGenerator[T](xs:T*) extends Generator[List[T]]{ | |
override def generate: List[T] = { | |
def generateRandomList(acc:List[T]):List[T] = { | |
val isEmpty = Booleans.generate | |
if(isEmpty){ | |
if(acc.isEmpty) | |
Nil | |
else | |
acc | |
}else{ | |
(IntervalRandomInteger(0, xs.length) map {x=>xs(x)}).generate :: generateRandomList(acc) | |
} | |
} | |
generateRandomList(List()) | |
} | |
} | |
trait Tree[+T] | |
case class Leaf[T] (t : T) extends Tree[T] | |
case class Inner[T](left : Tree[T], right: Tree[T]) extends Tree[T] | |
/** | |
* Return random [[Tree]] of type T by selected values from xs | |
* @param xs [[scala.Seq]] of type T | |
* @tparam T type of any [[scala.Any]] | |
*/ | |
case class RandomTree[T] (xs:T*) extends Generator[Tree[T]]{ | |
override def generate: Tree[T] = { | |
val isLeaf = Booleans.generate | |
val value : T = (IntervalRandomInteger(0, xs.length) map {x=>xs(x)}).generate | |
if(isLeaf) | |
Leaf(value) | |
else | |
Inner(generate,generate) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment