COVERAGE SUMMARY
FILE SUMMARY
NameExecutedRoutines%ExecutedLines%Unexecuted
/home/matt/eu/rds/include/std/rand.e6785.71%355761.40%22
ROUTINE SUMMARY
RoutineExecutedLinesUnexecuted
sample()0200.00%20
roll()7977.78%2
chance()22100.00%0
rand_range()88100.00%0
rnd()99100.00%0
rnd_1()55100.00%0
set_rand()33100.00%0
LINE COVERAGE DETAIL
#Executed
1
-- (c) Copyright - See License.txt
2
--
3
4
namespace random
5
6
--****
7
-- == Random Numbers
8
--
9
-- <>
10
--
11
12
--****
13
-- Signature:
14
-- function rand(object maximum)
15
--
16
-- Description:
17
-- Return a random positive integer.
18
--
19
-- Parameters:
20
-- # ##maximum## : an atom, a cap on the value to return.
21
--
22
-- Returns:
23
-- An **integer**, from 1 to ##maximum##.
24
--
25
-- Errors:
26
-- If [[:ceil]](##maximum##) is not a positive integer <= 1073741823,
27
-- an error will occur. It must also be at least 1.
28
--
29
-- Comments:
30
-- This function may be applied to an atom or to all elements of a sequence.
31
-- In order to get reproducible results from this function, you should call
32
-- [[:set_rand]]() with a reproducible value prior.
33
--
34
-- Example 1:
35
--
36
-- s = rand({10, 20, 30})
37
-- -- s might be: {5, 17, 23} or {9, 3, 12} etc.
38
--
39
--
40
-- See Also:
41
-- [[:set_rand]], [[:ceil]]
42
43
44
--**
45
-- Return a random integer from a specified inclusive integer range.
46
--
47
-- Parameters:
48
-- # ##lo## : an integer, the lower bound of the range
49
-- # ##hi## : an integer, the upper bound of the range.
50
--
51
-- Returns:
52
-- An **integer**, randomly drawn between ##lo## and ##hi## inclusive.
53
--
54
-- Errors:
55
-- If ##lo## is not less than ##hi##, an error will occur.
56
--
57
-- Comments:
58
-- This function may be applied to an atom or to all elements of a sequence.
59
-- In order to get reproducible results from this function, you should
60
-- call ##set_rand##() with a reproducible value prior.
61
--
62
-- Example 1:
63
--
64
-- s = rand_range(18, 24)
65
-- -- s could be any of: 18, 19, 20, 21, 22, 23 or 24
66
--
67
--
68
-- See Also:
69
-- [[:rand]], [[:set_rand]], [[:rnd]]
70
7135
72
7335
if lo > hi then
741
integer temp = hi
751
hi = lo
761
lo = temp
77
end if
78
7935
lo -= 1
8035
hi -= lo
81
8235
return lo + rand(hi)
83
end function
84
85101
constant M_SET_RAND = 35
86
87
--**
88
-- Return a random floating point number in the range 0 to 1.
89
--
90
-- Parameters:
91
-- None.
92
--
93
-- Returns:
94
-- An **atom**, randomly drawn between 0.0 and 1.0 inclusive.
95
--
96
-- Comments:
97
-- In order to get reproducible results from this function, you should
98
-- call ##set_rand##() with a reproducible value prior to calling this.
99
--
100
-- Example 1:
101
--
102
-- set_rand(1001)
103
-- s = rnd()
104
-- -- s is 0.2634879318
105
--
106
--
107
-- See Also:
108
-- [[:rand]], [[:set_rand]], [[:rand_range]]
109
11010010
111
atom a,b,r
112
11310010
a = rand(#3FFFFFFF)
11410010
if a = 1 then return 0 end if
11510010
b = rand(#3FFFFFFF)
11610010
if b = 1 then return 0 end if
11710010
if a > b then
1184988
r = b / a
119
else
1205022
r = a / b
121
end if
122
12310010
return r
124
end function
125
126
--**
127
-- Return a random floating point number in the range 0 to less than 1.
128
--
129
-- Parameters:
130
-- None.
131
--
132
-- Returns:
133
-- An **atom**, randomly drawn between 0.0 and a number less than 1.0
134
--
135
-- Comments:
136
-- In order to get reproducible results from this function, you should
137
-- call ##set_rand##() with a reproducible value prior to calling this.
138
--
139
-- Example 1:
140
--
141
-- set_rand(1001)
142
-- s = rnd_1()
143
-- -- s is 0.2634879318
144
--
145
--
146
-- See Also:
147
-- [[:rand]], [[:set_rand]], [[:rand_range]]
148
14910001
150
atom r
151
15210001
while r >= 1.0 with entry do
153
entry
15410001
r = rnd()
15510001
end while
15610001
return r
157
end function
158
159
--**
160
-- Reset the random number generator.
161
--
162
-- Parameters:
163
-- # ##seed## : an object. The generator uses this initialize itself for the next
164
-- random number generated. This can be a single integer or atom,
165
-- or a sequence of two integers, or an empty sequence or any
166
-- other sort of sequence.
167
--
168
-- Comments:
169
-- * Starting from a ##seed##, the values returned by ##rand##() are
170
-- reproducible. This is useful for demos and stress tests based on random
171
-- data. Normally the numbers returned by the ##rand##() function are totally
172
-- unpredictable, and will be different each time you run your program.
173
-- Sometimes however you may wish to repeat the same series of numbers,
174
-- perhaps because you are trying to debug your program, or maybe you want
175
-- the ability to generate the same output (e.g. a random picture) for your
176
-- user upon request.
177
-- * Internally there are actually two seed values.
178
-- ** When ##set_rand()## is called with a single integer or atom, the two
179
-- internal seeds are derived from the parameter.
180
-- ** When ##set_rand()## is called with a sequence of exactly two integers/atoms
181
-- the internal seeds are set to the parameter values.
182
-- ** When ##set_rand()## is called with an empty sequence, the internal seeds are
183
-- set to random values and are unpredictable. This is how to reset the generator.
184
-- ** When ##set_rand()## is called with any other sequence, the internal seeds are
185
-- set based on the length of the sequence and the hashed value of the sequence.
186
-- * Aside from an empty ##seed## parameter, this sets the generator to a known state
187
-- and the random numbers generated after come in a predicable order, though they still
188
-- appear to be random.
189
--
190
-- Example 1:
191
--
192
-- sequence s, t
193
-- s = repeat(0, 3)
194
-- t = s
195
--
196
-- set_rand(12345)
197
-- s[1] = rand(10)
198
-- s[2] = rand(100)
199
-- s[3] = rand(1000)
200
--
201
-- set_rand(12345) -- same value for set_rand()
202
-- t[1] = rand(10) -- same arguments to rand() as before
203
-- t[2] = rand(100)
204
-- t[3] = rand(1000)
205
-- -- at this point s and t will be identical
206
-- set_rand("") -- Reset the generator to an unknown seed.
207
-- t[1] = rand(10) -- Could be anything now, no way to predict it.
208
--
209
--
210
-- See Also:
211
-- [[:rand]]
212
21310
214
-- A given value of seed will cause the same series of
215
-- random numbers to be generated from the rand() function
21610
machine_proc(M_SET_RAND, seed)
21710
end procedure
218
219
--**
220
-- Simulates the probability of a desired outcome.
221
--
222
-- Parameters:
223
-- # ##my_limit## : an atom. The desired chance of something happening.
224
-- # ##top_limit##: an atom. The maximum chance of something happening. The
225
-- default is 100.
226
--
227
-- Returns:
228
-- an integer. 1 if the desired chance happened otherwise 0.
229
--
230
-- Comments:
231
-- This simulates the chance of something happening. For example, if you
232
-- wnat something to happen with a probablity of 25 times out of 100 times then you code ##chance(25)##
233
-- and if you want something to (most likely) occur 345 times out of 999 times, you code
234
-- ##chance(345, 999)###.
235
--
236
-- Example 1:
237
--
238
-- -- 65% of the days are sunny, so ...
239
-- if chance(65) then
240
-- puts(1, "Today will be a sunny day")
241
-- elsif chance(40) then
242
-- -- And 40% of non-sunny days it will rain.
243
-- puts(1, "It will rain today")
244
-- else
245
-- puts(1, "Today will be a overcast day")
246
-- end if
247
--
248
--
249
-- See Also:
250
-- [[:rnd]], [[:roll]]
25110000
25210000
return (rnd_1() * top_limit) <= my_limit
253
end function
254
255
256
--**
257
-- Simulates the probability of a dice throw.
258
--
259
-- Parameters:
260
-- # ##desired## : an object. One or more desired outcomes.
261
-- # ##sides##: an integer. The number of sides on the dice. Default is 6.
262
--
263
-- Returns:
264
-- an integer. 0 if none of the desired outcomes occured, otherwise
265
-- the face number that was rolled.
266
--
267
-- Comments:
268
-- The minimum number of sides is 2 and there is no maximum.
269
--
270
-- Example 1:
271
--
272
-- res = roll(1, 2) -- Simulate a coin toss.
273
-- res = roll({1,6}) -- Try for a 1 or a 6 from a standard die toss.
274
-- res = roll({1,2,3,4}, 20) -- Looking for any number under 5 from a 20-sided die.
275
--
276
--
277
-- See Also:
278
-- [[:rnd]], [[:chance]]
27910000
280
integer rolled
28110000
if sides < 2 then
2820
return 0
283
end if
28410000
if atom(desired) then
2850
desired = {desired}
286
end if
287
28810000
rolled = find( rand(sides), desired)
28910000
if rolled then
2901507
return desired[rolled]
291
else
2928493
return 0
293
end if
294
end function
295
296
--**
297
-- Selects a random sample sub-set of items from a population set.
298
--
299
-- Parameters:
300
-- # ##full_set## : a sequence. The set of items from which to take a sample.
301
-- # ##sample_size##: an integer. The number of samples to take.
302
-- # ##return_remaining##: an integer. If non-zero, the sub-set not selected is also returned.
303
-- If zero, the default, only the sampled set is returned.
304
--
305
-- Returns:
306
-- a sequence. When ##return_remaining## = 0 then this is the set of samples, otherwise
307
-- it returns a two-element sequence; the first is the samples, and the second
308
-- is the remainder of the population (in the original order).
309
--
310
-- Comments:
311
-- * If ##sample_size## is less than 1, an empty set is returned.
312
-- * If ##sample_size## is greater than or equal to the population count,
313
-- the entire population set is returned, but in a random order.
314
--
315
-- Example 1:
316
--
317
-- set_rand("example")
318
-- printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 1)}) --> "t"
319
-- printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 5)}) --> "flukq"
320
-- printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", -1)}) --> ""
321
-- printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 26)}) --> "kghrsxmjoeubaywlzftcpivqnd"
322
-- printf(1, "%s\n", { sample("abcdefghijklmnopqrstuvwxyz", 25)}) --> "omntrqsbjguaikzywvxflpedc"
323
--
324
--
325
-- Example 2:
326
--
327
-- -- Deal 4 hands of 5 cards from a standard deck of cards.
328
-- sequence theDeck
329
-- sequence hands = {}
330
-- sequence rt
331
-- function new_deck()
332
-- sequence nd = {}
333
-- for i = 1 to 4 do
334
-- for j = 1 to 13 do
335
-- nd = append(nd, {i,j})
336
-- end for
337
-- end for
338
-- return nd
339
-- end function
340
-- theDeck = new_deck()
341
-- for i = 1 to 4 do
342
-- rt = sample(theDeck, 5, 1)
343
-- theDeck = rt[2]
344
-- hands = append(hands, rt[1])
345
-- end for
346
--
347
--
3480
349
sequence lResult
350
integer lIdx
351
integer lChoice
352
integer lLen
353
3540
if sample_size < 1 then
3550
if return_remaining then
3560
return {{}, full_set}
357
else
3580
return {}
359
end if
360
end if
361
3620
if sample_size >= length(full_set) then
3630
sample_size = length(full_set)
364
end if
365
3660
lResult = repeat(0, sample_size)
3670
lIdx = 0
3680
lLen = length(full_set)
3690
while lIdx < sample_size do
3700
lChoice = rand(lLen)
3710
lIdx += 1
3720
lResult[lIdx] = full_set[lChoice]
3730
lLen -= 1
3740
full_set[lChoice .. $-1] = full_set[lChoice+1 .. $]
3750
end while
376
3770
if return_remaining then
3780
return {lResult, full_set[1 .. $ - sample_size]}
379
else
3800
return lResult
381
end if
382
end function