P14-P21: 細かい問題
だいたい同様の手順で解ける細かい問題。
pushして最後にreverse。
;; P14 (defun dupli (list) (let ((acc '())) (dolist (elm list) (dotimes (i 2) (push elm acc))) (reverse acc))) (dupli '(a b c d e)) ;; => (A A B B C C D D E E)
;; P15 (defun repli (list times) (let ((acc '())) (dolist (elm list) (dotimes (i times) (push elm acc))) (reverse acc))) (repli '(a b c d e) 3) ;; => (A A A B B B C C C D D D E E E)
;; P16 (defun drop (list times) (let ((acc '()) (i 0)) (dolist (elem list) (if (= (incf i) times) (setf i 0) (push elem acc))) (reverse acc))) (drop '(a b c d e f g h i j k) 3) ;; => (A B D E G H J K)
P17ではcons cellが欲しかったのでdoをつかう。
;; P17 (defun split (list index) (do ((l list (cdr l)) (acc '()) (i 1 (1+ i))) ((> i index) (list (reverse acc) l)) (push (car l) acc))) (split '(1 2 3 4 5) 2) ;; => ((1 2) (3 4 5))
;; P18 (defun slice (list start end) (let ((acc '()) (i 1)) (dolist (elem list) (cond ((and (<= start i end)) (push elem acc)) ((> i end) (return))) (incf i)) (reverse acc))) (slice '(a b c d e) 2 4) ;; => (B C D)
;; P19 (defun rotate (list n) (let* ((len (length list)) (split-point (if (< 0 n) (- len (mod (- n) len)) (mod n len)))) (let ((split (split list split-point))) (append (second split) (first split))))) (rotate '(a b c d e f) 2) ;; => (C D E F A B) (rotate '(a b c d e f) -2) ;; => (E F A B C D) (rotate '(a b c d e f) 6) ;; => (A B C D E F) (rotate '(a b c d e f) -6) ;; => (A B C D E F)
P20とP21は再帰で実装。
doでも出来たかな。
;; P20 (defun remove-at (list n) (if (<= n 1) (cdr list) (cons (car list) (remove-at (cdr list) (1- n))))) (remove-at '(a b c d e) 3) ;; => (A B D E) >|lisp| ;; P21 (defun insert-at (alt list n) (if (<= n 1) (cons alt (cdr list)) (cons (car list) (insert-at alt (cdr list) (1- n))))) (insert-at 'alpha '(a b c d) 2) ;; => (A ALPHA B C)