; minimum standard random number generator
(define (logand a b)
(if (or (zero? a) (zero? b)) 0
(+ (* (logand (floor (/ a 2)) (floor (/ b 2))) 2)
(if (or (even? a) (even? b)) 0 1))))
(define (ash int cnt)
(if (negative? cnt)
(let ((n (expt 2 (- cnt))))
(if (negative? int)
(+ -1 (quotient (+ 1 int) n))
(quotient int n)))
(* (expt 2 cnt) int)))
(define seed 1)
(define (minstd0) (set! seed (modulo (* 16807 seed) 2147483647)) seed)
(define minstd1
(let ((a 16807) (m 2147483647) (seed (current-seconds)))
(lambda args (if (pair? args) (set! seed (modulo (car args) m)))
(set! seed (modulo (* a seed) m)) (/ seed m))))
(define minstd2
(let ((a 16807) (m 2147483647) (q 127773) (r 2836)
(seed (current-seconds)))
(lambda args (if (pair? args) (set! seed (modulo (car args) m)))
(let* ((lo (modulo seed q)) (hi (quotient seed q))
(test (- (* a lo) (* r hi))))
(set! seed (if (positive? test) test (+ test m)))
(/ seed m)))))
(define minstd3
(let ((a 16807) (m 2147483647) (seed (current-seconds)))
(lambda args (if (pair? args) (set! seed (modulo (car args) m)))
(let* ((lo (* a (logand seed #xFFFF)))
(hi (* a (ash seed -16)))
(lo (+ lo (ash (logand hi #x7FFF) 16)))
(lo (+ lo (ash hi -15)))
(lo (if (>= lo #x7FFFFFFF) (- lo #x7FFFFFFF) lo)))
(set! seed lo) (/ seed m)))))
(display (minstd0)) (newline)
(display (do ((n 1 (+ n 1))) ((= 9999 n) (minstd0)) (minstd0))) (newline)
(display (minstd1 1)) (newline)
(display (do ((n 1 (+ n 1))) ((= 9999 n) (minstd1)) (minstd1))) (newline)
(display (minstd2 1)) (newline)
(display (do ((n 1 (+ n 1))) ((= 9999 n) (minstd2)) (minstd2))) (newline)
(display (minstd3 1)) (newline)
(display (do ((n 1 (+ n 1))) ((= 9999 n) (minstd3)) (minstd3))) (newline)