Unexpected list duplication using Sort with shared Lisp

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

This is my first post on this site.

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

I have a function that finds all the correct divisors of 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 (/ xi))) (when (integerp div) (push i divs) (push div divs)))) divs)) 

This feature works great. For example:

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

The problem occurs when I try to sort the resulting list:

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

Ok, that worked fine. But what happens when I call the 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) 

Divisors of previous queries are saved after sorting the resulting list. If I recompile the function, I will not get errors until I sort the resulting list again. I suppose I messed up somewhere in the function definition, but I'm pretty new to Lisp and I can't find the error. Maybe there is a problem with nested (let ...) forms?

Thanks in advance!

+2
lisp common-lisp
source share
2 answers

FAQ.

You have changed the literal data. You need new data. Use the LIST function or function to create a copy.

+9
source share

Rainer is right; if this is not obvious, the code can be fixed with this change:

 (let ((sq (sqrt x)) (divs (list 1))) 
+3
source share

All Articles