一般的なLISPに関する質問
-
27-09-2019 - |
質問
私はここで小さな問題に夢中になっています、私はエラーを受け続けているので、なぜコードがリストの範囲を変更することになっているのかを理解できないようです。 (1 2 3 4)
そして、私たちは11〜14で範囲を変更したいと考えています (11 12 13 14)
問題は、最後に呼ばれる関数です scale-list
次のように言ってエラーが返されます
デバッガーが入力されました - リスプエラー:(間違ったタイプのargument number-or-marker-p nil)
誰かが手がかりを持っていますか? Aquamacsを事前に編集者として使用しています
;;finds minimum in a list
(defun minimum (list)
(car (sort list #'<)))
;;finds maximum in a list
(defun maximum (list)
(car (sort list #'>)))
;;calculates the range of a list
(defun range (list)
(- (maximum list) (minimum list)))
;;scales one value to another range
(defun scale-value (list low high n)
(+ (/ (* (- (nth (- n 1) list)
(minimum list))
(- high low))
(range list))
low))
;;is supposed to scale the whole list to another range
(defun scale-list (list low high n)
(unless (= n 0)
(cons (scale-value list low high n)
(scale-list list low high (- n 1)))))
(scale-list '(1 2 3 4) 21 24 4)
解決
最大値と最小値の定義を改善する必要があります。ソートは破壊的です。また、 '(1 2 3 4)のような文字通りの定数でソートを呼び出すことも間違っています - 繰り返しますが、ソートは破壊的です。
より良い定義:
(defun minimum (list)
(reduce #'min list))
(defun maximum (list)
(reduce #'max list))
範囲のより効率的な定義:
(defun range (list)
(loop for e in list
maximize e into max
minimize e into min
finally (return (- max min))))
スケールリストとスケール値もLISPのようではありません。再帰関数でこのようにnthを呼び出すと、何かが間違っています。インデックスではなく、リストを越えて再発する必要があります。スケール値の呼び出し範囲と各コールの最小。なんで?
このバリアントを確認してください:
;;scales one value to another range
(defun scale-value (item low high min range)
(+ (/ (* (- item min)
(- high low))
range)
low))
;;is supposed to scale the whole list to another range
(defun scale-list (list low high)
(let ((min (minimum list))
(range (range list)))
(labels ((scale-list-aux (list)
(when list
(cons (scale-value (first list) low high min range)
(scale-list-aux (rest list))))))
(scale-list-aux list))))
(scale-list '(1 2 3 4) 21 24)
何を改善できますか?たとえば、再帰を取り除き、MapCarに置き換えます。
他のヒント
何かがうまくいかなかったのでコードを投稿します...
;;finds minimum in a list
(defun minimum(list)
(car (sort list #'<)))
;;finds maximum in a list
(defun maximum(list)
(car (sort list #'>)))
;;calculates the range of a list
(defun range(list)
(- (maximum list) (minimum list)))
;;scales one value to another range
(defun scale-value(list low high n)
(+ (/ (* (- (nth (- n 1) list) (minimum list)) (- high low)) (range list)) low))
;;is supposed to scale the whole list to another range
(defun scale-list(list low high n)
(unless (= n 0)
(cons (scale-value list low high n) (scale-list list low high (- n 1)))))
(scale-list '(1 2 3 4) 21 24 4)
実際のスタックトレースは次のようなものです。
-(nil 0.1)
(* (- (nth ... list) (minimum list)) (- high low))
(/ (* (- ... ...) (- high low)) (range list))
(+ (/ (* ... ...) (range list)) low)
scale-value((0.1) 20 30 3)
私はあなたが間違ったn番目の要素を決定すると思います、そして、これはnilを返します。
所属していません StackOverflow