#-(and) "

P21 (*) Insert an element at a given position into a list.
    Example:
    * (insert-at 'alfa '(a b c d) 2)
    (A ALFA B C D)
"


;; Recursive solution, sharing the tail:

(defun insert-at (item list index)
  (cond
    ((< index 1) (error "Index too small ~A" index))
    ((= index 1) (cons item list))
    ((endp list) (error "Index too big"))
    (t (cons (first list) (insert-at item (rest list) (1- index))))))



;; Functional solution, using the split function of p17.

(defun insert-at (item list index)
  (destructuring-bind (left right) (split list (1- index))
    (append left (list item) right)))



;; Smartass solution, using Common Lisp, sharing the tail:

(defun insert-at (item list index)
  (append (subseq list 0 (1- index))
          (list item)
          (nthcdr (1- index) list)))


;; Smartass solution, using Common Lisp, copying the whole result:

(defun insert-at (item list index)
  (concatenate 'list
    (subseq list 0 (1- index))
    (list item)
    (nthcdr (1- index) list)))


;; Smartass solution, using Common Lisp, modifying the original list!

(defun insert-at (item list index)
  (cond
    ((< index 1) (error "Index too small ~A" index))
    ((= index 1) (cons item list))
    (t (push item (cdr (nthcdr (- index 2) list)))
       list)))

;; (let ((list (list 'a 'b 'c 'd)))
;;   (values list
;;           (insert-at 'alfa list 2)))
;; --> (A ALFA B C D)
;;     (A ALFA B C D)
;;
;; (let ((list (list 'a 'b 'c 'd)))
;;   (values list
;;           (insert-at 'alfa list 1)))
;; --> (A B C D)
;;     (ALFA A B C D)

;;;; THE END ;;;;
ViewGit