Last active
September 21, 2022 16:08
-
-
Save retraigo/51c3c2d0d288c0b4a1a692d720282fd0 to your computer and use it in GitHub Desktop.
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
// Weighted random selection in Scala 2 | |
// You have an array of items. Each item is an unsigned integer. | |
// The value of each item determines its weight. | |
// Higher the weight, higher the chance of rolling it. | |
class Fortuna(items: Array[Double]) { | |
private val weights = items; | |
private val cumulativeWeights: Array[Double] = new Array(items.length); | |
private var totalChance: Double = 0; | |
for (i <- 0 until items.length) { | |
cumulativeWeights(i) = totalChance + items(i); | |
totalChance = totalChance + items(i); | |
} | |
def get(count: Int): Array[Int] = { | |
val result = new Array[Int](count); | |
for (i <- 0 until count) { | |
result(i) = roll(); | |
} | |
return result; | |
} | |
def get_with_linear_search(count: Int): Array[Int] = { | |
val result = new Array[Int](count); | |
for (i <- 0 until count) { | |
result(i) = roll_with_linear_search(); | |
} | |
return result; | |
} | |
def roll(): Int = { | |
if (cumulativeWeights.length == 1) return -1; | |
val rng = Math.random() * totalChance; | |
var lower = 0; | |
var max = cumulativeWeights.length - 1; | |
var mid = ((max + lower) / 2); | |
while (mid != 0 && lower <= max) { | |
if ( | |
(cumulativeWeights(mid) > rng && | |
cumulativeWeights(mid - 1) < rng) || | |
cumulativeWeights(mid) == rng | |
) return mid; | |
if (cumulativeWeights(mid) < rng) { | |
lower = mid + 1; | |
mid = ((max + lower) / 2); | |
} else { | |
max = mid - 1; | |
mid = ((max + lower) / 2); | |
} | |
} | |
return mid; | |
} | |
def roll_with_linear_search(): Int = { | |
if (weights.length == 1) return -1; | |
val rng = Math.random() * totalChance; | |
var total = totalChance; | |
var i = 0; | |
if (totalChance == 0) { | |
while (i < weights.length) { | |
total = total + weights(i); | |
i = i + 1; | |
} | |
} | |
val result = Math.random() * total; | |
var going = 0.0; | |
i = 0; | |
while (i < weights.length) { | |
going = going + weights(i); | |
if (result < going) { | |
return i; | |
} | |
i = i + 1; | |
} | |
return (Math.random() * weights.length).toInt; | |
} | |
} | |
object Test { | |
val data: Array[Double] = Array(25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 11, | |
11, 11, 25, 25, 25, 11, 1, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 11, 11, 11, 25, 25, 25, 11, 25, 1, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 11, 11, 11, 11, 11, 11, 11, 11, 1, 1, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 11, 11, 11, 11, 11, 11, 11, | |
25, 25, 1, 1, 1, 1, 1, 1, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 11, 11, | |
11, 25, 25, 11, 11, 25, 11, 1, 1, 1, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 11, | |
11, 25, 1, 1, 1, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 1, 1, 25, 25, 25, 25, 1, 1, 1, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | |
25, 25, 25, 1, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25); | |
def main(args: Array[String]) = { | |
println("Woke"); | |
val machine = new Fortuna(data); | |
println(s"${machine.get(1000).toSeq}") | |
println(s"${machine.get_with_linear_search(1000).toSeq}") | |
} | |
} |
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
// Weighted random selection in Scala 3 | |
// You have an array of items. Each item is an unsigned integer. | |
// The value of each item determines its weight. | |
// Higher the weight, higher the chance of rolling it. | |
class Fortuna(items: Array[Double]) { | |
private val weights = items; | |
private val cumulativeWeights: Array[Double] = new Array(items.length); | |
private var totalChance: Double = 0; | |
for (i <- 0 until items.length) { | |
cumulativeWeights(i) = totalChance + items(i); | |
totalChance = totalChance + items(i); | |
} | |
def get(count: Int): Array[Int] = | |
val result = new Array[Int](count); | |
for (i <- 0 until count) { | |
result(i) = roll(); | |
} | |
return result; | |
def get_with_linear_search(count: Int): Array[Int] = | |
val result = new Array[Int](count); | |
for (i <- 0 until count) { | |
result(i) = roll_with_linear_search(); | |
} | |
return result; | |
def roll(): Int = | |
if (cumulativeWeights.length == 1) return -1; | |
val rng = Math.random() * totalChance; | |
var lower = 0; | |
var max = cumulativeWeights.length - 1; | |
var mid = ((max + lower) / 2); | |
while ( | |
mid != 0 && lower <= max | |
) { | |
if ( | |
(cumulativeWeights(mid) > rng && | |
cumulativeWeights(mid - 1) < rng) || | |
cumulativeWeights(mid) == rng | |
) return mid; | |
if (cumulativeWeights(mid) < rng) { | |
lower = mid + 1; | |
mid = ((max + lower) / 2); | |
} else { | |
max = mid - 1; | |
mid = ((max + lower) / 2); | |
} | |
} | |
return mid; | |
def roll_with_linear_search(): Int = | |
if (weights.length == 1) return -1; | |
val rng = Math.random() * totalChance; | |
var total = totalChance; | |
var i = 0; | |
if (totalChance == 0) { | |
while (i < weights.length) { | |
total = total + weights(i); | |
i = i + 1; | |
} | |
} | |
val result = Math.random() * total; | |
var going = 0.0; | |
i = 0; | |
while (i < weights.length) { | |
going = going + weights(i); | |
if (result < going) { | |
return i; | |
} | |
i = i + 1; | |
} | |
return (Math.random() * weights.length).toInt; | |
} | |
val data: Array[Double] = Array(25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,11,25,25,25,11,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,11,25,25,25,11,25,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,11,11,11,11,11,11,1,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,11,11,11,11,11,25,25,1,1,1,1,1,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,11,25,25,11,11,25,11,1,1,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,11,11,25,1,1,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,1,1,25,25,25,25,1,1,1,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,1,25,25,25,25,25,25,25,25,25,25,25,25); | |
@main def Test() = | |
val machine = new Fortuna(data); | |
println(s"${machine.get(1000).toSeq}") | |
println(s"${machine.get_with_linear_search(1000).toSeq}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment