rand 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|