【发布时间】:2015-12-10 05:29:43
【问题描述】:
作为Eulerian travails 的一部分,我正在尝试使用分解轮对Sieve of Eratosthenes 进行编码。到目前为止我的代码是:
(defun ring (&rest content)
"Returns a circular list containing the elements in content.
The returned list starts with the first element of content."
(setf (cdr (last content)) content))
(defun factorization-wheel (lst)
"Returns a circular list containing a factorization
wheel using the list of prime numbers in lst"
(let ((circumference (apply #'* lst)))
(loop for i from 1 to circumference
unless (some #'(lambda (x) (zerop (mod i x))) lst)
collect i into wheel
finally (return (apply #'ring
(maplist
#'(lambda (x) ; Takes exception to long lists (?!)
(if (cdr x)
(- (cadr x) (car x))
(- circumference (car x) -1)))
wheel))))))
(defun eratosthenes (n &optional (wheel (ring 4 2)))
"Returns primes up to n calculated using
a Sieve of Eratosthenes and a factorization wheel"
(let* ((candidates (loop with s = 1
for i in wheel
collect (setf s (+ i s))
until (> s n))))
(maplist #'(lambda (x)
(if (> (expt (car x) 2) n)
(return-from eratosthenes candidates))
(delete-if
#'(lambda (y) (zerop (mod y (car x))))
(cdr x)))
candidates)))
对于超过 6 个元素的轮子,我得到了以下结果。我真的不明白为什么:
21 > (factorization-wheel '(2 3 5 7 11 13))
(16 2 4 6 2 6 4 2 4 6 6 2 6 4 2 6 4 6 8 4 ...)
21 > (factorization-wheel '(2 3 5 7 11 13 17))
> Error: Too many arguments.
> While executing: FACTORIZATION-WHEEL, in process listener(1).
否则该算法似乎工作正常,并产生具有 6 个或更少元素的轮子的素数。
显然apply 或ring 会在向他们传递长列表时嗤之以鼻。
但是列表不应该算作单个参数吗?我承认我完全糊涂了。任何意见表示赞赏。
【问题讨论】:
-
错过这个算法的要点(和美丽)非常受欢迎。埃拉托色尼筛法基于重复添加;它不使用
mod或任何其他方法测试可分性。 (参见例如this paper。) -
感谢伟大的链接!我的
factorization-wheel也是垃圾,所以我想我会重新开始。
标签: lisp common-lisp apply sieve-of-eratosthenes wheel-factorization