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 ...)フォームの問題かもしれませんか?
ありがとうございます!
ありがとうございます! もっと明示できますか?私は理解できません。 –
@Lisper ''(1)'はリストリテラルです。リテラルに対する破壊的操作の結果は定義されておらず、 'sort'は破壊的な操作です。 'list'関数を使ってリストを構築します。 –