Created
October 19, 2017 18:57
-
-
Save battermann/aec4d82681b88a0c0cc50ceaee35e894 to your computer and use it in GitHub Desktop.
functional pseudo random number generation
This file contains 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
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