-
Notifications
You must be signed in to change notification settings - Fork 0
/
random.zp
89 lines (78 loc) · 2.98 KB
/
random.zp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
;; This code is taken from:
;; http://stackoverflow.com/questions/14674165/scheme-generate-random
;; It is not to be used in cryptography or related fields.
(define random
(let ((a 69069.0) (c 1) (m (expt 2 32)) (seed 19380110))
(lambda new-seed
"generate a new random number or reseeds the random number generator if
an argument <par>new-seed</par> is provided.
params:
- new-seed: seed to reseed the RNG with (optional)
complexity: O(1)
returns: a random floating point number between 0 and 1"
(begin
(if (and (not (null? new-seed)) (number? (car new-seed)))
(set! seed (car new-seed))
(set! seed (modulo (+ (* seed a) c) m)))
(/. seed m)))))
(define randint
(let ((precomp (pow 2 1023)))
(lambda (lo . hi)
"generate a random integer between the given range (the lower range is optional).
The upper range is exclusive, the lower range inclusive.
Example:
<zepto>
(randint 10) ; generate a random number between 0 and 10
(randint 1 5) ; generate a random number between 1 and 5
</zepto>
params:
- lo: the lower range (optional)
- hi: the upper range
complexity: O(1)
returns: a random number in the range"
(cond ((null? hi) (randint 0 lo))
((= (length hi) 1)
(+ lo (/ (* (floor (* (random) precomp)) (- (car hi) lo)) precomp)))
(else (error "randint" "usage: (randint [lo] hi)"))))))
(define (random-list n lo . hi)
"generate a list of random integers (of length <par>n</par>)
between the given args (the lower range is optional).
params:
- n: the length of the list
- lo: the lower range (optional)
- hi: the upper range
complexity: O(n)
returns: a list of random integers"
(if (< n 1)
'()
(if (truthy? hi)
(++ (list (randint lo (car hi))) (random-list (- n 1) lo (car hi)))
(++ (list (randint lo)) (random-list (- n 1) lo)))))
; This has been taken from https://github.com/ashinn/chibi-scheme/blob/23ac772e3ac347d01647952621fbc83b4293448b/lib/chibi/math/prime.scm
(define (random-prime lo hi)
"Returns a random prime between lo (inclusive) and hi (exclusive).
params:
- lo: the lower range
- hi: the upper range
complexity: random
returns: a random prime"
(if (> lo hi)
(error "random-prime" "bad range: " lo hi))
(let* ((n (bitwise-or 1 (randint lo hi)))
(x (math:prime-above n hi)))
(if (truthy? x)
x
(math:prime-above lo n))))
(define (random-prime-distinct-from lo hi p)
"Variant of <fun>random-prime</fun> which ensures the result is
distinct from <par>p</par>.
params:
- lo: the lower range
- hi: the upper range
- p: the prime that the random prime should be distinct from
complexity: random
returns: a random prime distinct from <par>p</par>"
(let ((q (random-prime lo hi)))
(if (= q p)
(random-prime-distinct-from lo hi p)
q)))