From d7655ae27679b5da4e78bc44636113dd36afd179 Mon Sep 17 00:00:00 2001 From: Avril Date: Thu, 23 Apr 2020 07:55:52 +0100 Subject: [PATCH] more stuff --- cl-rng.lisp | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/cl-rng.lisp b/cl-rng.lisp index ca55ec7..f0708fe 100644 --- a/cl-rng.lisp +++ b/cl-rng.lisp @@ -2,15 +2,15 @@ (in-package :cl-rng) -(defparameter *default-randomness-provider* #'urandom) +(defparameter *default-randomness-provider* #'urandom + "The default randomness provider used by cl-rng functions") (defun chance (fraction &key (provider *default-randomness-provider*)) + "Returns T if chance fraction is met" (< (funcall provider) fraction)) -(export '*default-randomness-provider*) -(export 'chance) - (defun weighted (weights &key (default nil) (provider *default-randomness-provider*)) + "Interpret weights as an alist where the key is the item and the value is the chance. If no chances are met, return default" (let ((previous 0) (result (funcall provider)) (rval default)) @@ -27,6 +27,7 @@ (export 'weighted) (defun shuffle! (sequence &key (provider *default-randomness-provider*)) + "In-place shuffle a sequence" (if (listp sequence) (loop for i from (1- (length sequence)) above 0 do (rotatef (nth i sequence) @@ -36,5 +37,27 @@ (aref sequence (funcall provider :limit i :transform #'floor))))) sequence) -(export 'shuffle!) +(defun within (sequence &key (provider *default-randomness-provider*)) + "A random value withing a sequence. Can be setf()'d" + (if (listp sequence) + (nth (funcall provider :limit (1- (length sequence)) :transform 'round) sequence) + (aref sequence (funcall provider :limit (1- (length sequence)) :transform 'round)))) + +(defun within-set (sequence value) + (let ((index (funcall *default-randomness-provider* :limit (1- (length sequence)) :transform 'round))) + (if (listp sequence) + (setf (nth index sequence) value) + (setf (aref sequence index) value)))) +(defun range (start end &key (integral nil) (provider *default-randomness-provider*)) + "A random number in a range" + (+ start (funcall provider :limit (- end start) :transform (if integral 'round 'identity)))) + +;; Exports + +(export '*default-randomness-provider*) +(defsetf within within-set) +(export 'range) +(export 'within) +(export 'shuffle!) +(export 'chance)