import sun.reflect.generics.reflectiveObjects.NotImplementedException | |
object X extends App { | |
trait RNG { | |
def nextInt: (Int, RNG) | |
} | |
object RNG { | |
def simple(seed: Long): RNG = new RNG { | |
def nextInt = { | |
val seed2 = (seed*0x5DEECE66DL + 0xBL) & | |
((1L << 48) - 1) | |
((seed2 >>> 16).asInstanceOf[Int], | |
simple(seed2)) | |
} | |
} | |
} | |
def positiveInt(rng: RNG): (Int, RNG) = { | |
val (n, newRng) = rng.nextInt | |
val pos = if (n == Int.MinValue) 0 else n.abs | |
(pos, newRng) | |
} | |
def positiveInt2(rng: RNG): (Int, RNG) = rng.nextInt match { | |
case (Int.MinValue, nextRng) => (0, nextRng) | |
case (n, nextRng) => (n.abs, nextRng) | |
} | |
def ints(count: Int)(rng: RNG): (List[Int], RNG) = | |
if (count <= 0) (Nil, rng) | |
else rng.nextInt match { | |
case (n, nextRng) => | |
val (tail, nextRng2) = ints(count - 1)(nextRng) | |
(n :: tail, nextRng2) | |
} | |
type Rand[+A] = RNG => (A, RNG) | |
def map[A,B](s: Rand[A])(f: A => B): Rand[B] = | |
rng => { | |
val (a, rng2) = s(rng) | |
(f(a), rng2) | |
} | |
def positiveMax(n: Int): Rand[Int] = map(_.nextInt) { r => (r % n).abs } | |
val double: Rand[Double] = map(_.nextInt) { r => r.toDouble / Int.MaxValue } | |
def map2[A,B,C](ra: Rand[A], rb: Rand[B])(f: (A, B) => C): Rand[C] = | |
rng => { | |
val (a, rng2) = ra(rng) | |
val (b, rng3) = rb(rng2) | |
(f(a, b), rng3) | |
} | |
val intDouble: (RNG) => ((Int, Double), RNG) = map2(_.nextInt, double) { (_, _) } | |
val doubleInt = map2(double, _.nextInt) { (_, _) } | |
def sequence[A](fs: List[Rand[A]]): Rand[List[A]] = fs match { | |
case Nil => { rng => (Nil, rng) } | |
case head :: tail => { rng => | |
val (a, interRng) = head(rng) | |
val (rest, nextRng) = sequence(tail)(interRng) | |
(a :: rest, nextRng) | |
} | |
} | |
def RngMock(nums: List[Int]): RNG = new RNG { | |
def nextInt = nums match { | |
case Nil => throw new NotImplementedException | |
case head :: tail => (head, RngMock(tail)) | |
} | |
} | |
println(RNG.simple(4).nextInt) | |
println((Int.MinValue - 1).abs) | |
println(Int.MinValue.abs) | |
println(ints(10)(RngMock(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)))) | |
println(positiveMax(100000)(RngMock(List(100010)))) | |
println(sequence(List[Rand[Int]](_.nextInt, _.nextInt, _.nextInt))(RngMock(List(1, 4, 8)))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment