scala.util.Randomで乱数を生成する。
1から10までのランダムな数をつくるのはどうやるんだろう。
Scala Standard Library 2.12.8 - scala.util.Randomを見てみたが、おおむねjava.util.Randomとおなじか?
scala> import scala.util.Random import scala.util.Random scala> val r = new Random r: scala.util.Random = scala.util.Random@5f04eb scala> r.nextInt res173: Int = -49067135 scala> r.nextInt(10) res175: Int = 4 scala> r.nextInt(10) + 1 res176: Int = 1
ランダムな数字のリストがほしい
scala> r.shuffle((1 to 10).toSeq) res37: scala.collection.immutable.IndexedSeq[Int] = Vector(7, 4, 8, 9, 1, 3, 10, 5, 2, 6)
ちょっとちがうかな。
こうかなあ
scala> def r10 = r.nextInt(10) + 1 r10: Int scala> r10 res168: Int = 10 scala> r10 res169: Int = 1 scala> def infinitR10: Stream[Int] = Stream.cons(r10, infinitR10) infinitR10: Stream[Int] scala> infinitR10 take 20 res171: scala.collection.immutable.Stream[Int] = Stream(6, ?) scala> infinitR10 take 20 foreach println 10 2 1 8 6 6 4 8 5 4 9 7 10 2 6 7 6 2 4 10 scala>
あれ?なんか数が偏っている?一様になってないかな。うーん。集計してみる。
scala> b.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) => | acc + (e -> (acc.getOrElse(e, 0) + 1)) | } res208: scala.collection.immutable.Map[Int,Int] = Map(5 -> 6, 1 -> 1, 6 -> 2, 9 -> 3, 2 -> 2, 7 -> 1, 3 -> 1, 8 -> 2, 4 -> 2) scala> val c = infinitR10 take 10000 c: scala.collection.immutable.Stream[Int] = Stream(4, ?) scala> c.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) => | acc + (e -> (acc.getOrElse(e, 0) + 1)) | } res209: scala.collection.immutable.Map[Int,Int] = Map(5 -> 1038, 10 -> 1028, 1 -> 964, 6 -> 1008, 9 -> 1011, 2 -> 1018, 7 -> 1009, 3 -> 1000, 8 -> 930, 4 -> 994)
もっと多くのデータで!
ヒープのサイズを増やして、ScalaのREPLを起動しなおす。
F:\Data\ProgrammingLanguage\Scala\play-projects>scala -DXmx1024m Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) Client VM, Java 1.7.0_02). Type in expressions to have them evaluated. Type :help for more information. scala> import scala.util.Random import scala.util.Random scala> val r = new Random r: scala.util.Random = scala.util.Random@d7ba5b scala> def r10 = r.nextInt(10) + 1 r10: Int scala> def infinitR10: Stream[Int] = Stream.cons(r10, infinitR10) infinitR10: Stream[Int] scala> val d = infinitR10 take 1000000 d: scala.collection.immutable.Stream[Int] = Stream(1, ?) scala> val result = d.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) => | acc + (e -> (acc.getOrElse(e, 0) + 1)) | } result: scala.collection.immutable.Map[Int,Int] = Map(5 -> 100161, 10 -> 99790, 1 -> 99934, 6 -> 99675, 9 -> 99919, 2 -> 99738, 7 -> 99758, 3 -> 100131, 8 -> 100429, 4 -> 100465) scala> import scala.collection.immutable.TreeMap import scala.collection.immutable.TreeMap scala> val result2 = TreeMap[Int, Int]() result2: scala.collection.immutable.TreeMap[Int,Int] = Map() scala> result2 ++ result res6: scala.collection.immutable.TreeMap[Int,Int] = Map(1 -> 99934, 2 -> 99738, 3 -> 100131, 4 -> 100465, 5 -> 100161, 6 -> 99675, 7 -> 99758, 8 -> 100429, 9 -> 99919, 10 -> 99790) scala>
さらに要素の数を1000000から10000000にしたら、Out Of Memoryになってしまった。そうならないためのStreamではないのか?自分がなにかまちがっているのか。うーん。。。。
Scala Standard Library 2.12.8 - scala.collection.immutable.Streamにある例のIteratorを使う方法を試してみる。
scala> import scala.util.Random import scala.util.Random scala> val r = new Random r: scala.util.Random = scala.util.Random@d7ba5b scala> def r10 = r.nextInt(10) + 1 r10: Int scala> val it = new Iterator[Int] { | def hasNext = true | def next: Int = { r10 } | } it: java.lang.Object with Iterator[Int] = non-empty iterator scala> val d = it take 100000000 d: Iterator[Int] = non-empty iterator scala> val result = d.foldLeft (Map[Int, Int]()) { (acc: Map[Int, Int], e: Int) => | acc + (e -> (acc.getOrElse(e, 0) + 1)) | } result: scala.collection.immutable.Map[Int,Int] = Map(5 -> 9999613, 10 -> 9998925, 1 -> 10005035, 6 -> 10004810, 9 -> 9992785, 2 -> 9995009, 7 -> 9999772, 3 -> 10002721, 8 -> 10000349, 4 -> 10000981) scala> import scala.collection.immutable.TreeMap import scala.collection.immutable.TreeMap scala> val result2 = TreeMap[Int, Int]() result2: scala.collection.immutable.TreeMap[Int,Int] = Map() scala> result2 ++ result res7: scala.collection.immutable.TreeMap[Int,Int] = Map(1 -> 10005035, 2 -> 9995009, 3 -> 10002721, 4 -> 10000981, 5 -> 9999613, 6 -> 10004810, 7 -> 9999772, 8 -> 10000349, 9 -> 9992785, 10 -> 9998925) scala>
おおー、Iteratorだと、10000000どころか100000000でもだいじょうぶだ。
もはや、主題がRandomのはなしでなくなってしまったが、、、、Streamはつかいかたは、勉強だな。とりあえずは、Iteratorがお手軽だと。