Почему мой цикл Common Lisp работает только с тривиальным кодом? - PullRequest
3 голосов
/ 06 ноября 2011

У меня есть немного кода:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return x) 
           (if (not (mod x i))
               (return (append i (divisor (/ x i))))))))

, который должен вернуть список простых факторов x.Тем не менее, код просто возвращает х.

Функция defun оценивается без ошибок.Я пытался отследить каждую функцию в defun, и ни одна из них никогда не оценивалась.Цикл - это макрос, поэтому я не могу отследить его, но если я очищу внутреннюю часть цикла и заменим на

(format t "~d " i)

, он будет считать от 2 до x, как я и ожидал.

Я предполагаю, что сделал что-то не так, но не могу понять.

Ответы [ 3 ]

6 голосов
/ 06 ноября 2011

Одна проблема заключается в том, что вы используете (not (mod x i)), чтобы определить, равно ли значение mod 0, что неверно.

Другая проблема заключается в том, что вы добавляете атомы в списки, и я не думаю, что это именно то, что вы хотите сделать.

Вот исправленная версия, которая, кажется, работает:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return (list x))
           (if (= (mod x i) 0)
               (return (append (list i) (divisor (/ x i))))))))
2 голосов
/ 06 ноября 2011

В вашем цикле я в итоге достиг х. Итак, вы возвращаете x, отбрасывая любое другое возвращаемое значение, которое вы могли бы вернуть из подрекурсий.

Я думаю, вы неправильно соединили цикл с рекурсией. Вам нужно сделать только один из них.

1 голос
/ 07 ноября 2011
    (defun divisor (x) 
      (loop for i from 2 to x when (eql 0 (mod x i)) collect i))
...