P23: リストからランダムにN個の要素を取り出す

multiple-value-bindは使ってみたかっただけです。はい。

;; P23
(defun nth-and-remove (n list &optional (acc nil))
  (if (or (<= n 0) (null list))
      (values (car list) (append (nreverse acc) (cdr list)))
    (nth-and-remove (1- n) (cdr list) (cons (car list) acc))))

(defun rnd-select (list num)
  (if (or (<= num 0) (null list))
      nil
    (multiple-value-bind (elem rest)
	(nth-and-remove (random (length list)) list)
      (cons elem (rnd-select rest (1- num))))))

(nth-and-remove 8 '(a b c d e f g h i j k l m n))
;; => I, (A B C D E F G H J K L M N)

(rnd-select '(a b c d e f g h) 3)
;; => (C G F)