2 # Chooses a random array element from the receiver based on the weights
3 # provided. If _weights_ is nil, then each element is weighed equally.
9 # If _weights_ is an array, then each element of the receiver gets its
10 # weight from the corresponding element of _weights_. Notice that it
11 # favors the element with the highest weight.
13 # [1,2,3].random([1,4,1]) #=> 2
14 # [1,2,3].random([1,4,1]) #=> 1
15 # [1,2,3].random([1,4,1]) #=> 2
16 # [1,2,3].random([1,4,1]) #=> 2
17 # [1,2,3].random([1,4,1]) #=> 3
19 # If _weights_ is a symbol, the weight array is constructed by calling
20 # the appropriate method on each array element in turn. Notice that
21 # it favors the longer word when using :length.
23 # ['dog', 'cat', 'hippopotamus'].random(:length) #=> "hippopotamus"
24 # ['dog', 'cat', 'hippopotamus'].random(:length) #=> "dog"
25 # ['dog', 'cat', 'hippopotamus'].random(:length) #=> "hippopotamus"
26 # ['dog', 'cat', 'hippopotamus'].random(:length) #=> "hippopotamus"
27 # ['dog', 'cat', 'hippopotamus'].random(:length) #=> "cat"
28 def random(weights=nil)
29 return random(map {|n| n.send(weights)}) if weights.is_a? Symbol
31 weights ||= Array.new(length, 1.0)
32 total = weights.inject(0.0) {|t,w| t+w}
35 zip(weights).each do |n,w|
36 return n if w >= point
41 # Generates a permutation of the receiver based on _weights_ as in
42 # Array#random. Notice that it favors the element with the highest
45 # [1,2,3].randomize #=> [2,1,3]
46 # [1,2,3].randomize #=> [1,3,2]
47 # [1,2,3].randomize([1,4,1]) #=> [2,1,3]
48 # [1,2,3].randomize([1,4,1]) #=> [2,3,1]
49 # [1,2,3].randomize([1,4,1]) #=> [1,2,3]
50 # [1,2,3].randomize([1,4,1]) #=> [2,3,1]
51 # [1,2,3].randomize([1,4,1]) #=> [3,2,1]
52 # [1,2,3].randomize([1,4,1]) #=> [2,1,3]
53 def randomize(weights=nil)
54 return randomize(map {|n| n.send(weights)}) if weights.is_a? Symbol
56 weights = weights.nil? ? Array.new(length, 1.0) : weights.dup
58 # pick out elements until there are none left
59 list, result = self.dup, []
62 result << list.random(weights)
63 # remove the element from the temporary list and its weight
64 weights.delete_at(list.index(result.last))
65 list.delete result.last