rand 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +25 -0
- data/Manifest.txt +7 -0
- data/README.txt +62 -0
- data/Rakefile +52 -0
- data/lib/rand.rb +319 -0
- data/setup.rb +1585 -0
- data/test/test_rand.rb +183 -0
- metadata +70 -0
data/History.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
== 0.9.1 / 2007-05-27
|
2
|
+
|
3
|
+
* (setup.rb) Added setup 3.4.1, for non-gem users.
|
4
|
+
|
5
|
+
* (Rakefile) Now we just require 'hoe' from seattle.rb and override
|
6
|
+
a few tasks which aren't generated to our liking. (Keegan Quinn, 2007-05-29)
|
7
|
+
|
8
|
+
* Rearranged files to match the usual Ruby project layout.
|
9
|
+
(Keegan Quinn, 2007-05-29)
|
10
|
+
|
11
|
+
* (install.rb) Removed old installation script. (Keegan Quinn, 2007-05-29)
|
12
|
+
|
13
|
+
* lib/rand.rb: New shuffle. (Ilmari Heikkinen, 2005-01-04)
|
14
|
+
|
15
|
+
* test/test_rand.rb: Bias tests. (Ilmari Heikkinen, 2005-01-04)
|
16
|
+
|
17
|
+
* lib/rand.rb: Document _with_index methods. (Christian Neukirchen, 2004-12-03)
|
18
|
+
|
19
|
+
* lib/rand.rb: Add pick_with_index. (Christian Neukirchen, 2004-12-02)
|
20
|
+
|
21
|
+
|
22
|
+
== 0.9.0 / 2004-11-29
|
23
|
+
|
24
|
+
* Initial release.
|
25
|
+
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
= rand.rb -- library for picking random elements and shuffling
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
|
5
|
+
rand.rb adds new methods to Enumerable, Array, and Hash to:
|
6
|
+
|
7
|
+
* return a random element (+pick+, +pick_index+, +pick_key+,
|
8
|
+
+pick_value+ and their destructive versions suffixed with
|
9
|
+
<tt>!</tt>).
|
10
|
+
|
11
|
+
* arrange elements in new, random order (+shuffle+,
|
12
|
+
+shuffle_hash_pairs+, +shuffle_hash+).
|
13
|
+
|
14
|
+
* use above methods in convenient ways (+each_random+, +map_random+).
|
15
|
+
|
16
|
+
|
17
|
+
It also provides these new facilities to String:
|
18
|
+
|
19
|
+
* +shuffle_chars+, to arrange the characters of the string in new order.
|
20
|
+
|
21
|
+
* +pick_byte+, +pick_char+ and +pick_index+, to return random bytes,
|
22
|
+
characters or elements.
|
23
|
+
|
24
|
+
|
25
|
+
== Limitations
|
26
|
+
|
27
|
+
* Enumerable#pick does not work for infinite Enumerables. (Doesn't
|
28
|
+
make sense, anyway.)
|
29
|
+
|
30
|
+
* Enumerable#pick has O(n) memory usage in worst case. There is an
|
31
|
+
alternative solution at [ruby-talk:94451], but not yet integrated
|
32
|
+
into rand.rb.
|
33
|
+
|
34
|
+
* Enumerable#shuffle is sightly biased due the limited number of
|
35
|
+
Floats between 0 and 1. This will possibly be addressed in a later
|
36
|
+
release.
|
37
|
+
|
38
|
+
|
39
|
+
== Authors
|
40
|
+
|
41
|
+
Ilmari Heikkinen <mailto:kig@misfiring.net>:: Code and unit tests
|
42
|
+
Christian Neukirchen <mailto:chneukirchen@gmail.com>:: Documentation and
|
43
|
+
housekeeping.
|
44
|
+
|
45
|
+
Please mail bugs, feature requests or patches to the mail addresses
|
46
|
+
above or use IRC[irc://freenode.net/#ruby-lang] to contact the
|
47
|
+
developers.
|
48
|
+
|
49
|
+
|
50
|
+
== History
|
51
|
+
|
52
|
+
November 26, 2004:: Initial version done as IRC collaboration project
|
53
|
+
between <tt>kig</tt> and <tt>chris2</tt>.
|
54
|
+
|
55
|
+
November 29, 2004:: First public release 0.9.
|
56
|
+
|
57
|
+
|
58
|
+
== Copyright
|
59
|
+
|
60
|
+
Copyright (C) 2004 Ilmari Heikkinen
|
61
|
+
Parts Copyright (C) 2004 Christian Neukirchen
|
62
|
+
This work is licensed under the same terms as Ruby itself.
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# $Id: Rakefile 24 2007-07-14 13:24:11Z keegan $
|
2
|
+
# Copyright 2007 Keegan Quinn
|
3
|
+
#
|
4
|
+
# Rakefile for rand, a library to shuffle and pick elements at random.
|
5
|
+
#
|
6
|
+
# This script can be redistributed and/or modified under the terms of the
|
7
|
+
# Ruby license. It comes without any warranty, to the extent permitted by
|
8
|
+
# applicable law.
|
9
|
+
|
10
|
+
|
11
|
+
SHORTNAME = 'rand'
|
12
|
+
PKG_FILES = [ '[A-Z]*', 'setup.rb', 'lib/**/*.rb', 'test/**/*.rb' ]
|
13
|
+
PKG_VERSION = '0.9.1'
|
14
|
+
RDOC_OPTIONS = [
|
15
|
+
'--title', 'rand -- Random elements and shuffling', '--main', 'README.txt',
|
16
|
+
'--line-numbers', '--inline-source', '--all'
|
17
|
+
]
|
18
|
+
|
19
|
+
|
20
|
+
# Generate tasks with hoe
|
21
|
+
require 'hoe'
|
22
|
+
|
23
|
+
h = Hoe.new(SHORTNAME, PKG_VERSION) do |p|
|
24
|
+
p.rubyforge_name = SHORTNAME
|
25
|
+
p.summary = 'A library for picking random elements and shuffling.'
|
26
|
+
p.description = p.summary
|
27
|
+
|
28
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
29
|
+
|
30
|
+
p.url = 'http://rand.rubyforge.org'
|
31
|
+
p.email = 'keegan@rubyforge.org'
|
32
|
+
p.author = [ 'Ilmari Heikkinen', 'Christian Neukirchen', 'Keegan Quinn' ]
|
33
|
+
|
34
|
+
p.need_zip = true
|
35
|
+
p.remote_rdoc_dir = 'rdoc'
|
36
|
+
|
37
|
+
p.spec_extras = { 'rdoc_options' => RDOC_OPTIONS }
|
38
|
+
end
|
39
|
+
|
40
|
+
Rake::RDocTask.new(:docs) do |rd|
|
41
|
+
rd.main = "README.txt"
|
42
|
+
rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/
|
43
|
+
rd.rdoc_dir = 'doc'
|
44
|
+
|
45
|
+
files = h.spec.files.grep(/^(lib|bin)|txt$/)
|
46
|
+
files -= ['Manifest.txt']
|
47
|
+
rd.rdoc_files.push(*files)
|
48
|
+
|
49
|
+
title = "#{h.name}-#{h.version} Documentation"
|
50
|
+
|
51
|
+
rd.options << "-t #{title}"
|
52
|
+
end
|
data/lib/rand.rb
ADDED
@@ -0,0 +1,319 @@
|
|
1
|
+
# $Id: rand.rb 23 2007-07-14 13:13:48Z keegan $
|
2
|
+
# Copyright 2007 Keegan Quinn
|
3
|
+
# Copyright 2004 Christian Neukirchen
|
4
|
+
# Copyright 2004 Ilmari Heikkinen
|
5
|
+
#
|
6
|
+
# rand.rb -- library for picking random elements and shuffling
|
7
|
+
|
8
|
+
|
9
|
+
module Enumerable
|
10
|
+
# Choose and return a random element of the Enumerable.
|
11
|
+
# [1, 2, 3, 4].pick #=> 2 (or 1, 3, 4)
|
12
|
+
def pick
|
13
|
+
entries.pick
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return an array of the elements in random order.
|
17
|
+
# [1, 2, 3, 4].shuffle #=> [3, 4, 1, 2]
|
18
|
+
def shuffle
|
19
|
+
entries.shuffle
|
20
|
+
end
|
21
|
+
|
22
|
+
# Calls _block_ once for each element in _self_ in random order,
|
23
|
+
# passing that element as a parameter.
|
24
|
+
def each_random(&block)
|
25
|
+
shuffle.each(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Invokes _block_ once for each element of _self_ in random order.
|
29
|
+
# Creates a new array containing the values returned by the block.
|
30
|
+
def map_random(&block)
|
31
|
+
shuffle.map(&block)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
class Array
|
37
|
+
# Choose and return a random element of _self_.
|
38
|
+
# [1, 2, 3, 4].pick #=> 2 (or 1, 3, 4)
|
39
|
+
def pick
|
40
|
+
self[pick_index]
|
41
|
+
end
|
42
|
+
|
43
|
+
# Deletes a random element of _self_, returning that element.
|
44
|
+
# a = [1, 2, 3, 4]
|
45
|
+
# a.pick #=> 2
|
46
|
+
# a #=> [1, 3, 4]
|
47
|
+
def pick!
|
48
|
+
i = pick_index
|
49
|
+
rv = self[i]
|
50
|
+
delete_at(i)
|
51
|
+
rv
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return the index of an random element of _self_.
|
55
|
+
# ["foo", "bar", "baz"].pick_index #=> 1 (or 0, or 2)
|
56
|
+
def pick_index
|
57
|
+
rand(size)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Destructive pick_index. Delete a random element of _self_ and
|
61
|
+
# return its index.
|
62
|
+
# a = [11, 22, 33, 44]
|
63
|
+
# a.pick_index! #=> 2
|
64
|
+
# a #=> [11, 22, 44]
|
65
|
+
def pick_index!
|
66
|
+
i = pick_index
|
67
|
+
delete_at i
|
68
|
+
i
|
69
|
+
end
|
70
|
+
|
71
|
+
# Return a random element of _self_ with its index.
|
72
|
+
# a = ["a", "b", "c", "d"]
|
73
|
+
# a.pick_with_index #=> ["b", 1]
|
74
|
+
# a #=> ["a", "b", "c", "d"]
|
75
|
+
def pick_with_index
|
76
|
+
i = pick_index
|
77
|
+
[self[i], i]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Delete and return a random element of _self_ with its index.
|
81
|
+
# a = ["a", "b", "c", "d"]
|
82
|
+
# a.pick_with_index! #=> ["b", 1]
|
83
|
+
# a #=> ["a", "c", "d"]
|
84
|
+
def pick_with_index!
|
85
|
+
rv = pick_with_index
|
86
|
+
delete_at rv[1]
|
87
|
+
rv
|
88
|
+
end
|
89
|
+
|
90
|
+
# Return an array of the elements in random order.
|
91
|
+
# [11, 22, 33, 44].shuffle #=> [33, 11, 44, 22]
|
92
|
+
def shuffle
|
93
|
+
dup.shuffle!
|
94
|
+
end
|
95
|
+
|
96
|
+
# Destructive shuffle. Arrange the elements of _self_ in new order.
|
97
|
+
# Using Fisher-Yates shuffle.
|
98
|
+
# a = [11, 22, 33, 44]
|
99
|
+
# a.shuffle!
|
100
|
+
# a #=> [33, 11, 44, 22]
|
101
|
+
def shuffle!
|
102
|
+
(size-1).downto(1) {|index|
|
103
|
+
other_index = rand(index+1)
|
104
|
+
next if index == other_index
|
105
|
+
tmp = self[index]
|
106
|
+
self[index] = self[other_index]
|
107
|
+
self[other_index] = tmp
|
108
|
+
}
|
109
|
+
self
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
class Hash
|
115
|
+
# Choose and return a random key-value pair of _self_.
|
116
|
+
# {:one => 1, :two => 2, :three => 3}.pick #=> [:one, 1]
|
117
|
+
def pick
|
118
|
+
k = keys.pick
|
119
|
+
[k, self[k]]
|
120
|
+
end
|
121
|
+
|
122
|
+
# Deletes a random key-value pair of _self_, returning that pair.
|
123
|
+
# a = {:one => 1, :two => 2, :three => 3}
|
124
|
+
# a.pick #=> [:two, 2]
|
125
|
+
# a #=> {:one => 1, :three => 3}
|
126
|
+
def pick!
|
127
|
+
rv = pick
|
128
|
+
delete rv.first
|
129
|
+
rv
|
130
|
+
end
|
131
|
+
|
132
|
+
# Return a random key of _self_.
|
133
|
+
# {:one => 1, :two => 2, :three => 3}.pick_key #=> :three
|
134
|
+
def pick_key
|
135
|
+
keys.pick
|
136
|
+
end
|
137
|
+
|
138
|
+
# Return a random value of _self_.
|
139
|
+
# {:one => 1, :two => 2, :three => 3}.pick_value #=> 3
|
140
|
+
def pick_value
|
141
|
+
values.pick
|
142
|
+
end
|
143
|
+
|
144
|
+
# Delete a random key-value pair of _self_ and return the key.
|
145
|
+
# a = {:one => 1, :two => 2, :three => 3}
|
146
|
+
# a.pick_key! #=> :two
|
147
|
+
# a #=> {:one => 1, :three => 3}
|
148
|
+
def pick_key!
|
149
|
+
pick!.first
|
150
|
+
end
|
151
|
+
|
152
|
+
# Delete a random key-value pair of _self_ and return the value.
|
153
|
+
# a = {:one => 1, :two => 2, :three => 3}
|
154
|
+
# a.pick_value! #=> 2
|
155
|
+
# a #=> {:one => 1, :three => 3}
|
156
|
+
def pick_value!
|
157
|
+
pick!.last
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return the key-value pairs of _self_ with _keys_ and _values_
|
161
|
+
# shuffled independedly.
|
162
|
+
# {:one => 1, :two => 2, :three => 3}.shuffle_hash_pairs
|
163
|
+
# #=> [[:one, 3], [:two, 1], [:three, 2]]
|
164
|
+
def shuffle_hash_pairs
|
165
|
+
keys.shuffle.zip(values.shuffle)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Return a copy of _self_ with _values_ arranged in random order.
|
169
|
+
# {:one => 1, :two => 2, :three => 3}.shuffle_hash
|
170
|
+
# #=> {:two=>2, :three=>1, :one=>3}
|
171
|
+
def shuffle_hash
|
172
|
+
shuffled = {}
|
173
|
+
shuffle_hash_pairs.each{|k, v|
|
174
|
+
shuffled[k] = v
|
175
|
+
}
|
176
|
+
shuffled
|
177
|
+
end
|
178
|
+
|
179
|
+
# Destructive shuffle_hash. Arrange the values of _self_ in
|
180
|
+
# new, random order.
|
181
|
+
# h = {:one => 1, :two => 2, :three => 3}
|
182
|
+
# h.shuffle_hash!
|
183
|
+
# h #=> {:two=>2, :three=>1, :one=>3}
|
184
|
+
def shuffle_hash!
|
185
|
+
shuffle_hash_pairs.each{|k, v|
|
186
|
+
self[k] = v
|
187
|
+
}
|
188
|
+
self
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
class String
|
194
|
+
# Return the string with characters arranged in random order.
|
195
|
+
# "Ruby rules".shuffle_chars #=> "e lybRsuur"
|
196
|
+
def shuffle_chars
|
197
|
+
dup.shuffle_chars!
|
198
|
+
end
|
199
|
+
|
200
|
+
# Destructive shuffle_chars. Arrange the characters of the string
|
201
|
+
# in new, random order.
|
202
|
+
# s = "Ruby rules".shuffle_chars
|
203
|
+
# s.shuffle_chars!
|
204
|
+
# s #=> "e lybRsuur"
|
205
|
+
def shuffle_chars!
|
206
|
+
(0...size).each {|j|
|
207
|
+
i = rand(size-j)
|
208
|
+
self[j], self[j+i] = self[j+i], self[j]
|
209
|
+
}
|
210
|
+
self
|
211
|
+
end
|
212
|
+
|
213
|
+
# Return a random byte of _self_.
|
214
|
+
# "Ruby rules".pick_byte #=> 121
|
215
|
+
def pick_byte
|
216
|
+
self[pick_index]
|
217
|
+
end
|
218
|
+
|
219
|
+
# Return a single-character string of a random character in _self_.
|
220
|
+
# "Ruby rules".pick_char #=> "y"
|
221
|
+
def pick_char
|
222
|
+
pick_byte.chr
|
223
|
+
end
|
224
|
+
|
225
|
+
# Destructive pick_char. Delete a random character of the string
|
226
|
+
# and return it as a single-character string.
|
227
|
+
# s = "Ruby rules"
|
228
|
+
# s.pick_char! #=> "y"
|
229
|
+
# s #=> "Rub rules"
|
230
|
+
def pick_char!
|
231
|
+
i = pick_index
|
232
|
+
rv = self[i,1]
|
233
|
+
self[i,1] = ""
|
234
|
+
rv
|
235
|
+
end
|
236
|
+
|
237
|
+
# Destructive pick_byte. Delete a random byte of _self_ and return it.
|
238
|
+
# s = "Ruby rules"
|
239
|
+
# s.pick_byte! #=> 121
|
240
|
+
# s #=> "Rub rules"
|
241
|
+
def pick_byte!
|
242
|
+
pick_char![0]
|
243
|
+
end
|
244
|
+
|
245
|
+
# Return a random byte index of _self_.
|
246
|
+
# "Ruby rules".pick_index #=> 3
|
247
|
+
def pick_index
|
248
|
+
rand(size)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Destructive pick_index. Delete a random byte of _self_ and
|
252
|
+
# return it's index.
|
253
|
+
# s = "Ruby rules"
|
254
|
+
# s.pick_index #=> 3
|
255
|
+
# s #=> "Rub rules"
|
256
|
+
def pick_index!
|
257
|
+
i = pick_index
|
258
|
+
self[i,1] = ""
|
259
|
+
i
|
260
|
+
end
|
261
|
+
|
262
|
+
# Return a two element array consisting of an random byte of _self_
|
263
|
+
# and it's index.
|
264
|
+
# "Ruby rules".pick_byte_with_index #=> [121, 3]
|
265
|
+
def pick_byte_with_index
|
266
|
+
i = pick_index
|
267
|
+
[self[i], i]
|
268
|
+
end
|
269
|
+
|
270
|
+
# Destructive pick_byte_with_index. Delete a random byte of _self_
|
271
|
+
# and return it and it's index.
|
272
|
+
# s = "Ruby rules"
|
273
|
+
# s.pick_byte_with index! #=> [121, 3]
|
274
|
+
# s #=> "Rub rules"
|
275
|
+
def pick_byte_with_index!
|
276
|
+
rv = pick_byte_with_index
|
277
|
+
delete_at(rv[0])
|
278
|
+
rv
|
279
|
+
end
|
280
|
+
|
281
|
+
# Return a single-character string of a random character in _self_
|
282
|
+
# and it's index.
|
283
|
+
# "Ruby rules".pick_char_with_index #=> ["y", 3]
|
284
|
+
def pick_char_with_index
|
285
|
+
byte, index = pick_byte_with_index
|
286
|
+
[byte.chr, index]
|
287
|
+
end
|
288
|
+
|
289
|
+
# Destructive pick_char_with_index. Delete a random character of
|
290
|
+
# the string and return it as a single-character string together
|
291
|
+
# with it's index.
|
292
|
+
# s = "Ruby rules"
|
293
|
+
# s.pick_char_with_index! #=> ["y", 3]
|
294
|
+
# s #=> "Rub rules"
|
295
|
+
def pick_char_with_index!
|
296
|
+
byte, index = pick_byte_with_index!
|
297
|
+
[byte.chr, index]
|
298
|
+
end
|
299
|
+
|
300
|
+
def pick
|
301
|
+
to_a.pick
|
302
|
+
end
|
303
|
+
|
304
|
+
def pick!
|
305
|
+
pick_with_index![0]
|
306
|
+
end
|
307
|
+
|
308
|
+
def pick_with_index
|
309
|
+
to_a.pick_with_index
|
310
|
+
end
|
311
|
+
|
312
|
+
def pick_with_index!
|
313
|
+
tokens = to_a
|
314
|
+
s, index = tokens.pick_with_index
|
315
|
+
start = tokens[0, index].join
|
316
|
+
self[start.size, s.size] = ""
|
317
|
+
[s, index]
|
318
|
+
end
|
319
|
+
end
|