Suppose I have the following tree:
In my program, this tree is represented using a list: '(+ (* 5 6) (sqrt 3))
.
How do I get a subtree by its index?
The index should start from 0 and be depth-first. In the picture above, I have labelled all the nodes with their index to show this.
For example:
(define tree '(+ (* 5 6) (sqrt 3)))
(subtree tree 0) ; Returns: '(+ (* 5 6) (sqrt 3)))
(subtree tree 1) ; Returns: '(* 5 6)
(subtree tree 2) ; Returns: 5
(subtree tree 3) ; Returns: 6
(subtree tree 4) ; Returns: '(sqrt 3)
(subtree tree 5) ; Returns: 3
I tried to implement subtree
like this:
(define (subtree tree index)
(cond [(= index 0) tree]
[else
(subtree (cdr tree)
(- index 1))]))
However, this does not traverse into sublists. It is incorrect.
EDIT:
I tried to implement subtree
using continuation-passing style:
(define (subtree& exp index counter f)
(cond [(= counter index) exp]
[(null? exp) (f counter)]
[(list? exp)
(let ((children (cdr exp)))
(subtree& (car children)
index
(+ counter 1)
(lambda (counter2)
(if (null? (cdr children))
(f counter)
(subtree& (cadr children)
index
(+ counter2 1)
f)))))]
[else (f counter)]))
(define (subtree tree index)
(subtree& tree
index
0
(lambda (_)
(error "Index out of bounds" index))))
This works correctly for trees like:
'(+ 1 2)
'(+ (* 5 6) (sqrt 3))
However, it fails for trees like:
'(+ 1 2 3)
What is wrong with my implementation?