-1

So in lisp a list is a collection of cons nodes, each node has two parts to it. The car of the node and the cdr of that node, how would I go about reversing each cons node?

user3011240
  • 87
  • 2
  • 8
  • 3
    Can you give some examples of input and output you want? We're having some trouble figuring out the desired behavior here. – zck Feb 10 '15 at 06:25

3 Answers3

2

Using reduce:

(defun reverse-conses (list)
  (reduce (lambda (x acc) (cons acc x)) list :initial-value nil :from-end t))

Recursively:

(defun reverse-conses (list)
  (if (null list) nil
      (cons (reverse-conses (cdr list)) (car list))))
danlei
  • 14,121
  • 5
  • 58
  • 82
  • I don't think this does what is desired -- for example, `(reverse-conses '((1 . 2)))` returns `(NIL 1 . 2)`, not `((2 . 1))`. – zck Feb 10 '15 at 05:27
  • 2
    @zck, it depends on how one reads the question. My solution works as I intended. While the first half of the first sentence might be read as if it's about a list *containing* cons cells (but note the "in lisp", which indicates that it's about Lisp lists in general), the rest clearly talks about *nodes*, which I interpreted as the constituent cons cells of the list *itself*. Let's wait until the OP clarifies. – danlei Feb 10 '15 at 06:14
  • And, btw, now that I'm reading the question again, the title says *recursively*. But I'll wait for further clarification before I change my answer. – danlei Feb 10 '15 at 06:23
  • 1
    Yeah, it could be specified better. Let's hope that happens. – zck Feb 10 '15 at 06:24
  • Then again, I'll be offline for the next 10 hours. Added a recursive solution. – danlei Feb 10 '15 at 06:27
1

I'm starting with a single function that swaps a cons cell.

(defun swap-cons (cns)
  (cons (cdr cns)
        (car cns)))

Let's test it:

> (swap-cons (cons 1 2))
(2 . 1)
> (swap-cons (cons 1 (cons 2 3)))
((2 . 3) . 1)

So this works. Now we just need to map this function over the input list

(defun swap-conses (lst)
  (mapcar #'swap-cons
       lst))

> (swap-conses '((1 . 2)))
((2 . 1))
> (swap-conses '((1 . 2) (3 . 4)))
((2 . 1) (4 . 3))
> (swap-conses '((1 2)))
(((2) . 1))
> (swap-conses '((1 . 2) (3 4) (5 6 7)))
((2 . 1) ((4) . 3) ((6 7) . 5))
zck
  • 2,712
  • 2
  • 25
  • 44
  • 1
    The title and description of this question talk about different things. It's not especially clear what @user3011240 wants. – zck Feb 10 '15 at 21:15
0

To recursively go through a whole tree and swap car and cdr you can do something like this:

(defun reverse-conses (tree)
  (if (consp tree)
      (cons (reverse-conses (cdr tree))
            (reverse-conses (car tree)))
      tree))

(reverse-conses (cons 1 2))   ; ==> (2 . 1)
(reverse-conses '(1 2 3))     ; ==> (((nil . 3) . 2) . 1)
(reverse-conses '(1 (2 3) 4)) ; ==> (((nil . 4) (nil . 3) . 2) . 1)

Considering the argument can consist of improper lists there isn't a simpler solution to this.

Sylwester
  • 47,942
  • 4
  • 47
  • 79