Reputation: 309
I am working on a homework assignment, and the first functions had me doing things like deleting a given element of a list, or displaying a given element of a list. The next functions want me to delete nested lists, or display them. Do you have any general tips for working with nested lists? I imagine the functions will be very similar to the ones I wrote before, just tweaked a bit.
Here are two example of functions I have written so far. Note I must use the "cond" style of writing functions.
(defun delnth(L A)
(cond ((= A 1) (rest L))
(t (cons (first L) (delnth (rest L) (- A 1))))))
(defun remv(A L)
(cond ((eq A (first L)) (remv A (rest L)))
((null L) nil)
(t (cons (first L) (remv A (rest L) )))))
Upvotes: 0
Views: 2966
Reputation: 48775
Both of your functions work with nested cons
. '(1 2 3)
is (1 . (2 . (3 . ()))
and (cons 1 (cons 2 (cons 3 '())))
. A nested list would be that you also have nested cons
in the car
of cons
. eg. ((1 . ()) . ()) ; ==> ((1))
.
It's important to be able to see ((1) (2 3))
and understand that it is ((1 . ()) . ((2 . (3 . ())) . ()))
so that if you want to access 3
it's obviously the path d,a,d,a and in the reverse you can construct the accessor cadadr
.
cons
with cons
in the car
part are trees. When you make a function that walks the tree you need to walk both the car
and the cdr
in the event they are cons
. Thus:
;; generic function to walk trees and reduce
;; by combiner every value accessed by term
;; the default argument to combiner is tree-null
(defun accumulate-tree (tree term combiner null-value)
(labels ((rec (tree)
(cond ((null tree) null-value)
((atom tree) (funcall term tree))
(t (funcall combiner (rec (car tree))
(rec (cdr tree)))))))
(rec tree)))
(defun sum-numbers (tree)
(accumulate-tree tree
#'identity
#'+
0))
(defun count-numbers (tree)
(accumulate-tree tree
(lambda (v) (if (numberp v) 1 0))
#'+
0))
(sum-numbers '((1) (2 3) (((4)) 5))) ; ==> 15
(count-numbers '(a b 4 3 (e f 5) . 9)) ; ==> 4
The combiner doesn't need to reduce to an atom:
(defun reverse-tree (tree)
(accumulate-tree tree
#'identity
(lambda (a d) (cons d a))
'()))
(reverse-tree '((1 2) (3 4)))
; ==> ((nil (nil . 4) . 3) (nil . 2) . 1)
Upvotes: 1