forked from Mirror/wren
Add Random.shuffle().
This commit is contained in:
@ -93,3 +93,23 @@ Returns an integer between `start` and `end`, including `start` but excluding
|
||||
System.print(random.int(3, 4)) //> 3
|
||||
System.print(random.int(-10, 10)) //> -6
|
||||
System.print(random.int(-4, 2)) //> -2
|
||||
|
||||
### **shuffle**(list)
|
||||
|
||||
Randomly shuffles the elements in `list`. The items are randomly re-ordered in
|
||||
place.
|
||||
|
||||
:::wren
|
||||
var random = Random.new(12345)
|
||||
var list = (1..5).toList
|
||||
random.shuffle(list)
|
||||
System.print(list) //> [3, 2, 4, 1, 5]
|
||||
|
||||
Uses the Fisher-Yates algorithm to ensure that all permutations are chosen
|
||||
with equal probability.
|
||||
|
||||
Keep in mind that a list with even a modestly large number of elements has an
|
||||
astronomically large number of permutations. For example, there are about 10^74
|
||||
ways a deck of 56 cards can be shuffled. The random number generator's internal
|
||||
state is not that large, which means there are many permutations it will never
|
||||
generate.
|
||||
|
||||
@ -46,4 +46,16 @@ foreign class Random {
|
||||
foreign int()
|
||||
int(end) { (float() * end).floor }
|
||||
int(start, end) { (float() * (end - start)).floor + start }
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,4 +48,16 @@ static const char* randomModuleSource =
|
||||
" foreign int()\n"
|
||||
" int(end) { (float() * end).floor }\n"
|
||||
" int(start, end) { (float() * (end - start)).floor + start }\n"
|
||||
"\n"
|
||||
" shuffle(list) {\n"
|
||||
" if (list.isEmpty) return\n"
|
||||
"\n"
|
||||
" // Fisher-Yates shuffle.\n"
|
||||
" for (i in 0...list.count - 1) {\n"
|
||||
" var from = int(i, list.count)\n"
|
||||
" var temp = list[from]\n"
|
||||
" list[from] = list[i]\n"
|
||||
" list[i] = temp\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
23
test/random/shuffle.wren
Normal file
23
test/random/shuffle.wren
Normal file
@ -0,0 +1,23 @@
|
||||
import "random" for Random
|
||||
|
||||
var random = Random.new(12345)
|
||||
|
||||
// Empty list.
|
||||
var list = []
|
||||
random.shuffle(list)
|
||||
System.print(list) // expect: []
|
||||
|
||||
// One element.
|
||||
list = [1]
|
||||
random.shuffle(list)
|
||||
System.print(list) // expect: [1]
|
||||
|
||||
// Given enough tries, should generate all permutations.
|
||||
var hits = {}
|
||||
for (i in 1..200) {
|
||||
var list = [1, 2, 3, 4]
|
||||
random.shuffle(list)
|
||||
hits[list.toString] = true
|
||||
}
|
||||
|
||||
System.print(hits.count) // expect: 24
|
||||
Reference in New Issue
Block a user