編集: 解決策は、最初の (let...) 形式で '(1) を (list 1) に置き換えることです。これは、リテラル データを変更しようとしていたためです。助けてくれてありがとう!(私は賛成票を投じますが、明らかに15の評判が必要です...)
これは、このサイトでの私の最初の投稿です。
今日、いくつかの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))
この機能はうまく機能します。例えば:
(divisors 100)
==> (20 5 25 4 50 2 10 1)
結果のリストをソートしようとするたびに問題が発生します。
(sort (divisors 100) #'<)
==> (1 2 4 5 10 20 25 50)
まあ、それはうまくいきました。しかし、再び除数を呼び出すとどうなるでしょうか?
(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...) フォームの問題でしょうか?
前もって感謝します!