(defun weighted-pseudorandom (fn)
(do ((r 0 (random 1.0))
(test 1 (random 1.0)))
((< test (apply fn (list r))) r)))
(defun linear-prob-distribution (r)
r)
(defun quadratic-prob-distribution (r)
(expt r 2))
(defun check-distribution (fn)
(let ((randoms
(sort
(loop
for i
from 0 below 100000
collecting (weighted-pseudorandom fn))
#'<))
(scale (loop for i from 0 below 1 by 1/100 collecting i))
(result (make-hash-table))
(ptr -1/100))
(dolist (x randoms)
(if (> x ptr)
(progn
(princ (float ptr))
(princ ",")
(princ (gethash ptr result))
(fresh-line)
(setf ptr (+ ptr 1/100))
(setf (gethash ptr result) 0))
(incf (gethash ptr result))))))
(print "Linearly weighted generation of a 100,000 numbers")
(fresh-line)
(check-distribution #'linear-prob-distribution)
(print "Quadratic")
(fresh-line)
(check-distribution #'quadratic-prob-distribution)