;;; -*- lexical-binding: t -*- ;; ;; this file: ;; https://dataswamp.org/~incal/emacs-init/stats.el (require 'cl-lib) (defun decade () (interactive) (cl-loop with entries = () for d from 190 to 202 do (push (how-many (format "^.\\{14\\}%d[[:digit:]]" d)) entries) finally (message "%s" (nreverse entries)) )) (defun random-distribution (n sum &optional min no-error) "Return a list of N random numbers. \nThe sum of the numbers is SUM. \nEvery number is at least MIN. (default: 0) \nIf NO-ERROR, recompute unsolvable systems with MIN = 0. (default: nil)" (or min (setq min 0)) (let ((min-share (* n min))) (if (< sum min-share) (if no-error (random-distribution n sum) (error "Bogus indata, unsolvable") ) (let ((vals (make-list n min)) (pool (- sum min-share)) ) (cl-loop while (< 0 pool) do (cl-incf (nth (random n) vals)) (cl-decf pool) ) vals) ))) (defalias 'rd #'random-distribution) ;; (apply #'+ (rd 10 100 3)) ; sum is 100, OK ;; (rd 10 100) ; omitted/default min = 0, OK ;; (rd 10 100 10) ; border case, but OK ;; (rd 10 100 20) ; error: Bogus indata, unsolvable ;; (rd 10 100 20 t) ; unsolvable but no-error, recompute for min = 0 ;; ;; 10 example distributions for ;; n = 10, sum = 100, and min = 3, ;; i.e. (rd 10 100 3): ;; ;; (12 8 8 10 7 6 19 9 7 14) ;; ( 8 12 7 12 9 10 9 9 12 12) ;; (14 6 15 11 9 9 6 8 11 11) ;; ( 8 12 7 9 10 9 10 13 10 12) ;; (12 12 15 6 10 8 6 10 14 7) ;; ( 9 7 10 8 11 10 9 10 13 13) ;; ( 7 13 13 10 13 10 5 13 5 11) ;; (13 8 6 9 13 8 11 7 10 15) ;; ( 7 10 5 6 17 14 8 10 14 9) ;; (11 10 8 9 11 10 14 11 8 8) (provide 'stats)