Scheme changing tree values

大憨熊 提交于 2019-12-02 09:44:04

Write down what the possible inputs are (there are three cases in the description of what a tree looks like) and define the result for each case.

Here is the general tree-traversal you need to implement:

  • If the tree is empty:
    • Produce the empty tree
  • If the tree is a leaf:
    • Produce an inverted leaf
  • Otherwise:
    • Invert the node's value
    • Produce a new tree by combining this inverted value with the results of inverting each subtree

You're probably going to want to read about map in your favourite Scheme book.

It's possible (but I suspect that it's a later exercise) to generalise this so it applies an arbitrary function in the tree, just like map does with lists.

The explanation for the tree structure doesn't seem to work. (1 (-2) (3) is a node, but 1 is not a parent. However it seems you can look at the whole thing as a binary tree where pairs are nodes and the empty list is an empty tree and any other value is a leaf node.

The abstraction would look like this:

(define make-tree cons)
(define tree-left car)
(define tree-right cdr)
(define tree? pair?)
(define empty-tree '())

You can map over the values of a tree like this:

(define (map-tree proc tree)
  (cond ((eq? empty-tree tree) empty-tree)
        ((tree? tree) 
         (make-tree (map-tree proc (tree-left tree))
                    (map-tree proc (tree-right tree))))
        (else (proc tree))))

Example:

(map-tree (lambda (v) (+ v 1)) '(1 (2) 3))
; ==> (2 (3) 4)

Obviously you need to replace the first argument with a procedure that works like this:

(inverse #f) ; ==> #t
(inverse #t) ; ==> #f
(inverse 5)  ; ==> -5
;; optional
(inverse 'xxx) ; ==> xxx

Then it's easy to make your procedure:

(define (inverse-tree tree)
  (map-tree inverse tree))

(inverse-tree ’(-5 (1 (-2) (3) (#f)) (#t)))
; ==> (5 (-1 (2) (-3) (#t)) (#f))

Now if you cannot use abstractions you would need to use the substitution rules. eg.

(define (tree-inc v)
  (map-tree (lambda (v) (+ v 1)) v))

; ==
(define (tree-inc tree)
  (cond ((eq? '() tree) '())
        ...
        (else (+ (car tree) 1))))

There you have it. More difficult to read and reason about than one that uses abstractions. Good luck with that.

After a lot of digging and understanding the syntax better I cam up with a simple 1 function solution:

(define (inverse-tree tree)
  (cond ((eq? '() tree) '())
        ((pair? tree) 
         (cons (inverse-tree (car tree))
                    (inverse-tree (cdr tree))))
        (else ((lambda(x) (if (boolean? x) (not x) (- x))) tree))))

I think that should work:

  (define inverse-tree
  (lambda (tree)
    (if (null? tree)
        '()
        (if (number? (car tree))
            (cons (* -1 (car tree)) (inverse-tree (cdr tree)))
            (if (boolean? (car tree))
                (cons (not (car tree)) (inverse-tree (cdr tree)))
                (cons (inverse-tree (car tree)) (inverse-tree (cdr tree))))))))
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!