fork download
  1. (defclass dice ()
  2. ((prob-dist :initarg :prob-dist)
  3. threshold))
  4.  
  5. (defmethod initialize-instance :after ((dice dice) &rest initargs)
  6. (with-slots ((prob-dist prob-dist) (threshold threshold)) dice
  7. (setf threshold
  8. (nreverse (let ((sum (apply #'+ prob-dist)))
  9. (reduce (lambda (a b) (cons (+ (car a) (/ b sum)) a))
  10. prob-dist
  11. :initial-value (list 0)))))))
  12.  
  13. (defmethod roll ((dice dice))
  14. (position (random 1.0) (slot-value dice 'threshold)
  15. :test #'<=))
  16.  
  17. (defun count-dice (prob-dist)
  18. (loop with dice = (make-instance 'dice :prob-dist prob-dist)
  19. with count = (make-array (length prob-dist) :initial-element 0)
  20. repeat 1e5
  21. do (incf (elt count (1- (roll dice))))
  22. finally (loop for c across count
  23. for i upfrom 1
  24. do (format t "~a: ~a~%" i c))))
  25.  
  26. (count-dice '(1 2 1 2 1 2))
  27. (count-dice (loop for i from 1 to 4 collect (sqrt i)))
Success #stdin #stdout 4.83s 10824KB
stdin
Standard input is empty
stdout
1: 11192
2: 22195
3: 11241
4: 22080
5: 11048
6: 22244
1: 16247
2: 23070
3: 28206
4: 32477