在Common Lisp中打印前N个素数

bin*_*yjc 0 lisp printing primes clisp numbers

我正在制作一个Common Lisp函数来打印前N个素数.到目前为止,我已设法编写此代码:

;globals 
(setf isprime 1) ;if 1 then its a prime, 0 if not.
(setf from 1)    ;start from 1
(setf count 0)   ;should act as counter to check if we have already 
                 ;    N primes printed

;function so far.
(defun prime-numbers (to)
  (if (> count to) nil(progn
      (is-prime from from)
      (if (= isprime 1) (print from)(setf count (+ count 1)))
      (setf isprime 1)
      (setf from (+ from 1))
      (prime-numbers to)))
  (if (>= count to)(setf count 0) (setf from 1)))  

;code to check if a number is prime    
(defun is-prime(num val)
  (if (< num 3) nil 
    (progn
      (if (= (mod val (- num 1)) 0) (setf isprime 0))
      (is-prime (- num 1) val))))
Run Code Online (Sandbox Code Playgroud)

我的问题是,它没有正确打印N primes.如果我打电话>(prime-numbers 10),结果是: 1 2 3 5 7 11 13 17 19 1,即它只正确地打印了9个素数.

但如果我打电话>(prime-numbers 2) 给结果是:1 2 3 5 7 1

我在这做错了什么?这是我第一次在LISP中编码.

更新:

  (defparameter from 1)
  (defparameter count 0)

  (defun prime-numbers (to)
     (if (> count to)nil
         (progn
            (when (is-prime from) 
                (print from)
                (setf count (+ count 1)))
            (setf from (+ from 1))
            (prime-numbers to)))
     (when (>= count to)
         (setf count 0) 
         (setf from 1)))  

  (defun is-prime (n)
    (cond ((= 2 n) t)
     ((= 3 n) t)
     ((evenp n) nil)
     (t 
       (loop for i from 3 to (isqrt n) by 2
             never (zerop (mod n i))))))
Run Code Online (Sandbox Code Playgroud)

工作良好.但最后输出一个NIL.

Vat*_*ine 6

首先,根本不需要在这里使用全局变量.

使用true/false返回值.这将允许您的is-prime功能类似于:

(defun is-prime (n)
  (cond ((= 2 n) t) ;; Hard-code "2 is a prime"
        ((= 3 n) t) ;; Hard-code "3 is a prime"
        ((evenp n) nil) ;; If we're looking at an even now, it's not a prime
        (t ;; If it is divisible by an odd number below its square root, it's not prime
           (loop for i from 3 to (isqrt n) by 2
                 never (zerop (mod n i))))))
Run Code Online (Sandbox Code Playgroud)

这样,该功能不依赖于任何外部状态,并且没有任何东西可以混淆任何东西.

其次,1你看到的最后一个(可能)是函数的返回值.

要检查一下,请尝试:(progn(prime-number 10)nil)

第三,重写你的prime-numbers函数不使用全局变量.

第四,永远不要用setf或创建全局变量setq,使用defvar或者defparameter.它也是(大多数,但有些不同意)*earmuffs*在你的全局(真正的,"特殊")变量上使用的好风格.