Yet Another Common Lisp Problems #7 subseq

●問題7

リスト xs の n 番目から m - 1 番目までの要素を部分リストとして取り出す関数 subseq xs n m を定義してください。なお、リストの要素は 0 から数え始めるものとします。Common Lisp には同等の機能を持つ関数 subseq がありますので、ここでは関数名を my-subseq としました。

> (my-subseq '(a b c d e) 2 4)
(c d)
> (my-subseq '(a b c d e) 0 5)
(a b c d e)
> (my-subseq '(a b c d e) 0 0)
()

解答

ホームページ移転のお知らせ - Yahoo!ジオシティーズ
;; do で
(defun my-subseq (ls start end)
  (do ((i start (1+ i))
       (acc))
      ((>= i end) (nreverse acc))
    (push (nth i ls) acc)))

;; 再帰で
(defun my-subseq (ls start end)
  (cond ((<= end 0)   nil)
        ((<= start 0) (cons (car ls)
                            (my-subseq (cdr ls) (1- start) (1- end))))
        (t (my-subseq (nthcdr start ls) 0 (- end start)))))
=> my-subseq

;; 末尾再帰で
(defun my-subseq (ls start end &optional acc)
  (cond ((<= end 0)   (nreverse acc))
        ((<= start 0) (my-subseq (cdr ls) (1- start) (1- end) (cons (car ls) acc)))
        (t (my-subseq (nthcdr start ls) 0 (- end start)))))
=> my-subseq

答え合わせ

●解答7

;リスト : 部分リストを取り出す

(defun my-subseq (ls s e)
  (take (drop ls s) (- e s)))

my-subseq は drop と take を使うと簡単です。drop で ls から s 個の要素を取り除き、そのリストから e - s 個の要素を take で取り出すだけです。

解答7

存在を忘れてた。。。