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?
LISP: take an arbitrary s-expression and reverse every cons node (car and cdr of a node) recursively
Asked
Active
Viewed 317 times
-1
-
3Can 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 Answers
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
-
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
-
1The 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