99-lisp lisp 的99個問題 P11-20

babyyellow發表於2012-12-05

P11 (*) Modified run-length encoding.
    Modify the result of problem P10 in such a way that if an element has no duplicates it is simply copied

into the result list. Only elements with duplicates are transferred as (N E) lists.

    Example:
    * (encode-modified '(a a a a b c c a a d e e e e))
    ((4 A) B (2 C) (2 A) D (4 E))

CL-USER> (defun modify-element(lst)
       (if (> (car lst) 1 )
           (list lst)
           (cdr lst)))
            
STYLE-WARNING: redefining COMMON-LISP-USER::MODIFY-ELEMENT in DEFUN
MODIFY-ELEMENT
CL-USER> (defun encode-modify(lst)
       (let ((rl (encode lst)))
         (encode-modify-1 rl)))
STYLE-WARNING: redefining COMMON-LISP-USER::ENCODE-MODIFY in DEFUN
ENCODE-MODIFY
CL-USER> (encode-modify lst)
((4 A) B (2 C) (2 A) D (4 E))
CL-USER> lst
(A A A A B C C A A D E E E E)
CL-USER> (encode lst)
((4 A) (1 B) (2 C) (2 A) (1 D) (4 E))
CL-USER> (pack lst)
; Evaluation aborted on #.
CL-USER> (pack lst)
((A A A A) (B) (C C) (A A) (D) (E E E E))
CL-USER>
CL-USER> (encode-modify '(a a a b b (x y) c c c d e e e e))
((3 A) (2 B) (X Y) (3 C) D (4 E))
CL-USER> (encode-modify '(a a a b b (x y)(x y) c c c d e e e e))
((3 A) (2 B) (2 (X Y)) (3 C) D (4 E))




P12 (**) Decode a run-length encoded list.
    Given a run-length code list generated as specified in problem P11. Construct its uncompressed version.

CL-USER> (defun my-decode-element (lst)
       (if (consp lst)
           (repeat-element (car lst) (car(cdr lst)))
          (list lst)))
STYLE-WARNING: redefining COMMON-LISP-USER::MY-DECODE-ELEMENT in DEFUN
MY-DECODE-ELEMENT
CL-USER> (defun repeat-element (c x)
       (if (= c 0) nil
           (append (list x) (repeat-element (1- c) x))))
STYLE-WARNING: redefining COMMON-LISP-USER::REPEAT-ELEMENT in DEFUN
REPEAT-ELEMENT
CL-USER> (defun decode-element (lst)
       (if (null lst)
           nil
           (append (my-decode-element(car lst))(decode-element (cdr lst)))))
STYLE-WARNING: redefining COMMON-LISP-USER::DECODE-ELEMENT in DEFUN
DECODE-ELEMENT
CL-USER> (decode-element el)
(A A A B B (X Y) (X Y) C C C D E E E E)
CL-USER> el
((3 A) (2 B) (2 (X Y)) (3 C) D (4 E))
CL-USER>


P13 (**) Run-length encoding of a list (direct solution).
    Implement the so-called run-length encoding data compression method directly. I.e. don't explicitly create

the sublists containing the duplicates, as in problem P09, but only count them. As in problem P11, simplify the

result list by replacing the singleton lists (1 X) by X.

    Example:
    * (encode-direct '(a a a a b c c a a d e e e e))
    ((4 A) B (2 C) (2 A) D (4 E))

P14 (*) Duplicate the elements of a list.
    Example:
    * (dupli '(a b c c d))
    (A A B B C C C C D D)

CL-USER> (defun duli(lst)
       (if (null lst)
           nil
           (append (list (car lst) (car lst)) (duli (cdr lst)))))
DULI
CL-USER> (duli '(a b (x y) c))
(A A B B C C)
CL-USER> (duli '(a b (x y) c))
(A A B B (X Y) (X Y) C C)
CL-USER>



P15 (**) Replicate the elements of a list a given number of times.
    Example:
    * (repli '(a b c) 3)
    (A A A B B B C C C)

CL-USER>  (defun repeat-element (c x)
       (if (= c 0) nil
           (append (list x) (repeat-element (1- c) x))))
STYLE-WARNING: redefining COMMON-LISP-USER::REPEAT-ELEMENT in DEFUN
REPEAT-ELEMENT
CL-USER> (repeat-times '(a b c) 3)
(A A A B B B C C C)
CL-USER> (defun repeat-times (lst n)
       (if (null lst)
           nil
           (append (repeat-element n (car lst)) (repeat-times (cdr lst) n))))
STYLE-WARNING: redefining COMMON-LISP-USER::REPEAT-TIMES in DEFUN
REPEAT-TIMES
CL-USER> (repeat-times '(a b c) 3)
(A A A B B B C C C)
CL-USER>



P16 (**) Drop every N'th element from a list.
    Example:
    * (drop '(a b c d e f g h i k) 3)
    (A B D E G H K)


CL-USER> (defun remove-n (lst n)
       (let ((i 0))
         (loop for j in lst 
          when (not(= (mod (incf i) n) 0))
          collect j)))
             
STYLE-WARNING: redefining COMMON-LISP-USER::REMOVE-N in DEFUN
REMOVE-N
CL-USER> (remove-n lst 3)
(A B D E F G)
CL-USER> lst
(A B C D E C F G)
CL-USER> (remove-n '(a b c d e f j h k (x y)) 3)
(A B D E J H (X Y))
CL-USER> (remove-n '(a b c d e f j h (a)  k (x y)) 3)
(A B D E J H K (X Y))
CL-USER>




P17 (*) Split a list into two parts; the length of the first part is given.
    Do not use any predefined predicates.

    Example:
    * (split '(a b c d e f g h i k) 3)
    ( (A B C) (D E F G H I K))


CL-USER> (defun for-car (lst n)
       (if (null lst )
           nil
           (if (> n 0)
             (append (list (car lst)) (for-car (cdr lst) (decf n))))))
     
STYLE-WARNING: redefining COMMON-LISP-USER::FOR-CAR in DEFUN
FOR-CAR
CL-USER> (defun for-cdr (lst n)
       (if (null lst)
           nil
           (if (= n 0)
            lst
            (cdr (for-cdr lst (decf n))))))
STYLE-WARNING: redefining COMMON-LISP-USER::FOR-CDR in DEFUN
FOR-CDR
CL-USER> (defun split-n (lst n)
       (cons (for-car lst n) (list (for-cdr lst n))))
STYLE-WARNING: redefining COMMON-LISP-USER::SPLIT-N in DEFUN
SPLIT-N
CL-USER> (split-n lst 3)
((A B C) (D E C F G))
CL-USER>



P18 (**) Extract a slice from a list.
    Given two indices, I and K, the slice is the list containing the elements between the I'th and K'th element

of the original list (both limits included). Start counting the elements with 1.

    Example:
    * (slice '(a b c d e f g h i k) 3 7)
    (C D E F G)

CL-USER> (defun slice-iter (lst i k x)
       (cond ((null lst) nil)
         ( (< x i)  (slice-iter (cdr lst) i k (incf x)))
         ( (> x k) nil)
         (t (append (list(car lst)) (slice-iter (cdr lst) i k (incf x))))))
SLICE-ITER
CL-USER>
; No value
CL-USER> (defun slice (lst i k )
       (slice-iter lst i k 1))
STYLE-WARNING: redefining COMMON-LISP-USER::SLICE in DEFUN
SLICE
CL-USER> (slice lst 3 7)
(C D E C F)
CL-USER> lst
(A B C D E C F G)
CL-USER>



P19 (**) Rotate a list N places to the left.
    Examples:
    * (rotate '(a b c d e f g h) 3)
    (D E F G H A B C)

    * (rotate '(a b c d e f g h) -2)
    (G H A B C D E F)

    Hint: Use the predefined functions length and append, as well as the result of problem P17.

備註使用  P17 的 for-car 和for-cdr 兩個函式,很輕鬆實現。

CL-USER> (defun rotate (lst n)
       (cond ((null lst) nil)
         ((or (= n 0) (> n (length lst))) lst)
         ((> n 0) (cons (for-cdr lst n) (list(for-car lst n))))
         ((< n 0) (cons (for-cdr lst (+ (length lst) n))
                     (list (for-car lst (+ (length lst) n)))))
         ((< n -(length lst)) lst)))
STYLE-WARNING: redefining COMMON-LISP-USER::ROTATE in DEFUN
ROTATE
CL-USER> (rotate lst 3)
((D E C F G) (A B C))
CL-USER> (rotate lst -2)
((F G) (A B C D E C))
CL-USER>





P20 (*) Remove the K'th element from a list.
    Example:
    * (remove-at '(a b c d) 2)
    (A C D)


CL-USER>  (defun remove-at (lst n)
       (let ((i 0))
         (loop for j in lst 
          when (not (= (incf i) n))
          collect j)))
REMOVE-AT
CL-USER> (remove-at lst 5)
(A B C D C F G)
CL-USER> (remove-at lst 3)
(A B D E C F G)
CL-USER> lst
(A B C D E C F G)
CL-USER> 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/133735/viewspace-750585/,如需轉載,請註明出處,否則將追究法律責任。

相關文章