#:g1: closでL-99 (P20 指定した要素を削除)

Posted 2008-05-02 20:54:00 GMT

-(http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html)
なんとなく、「面倒版」ではベクタを基本にして、他は型変換させるように書いてみましたが、色々な型に対応する関数を書くときはやっぱりリストを基本にするんでしょうか。
型変換するにもコストが掛かるだろうし、型ごとに個別に記述するのも面倒だし、落し所の判断が難しいなあ(;´Д`)
ベンチマーク取ったりして判断するのかな?

(remove-at #(1 2 3 4 5 6) 1)
;=> #(2 3 4 5 6)
(remove-at '(1 2 3 4 5 6) 1)
;=> (2 3 4 5 6)
(remove-at "123456" 1)
;=> "23456"

(defgeneric REMOVE-AT (sequence position) (:documentation "P20 (*) Remove the K'th element from a list."))

;; 単純版 (defmethod REMOVE-AT ((sequence sequence) (position integer)) (concatenate (class-of sequence) (subseq sequence 0 (1- position)) (subseq sequence position)))

;; 面倒版 (defmethod REMOVE-AT ((sequence vector) (position integer)) (let ((len (length sequence))) (if (not (<= 1 position len)) (copy-seq sequence) (loop :with res := (if (stringp sequence) (make-string (1- len)) (make-array (1- len))) :and ridx := 0 :for x :across sequence :for idx :from 1 :to len :unless (= position idx) :do (setf (aref res ridx) x) (incf ridx) :finally (return res)))))

(defmethod REMOVE-AT ((sequence sequence) (position integer)) (coerce (remove-at (coerce sequence 'vector) position) (class-of sequence)))

comments powered by Disqus