Lisp:创建随机奇数

时间:2017-11-27 21:28:23

标签: common-lisp

我有这个:

(let ((num 1))
  (mapcar (lambda (x)
            (cons x (if (evenp (setf num (random 299)))
                        (1+ num)
                        (num))))
          '(a b c d e f)))

应该产生这样的东西:

 ((A . 37) (B . 283) (C . 232) (D . 251) (E . 273) (F . 170) 

只有奇数。是的,很奇怪的样子。是否有random-state的内容可以提供帮助?或者隐藏的系统变量"保留最初的random计算?这是我尝试的全局功能:

(defun random-odd ()
  (let ((num 0))
    (if (evenp (setf num (random 299)))
        (1+ num)
      (num))))

也不行。我在这里缺少什么?

2 个答案:

答案 0 :(得分:5)

除了样式并使用random-odd之外,您的num几乎没有问题 功能位置(记住,Lisp parentheses are meaningful):

(defun random-odd ()
  (let ((num (random 299)))
    (if (evenp num)
        (1+ num)
        num)))

这个函数的细微问题是得到299的概率从1到297得到任何其他奇数的概率。

这是因为(random 299)返回0到298之间的数字,概率为1/299。因此,random-odd将返回17,概率为2/299(如果random返回17或16),但它将返回299,概率为1/299(如果random返回298)。

因此我建议

(defun random-odd (even-limit)
  "Return an odd random number from 0 to EVEN-LIMIT, exclusive."
  (assert (evenp even-limit) (even-limit)
          "~S: ~S must be even" 'random-odd 'even-limit)
  (let ((num (random even-limit)))
    (if (evenp num)
        (1+ num)
        num)))

完全等效的方法是

(defun random-odd (half-limit)
  "Return a random odd number from 1 to half-limit*2-1 inclusive."
  (1+ (ash (random half-limit) 1)))

答案 1 :(得分:1)

{{1}}