Sunday, October 19, 2008

Lisp exercises

Long time, no post... Or something like that. Life's been moving ridiculously fast these days. Anyway, I got started learning Lisp (Common Lisp, if you most know) and found some nice exercises here. I'll post some of my first solutions here. I don't feel like posting to the newsgroup with this, but if you happen to have some Lisp experience and time, I'd appreciate some comments.

Some solutions:
;;; P01 - Find the last box of a list.
(defun my-last (list-arg)
  "By checking the length"
  (let ((list-length (length list-arg)))
    (nth (1- list-length) list-arg)))

(defun my-last-twist (list-arg)
  "By destructing a copy"
  (let ((list-tmp list-arg) (last) (tmp))
    (loop while (setf tmp (pop list-tmp)) do
         (setf last tmp))
    last))

;;; P02 - Find the last but one box of a list.
(defun my-but-last-rec (list-arg)
  "By recursion"
  (cond
    ((null list-arg) nil)
    ((null (rest list-arg)) nil)
    ((null (nth 2 list-arg)) (first list-arg))
    (t (my-but-last (rest list-arg)))))

(defun my-but-last (list-arg)
  "By indexing"
  (let ((list-length (length list-arg)))
    (if (<= 2 list-length)
        (nth (- list-length 2) list-arg)
        nil)))

;;; P07 - Flatten a nested list structure.
(defun my-flatten-real (list-arg)
  (if (not (listp list-arg))
      (list list-arg)
      (let ((acc (my-flatten-real (first list-arg))))
        (loop for item in (rest list-arg) do
             (setf acc (append acc (my-flatten-real item))))
        (return-from my-flatten-real acc))))

(defun my-flatten (list-arg)
  "Wrapper to keep this from returning a list of non-list arguments"
  (if (and (not (null list-arg)) (listp list-arg))
      (my-flatten-real list-arg)
      nil))

(defun sol-flatten (list-arg)
  "Based on original solution"
  (if (and (not (null list-arg)) (listp list-arg))
      (let ((item (car list-arg)) (list-rest (cdr list-arg)))  ; (rest list) <==> (cdr list) ?
        (if (listp item)
            (append (sol-flatten item) (sol-flatten list-rest))
            (append (cons item nil) (sol-flatten list-rest))))   ; (cons item nil) <==> (list item)?
      nil))

No comments:

Post a Comment