I'm really puzzled on how to do this... I can't even figure out how to start, I know how to do it for a binary tree but I want to be able to do it with any form of nested list, can anyone help me out please?
For this one, you need to use the template for traversing an arbitrarily nested list of elements. For example, study this procedure that copies an arbitrarily nested list:
(define (copy lst)
(cond ((null? lst) ; if list is empty
'()) ; return the empty list
((not (list? (car lst))) ; if current element is not a list
(cons (car lst) ; cons current element
(copy (cdr lst)))) ; with the rest of the list
(else ; if current element is a list
(cons (copy (car lst)) ; cons recursive call over current element
(copy (cdr lst)))))) ; with recursive call over rest of the list
A little convention first. Let's say that 1
is the base level, and that all the elements returned will be in a flat output list (without preserving the original structure of the input list). For example:
(elements-level '(1 2 3) 1)
; => '(1 2 3)
(elements-level '(1 (2) 3) 2)
; => '(2)
With the above template in mind, let's see how we can modify it for solving the problem at hand. I'll let you fill-in the blanks, because the question looks like homework:
(define (elements-level lst lvl)
(cond ((or (null? lst) (< lvl 1)) ; if list is empty or below level
'()) ; return the empty list
((not (list? (car lst))) ; if current element is not a list
(if (= lvl <???>) ; if `lvl` is the base level
(cons <???> ; cons current element in list
(elements-level <???> lvl)) ; and advance recursion over cdr part
(elements-level <???> lvl))) ; else advance recursion over cdr part
(else ; if current element is a list
(append ; use `append` for flattening the list
(elements-level <???> <???>) ; recur over car, decrease one level
(elements-level <???> <???>))))) ; recur over cdr, keep the same level
Test the procedure with this list, it must return '(1)
for level 1
, '(2)
for level 2
, and so on:
(elements-level '(1 (2 (3 (4 (5))))) 1)
; => '(1)