问题
How do I generate random in Scheme? Is there a special form or would I have to create a procedure? And if so, how do I do that? (I'm trying to create a procedure called random-choice that inputs two strategies and returns one at random.)
回答1:
The procedure is called, surprisingly enough, random - although the exact syntax might be different depending on the Scheme interpreter in use (read the documentation!), but the general idea is as follows:
(random)
=> 0.9113789707345018
For returning one of two possible values, this will do the trick in Racket:
(define (random-choice a b)
(if (zero? (random 2)) a b))
Notice that the 2 argument passed to random forces it to randomly return one of two possible values: 0 or 1. So if (random 2) evaluates to 0 then a is returned, otherwise b is returned.
(random-choice 4 2)
=> 4
(random-choice 4 2)
=> 2
回答2:
Standard Scheme does not provide a random number generator, and although most Scheme implementations provide one, they tend to differ in their details. If you want to write a portable Scheme program, it's easy to build your own random number generator; here's a method due to Knuth:
(define random
(let ((a 69069) (c 1) (m (expt 2 32)) (seed 19380110))
(lambda new-seed
(if (pair? new-seed)
(set! seed (car new-seed))
(set! seed (modulo (+ (* seed a) c) m)))
(/ seed m))))
Calling (random) returns a random fraction between 0 (inclusive) and 1 (exclusive). The random fractions cycle with period m. Calling (random seed) resets the seed of the random number generator, so that two random sequences starting from the same seed will be identical; dates in the form YYYYMMDD make good seeds (that's Knuth's birthday above). If you want to flip a coin, say: (if (< (random) 1/2) 'heads 'tails).
Sometimes you want a random integer over a range. The randint function shown below returns a random integer on the range lo (inclusive) to hi (exclusive); lo defaults to 0:
(define (randint . args)
(cond ((= (length args) 1)
(floor (* (random) (car args))))
((= (length args) 2)
(+ (car args) (floor (* (random) (- (cadr args) (car args))))))
(else (error 'randint "usage: (randint [lo] hi)"))))
Random numbers such as these are good enough for simple simulations, but beware they are not suitable for cryptographic applications. If you are interested, I have several random number generators, including some suitable for cryptographic applications, at my blog.
回答3:
Since your other question was about implementing a spaceship game in DrRacket, I will assume, that by Scheme you mean one of the teaching languages in DrRacket.
The way to find information on available functions in DrRacket is simple. Write, say, random in the interaction window. Place the cursor on top, and then press F1.
The documentation on the random in htdp-languages is here:
http://docs.racket-lang.org/htdp-langs/beginner.html?q=random#(def.htdp-beginner.((lib._lang/htdp-beginner..rkt)._random))
One way to return a random value:
(list-ref (list "one" "two") (random 2))
Here (random 2) will return 0 or 1. The list-ref will thus return either the entry with index 0 or index 1 of the list.
The advantage of using the above approach is that it is easy to extend to more values than two.
来源:https://stackoverflow.com/questions/14674165/scheme-generate-random