Unexpected List Duplication using Sort with Common Lisp

淺唱寂寞╮ 提交于 2020-01-04 09:19:26

问题


EDIT: The solution is to replace the '(1) with (list 1) in the first (let...) form. This is because I was trying to modify literal data. Thanks for the help! (I would give upvotes, but apparently you need 15 reputation...)

This is my first post on this site.

I was solving some Project Euler problems today and I came across some unexpected list sorting behavior (well, at least to me) in Common Lisp:

I have a function that finds all of the proper divisors of a number x:

(defun divisors (x)
    "Finds all of the proper divisors of x."
    (let ((sq (sqrt x)) (divs '(1)))
        (when (integerp sq) (push sq divs))
        (loop for i from 2 to (1- (floor sq)) do
        (let ((div (/ x i)))
            (when (integerp div)
                (push i divs)
                (push div divs))))
    divs))

This function works great. For example:

(divisors 100)
==> (20 5 25 4 50 2 10 1)

The problem arises whenever I try to sort the resulting list:

(sort (divisors 100) #'<)
==> (1 2 4 5 10 20 25 50)

Well, that worked fine. But what happens when I call divisors again?

(divisors 100)
==> (20 5 25 4 50 2 10 1 2 4 5 10 20 25 50)

What? Maybe if I try a different number...

(divisors 33)
==> (11 3 1 2 4 5 10 20 25 50)

The divisors from previous queries are persistent after I sort the resulting list. If I recompile the function, I get no errors until I sort the resulting list again. I am assuming I have messed up somewhere in the function definition, but I am pretty new to Lisp and I cannot find the error. Could it be a problem with the nested (let...) forms?

Thanks in advance!


回答1:


Frequently asked.

You've modified literal data. You need to cons up new data. Use the function LIST or the function to make a copy.




回答2:


Rainer is right; if it isn't obvious, the code can be fixed with this change:

(let ((sq (sqrt x)) (divs (list 1)))


来源:https://stackoverflow.com/questions/10155744/unexpected-list-duplication-using-sort-with-common-lisp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!