Wren testing
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
foreign class Random {
|
||||
construct new() {
|
||||
seed_()
|
||||
}
|
||||
|
||||
construct new(seed) {
|
||||
if (seed is Num) {
|
||||
seed_(seed)
|
||||
} else if (seed is Sequence) {
|
||||
if (seed.isEmpty) Fiber.abort("Sequence cannot be empty.")
|
||||
|
||||
// TODO: Empty sequence.
|
||||
var seeds = []
|
||||
for (element in seed) {
|
||||
if (!(element is Num)) Fiber.abort("Sequence elements must all be numbers.")
|
||||
|
||||
seeds.add(element)
|
||||
if (seeds.count == 16) break
|
||||
}
|
||||
|
||||
// Cycle the values to fill in any missing slots.
|
||||
var i = 0
|
||||
while (seeds.count < 16) {
|
||||
seeds.add(seeds[i])
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
seed_(
|
||||
seeds[0], seeds[1], seeds[2], seeds[3],
|
||||
seeds[4], seeds[5], seeds[6], seeds[7],
|
||||
seeds[8], seeds[9], seeds[10], seeds[11],
|
||||
seeds[12], seeds[13], seeds[14], seeds[15])
|
||||
} else {
|
||||
Fiber.abort("Seed must be a number or a sequence of numbers.")
|
||||
}
|
||||
}
|
||||
|
||||
foreign seed_()
|
||||
foreign seed_(seed)
|
||||
foreign seed_(n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16)
|
||||
|
||||
foreign float()
|
||||
float(end) { float() * end }
|
||||
float(start, end) { float() * (end - start) + start }
|
||||
|
||||
foreign int()
|
||||
int(end) { (float() * end).floor }
|
||||
int(start, end) { (float() * (end - start)).floor + start }
|
||||
|
||||
sample(list) {
|
||||
if (list.count == 0) Fiber.abort("Not enough elements to sample.")
|
||||
return list[int(list.count)]
|
||||
}
|
||||
sample(list, count) {
|
||||
if (count > list.count) Fiber.abort("Not enough elements to sample.")
|
||||
|
||||
var result = []
|
||||
|
||||
// The algorithm described in "Programming pearls: a sample of brilliance".
|
||||
// Use a hash map for sample sizes less than 1/4 of the population size and
|
||||
// an array of booleans for larger samples. This simple heuristic improves
|
||||
// performance for large sample sizes as well as reduces memory usage.
|
||||
if (count * 4 < list.count) {
|
||||
var picked = {}
|
||||
for (i in list.count - count...list.count) {
|
||||
var index = int(i + 1)
|
||||
if (picked.containsKey(index)) index = i
|
||||
picked[index] = true
|
||||
result.add(list[index])
|
||||
}
|
||||
} else {
|
||||
var picked = List.filled(list.count, false)
|
||||
for (i in list.count - count...list.count) {
|
||||
var index = int(i + 1)
|
||||
if (picked[index]) index = i
|
||||
picked[index] = true
|
||||
result.add(list[index])
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
shuffle(list) {
|
||||
if (list.isEmpty) return
|
||||
|
||||
// Fisher-Yates shuffle.
|
||||
for (i in 0...list.count - 1) {
|
||||
var from = int(i, list.count)
|
||||
var temp = list[from]
|
||||
list[from] = list[i]
|
||||
list[i] = temp
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user