1
0
forked from Mirror/wren

Add Random.shuffle().

This commit is contained in:
Bob Nystrom
2016-02-07 10:38:39 -08:00
parent 79558d95e5
commit d4a4b26203
4 changed files with 67 additions and 0 deletions

View File

@ -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.

View File

@ -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
}
}
}

View File

@ -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
View 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