Skip to content

Instantly share code, notes, and snippets.

@battermann
Created October 19, 2017 18:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save battermann/aec4d82681b88a0c0cc50ceaee35e894 to your computer and use it in GitHub Desktop.
Save battermann/aec4d82681b88a0c0cc50ceaee35e894 to your computer and use it in GitHub Desktop.
functional pseudo random number generation
import cats.data.State
object PRNG {
final case class Seed(seed: Long) {
private lazy val next = Seed(seed * 6364136223846793005L + 1442695040888963407L)
def nextInt: (Seed, Int) = {
(next, (next.seed >>> 16).asInstanceOf[Int])
}
def nonNegativeInt: (Seed, Int) = {
val (seed, value) = nextInt
(seed, if (value < 0) -(value + 1) else value)
}
def nextInt(bound: Int): (Seed, Int) = {
val (seed, value) = nonNegativeInt
(seed, value % bound)
}
def nextDouble: (Seed, Double) = {
val (seed, value) = nonNegativeInt
(seed, value / (Int.MaxValue.toDouble + 1))
}
}
def nextInt: State[Seed, Int] = State[Seed, Int](s => s.nextInt)
def nextInt(bound: Int): State[Seed, Int] = State[Seed, Int](s => s.nextInt(bound))
def nextDouble: State[Seed, Double] = State[Seed, Double](s => s.nextDouble)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment