2012-04-14 8 views
2

EDIT:解決策は、最初の(let ...)フォームの '(1)を(リスト1)に置き換えることです。これは、リテラルデータを変更しようとしていたためです。助けてくれてありがとう! (私はupvotesを与えるだろうが、明らかにあなたは15の評判が必要です...)予期しないリストの複製をCommon Lispで並べ替える

これはこのサイトの私の最初の投稿です。

私は今日、いくつかのProject Euler問題を解決していたと私は、Common Lispでは(まあ、少なくとも私には)いくつかの予期しないリストのソート振る舞いに出くわした:

私が見つけた機能を持っている数の適切な約数のすべて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)) 

この機能は素晴らしい機能です。

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

まあ、うまく働いた:たとえば:私は結果のリストをソートしようとしたときに

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

問題が発生します。しかし、私が再びdivisを呼ぶとどうなりますか?

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

何ですか?私は別の番号をしようとした場合、私は結果のリストをソートした後、たぶん...以前のクエリから

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

除数は永続的です。関数を再コンパイルすると、結果リストを再度ソートするまでエラーは発生しません。私は関数定義のどこかにぶち壊れていると仮定していますが、私はLispをかなり新しくしており、エラーを見つけることはできません。それはネストされた(let ...)フォームの問題かもしれませんか?

ありがとうございます!

答えて

9

よく聞かれます。

リテラルデータを変更しました。あなたは新しいデータを見直す必要があります。関数LISTまたは関数を使用してコピーを作成します。

+0

ありがとうございます! もっと明示できますか?私は理解できません。 –

+3

@Lisper ''(1)'はリストリテラルです。リテラルに対する破壊的操作の結果は定義されておらず、 'sort'は破壊的な操作です。 'list'関数を使ってリストを構築します。 –

3

ライナーが正しいです。明らかでない場合は、コードをこの変更で修正することができます。

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

Rainer、not Ranier –

+0

Yikes - 申し訳ありません、Rainer! –

関連する問題