;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This file is part of "NOVA": NOVA = search + COCOMO tools ; Copyright, 2008, Tim Menzies tim@menzies.us ; ; NOVA is free software: you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation, either version 3 of the License, or ; (at your option) any later version. ; ; NOVA is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; You should have received a copy of the GNU General Public License ; a long with NOVA. If not, see . ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (in-package :wvu-lib.guess) ;;;; ;;;; GUESS ;;;; (defgeneric guess (guessable-object) (:documentation "Guess a value")) ;;;; ;;;; GUESSING HELPER FUNCTIONS ;;;; ;;; guessing numbers (defun ?quantity (min max) "Returns a random number between min and max." (+ min (my-random (- max min)))) ;;; guessing list items (defun ?elt (l) "Returns a random item from a list." (when l (elt l (floor (my-random (length l)))))) (defun ?elts (l n) "Returns up to n random items from a list." (when l (if (zerop n) nil (let ((any (?elt l))) (cons any (?elts (remove any l) (- n 1))))))) (defun ?any (l &key (control 0.8) (power 1)) "Returns any number of items from a list, favoring smaller selections." (let* ((factor (expt control power)) (r (?quantity 0 1)) (some (round (log r factor))) (enough (min (length l) (max 1 some)))) (?elts l enough))) (defun ?lots (l) "Returns lots of items from a list." (?any l :power 1)) (defun ?some (l) "Returns some items from a list." (?any l :power 2)) (defun ?few (l) "Returns a few items from a list." (?any l :power 3)) ;;;; ;;;; BASIC GUESSING HELPER TYPES ;;;; ;;; num (defstruct num min max (discretize-bins 10)) (defun discretize (num &key (min-max nil min-max-p) (coerce-type nil coerce-p)) "descretize a num using either descretize-bins." (let ((cmin (if min-max-p (first min-max) (num-min num))) (cmax (if min-max-p (second min-max) (num-max num)))) (cond ((not (and cmin cmax)) ;this handles the case when either min or max is null (or min-max is a single number) (list (or cmin cmax))) ((= cmin cmax) (list cmin)) (t (with-slots (discretize-bins) num (let ((width (/ (- cmax cmin) (1- discretize-bins))) dvalues) (dotimes (i discretize-bins (nreverse dvalues)) (let ((dvalue (min cmax (+ cmin (* i width))))) (push (if coerce-p (coerce dvalue coerce-type) dvalue) dvalues))))))))) (defmethod guess ((num num)) (?quantity (num-min num) (num-max num))) ;;; bag (defstruct bag range) (defmethod guess ((bag bag)) (?elt (bag-range bag)))