LISP: Multilevel Recursive Inverse Function

How can I change the list so that each sub-list is also reversed? This is what I have so far:

(defun REV (L)
  (cond
    ((null L) nil)
    ((listp L)
     (append
      (REV (cdr L))
      (list (car L))))
    (t
     (append
      (REV (cdr L)) 
      (list (car L))))))

      

+2


source to share


4 answers


You are on the right track, but your last two conditions have the same action, which should indicate that one of them is not doing what it should. Indeed, the second condition, case listp

, is not true, because when it is a list, you need to add back that list instead of the unmodified list. Possible Solution:

(defun reverse (l)
  (cond ((null? l) nil)
        ((listp (car l)) (append (reverse (cdr l)) 
                                 (list (reverse (car l)))))
        (t
          (append (reverse (cdr l)) 
                  (list (car l))))))

>  (reverse '((1 2 3) (4 5 6)))
((6 5 4) (3 2 1))

      



As you can see, the only difference is that you are checking if the first item is a list, and if so, you change the first item before adding it.

+5


source


I would write like this:



(defun reverse-all (list)
  (loop
     with result = nil
     for element in list
     if (listp element)
     do (push (reverse-all element) result)
     else do (push element result)
     finally (return result)))

      

+2


source


Sounds like a home problem :)

It looks like you started by writing the usual reverse code. I'll give you a hint: the second condition (listp L) is not entirely correct (it will always be true). You want to check if there is something else in the list.

0


source


dmitry_vk's answer (which is probably faster in most lisps than using append in the previous examples) in a more logical way:

(defun reverse-all (list)
  (let ((result nil))
    (dolist (element list result)
      (if (listp element)
          (push (reverse-all element) result)
          (push element result)))))

      

Or even:

(defun reverse-all (list)
  (let ((result nil))
    (dolist (element list result)
      (push
        (if (listp element) (reverse-all element) element)
          result))))

      

0


source







All Articles