;; random number generator from ;; http://www.math.grin.edu/~stone/events/scheme-workshop/random.html, ;; based on proposal by Stephen K. Park et al. (define random-maker (let* ((multiplier 48271) (modulus 2147483647) (apply-congruence (lambda (current-seed) (let ((candidate (modulo (* current-seed multiplier) modulus))) (if (zero? candidate) modulus candidate)))) (coerce (lambda (proposed-seed) (if (integer? proposed-seed) (- modulus (modulo proposed-seed modulus)) 19860617)))) ;; an arbitrarily chosen birthday (lambda (initial-seed) (let ((seed (coerce initial-seed))) (lambda args (cond ((null? args) (set! seed (apply-congruence seed)) (/ (- modulus seed) modulus)) ((null? (cdr args)) (let* ((proposed-top (ceiling (abs (car args)))) (exact-top (if (inexact? proposed-top) (inexact->exact proposed-top) proposed-top)) (top (if (zero? exact-top) 1 exact-top))) (set! seed (apply-congruence seed)) (inexact->exact (floor (* top (/ seed modulus)))))) ((eq? (cadr args) 'reset) (set! seed (coerce (car args)))) (else (display "random: unrecognized message") (newline)))))))) (define random (random-maker 19781116)) ;; another arbitrarily chosen birthday (define (bb n) (bbfill n n (make-vector n 0) 0)) (define r 0) (define (bbfill total-balls balls-left bins max-balls) (cond ((= balls-left 0) max-balls) (else (set! r (random total-balls)) (let ((balls-in-bin (1+ (vector-ref bins r)))) (vector-set! bins r balls-in-bin) (if (> balls-in-bin max-balls) (bbfill total-balls (- balls-left 1) bins balls-in-bin) (bbfill total-balls (- balls-left 1) bins max-balls))))))