Scheme Questions 1. ((fame (fame)) fame) 2. 5 3. Error! cannot use car on words 4. word 5. (-1 -999) 6. Error! cannot call the word '-' 7. ((a b) (c d) e) +---+---+ +---+---+ +---+---+ -->| | ---->| | ---->| | / | +-|-+---+ +-|-+---+ +-|-+---+ | | V | V e | +---+---+ +---+---+ | | | ------>| | / | | +-|-+---+ +-|-+---+ | V V V c d +---+---+ +---+---+ | | ----->| | / | +-|-+---+ +-|-+---+ V V a b 8. (((c) s) (6 1) a) +---+---+ +---+---+ +---+---+ --->| | ----->| | ------>| | / | +-|-+---+ +-|-+---+ +-|-+---+ | | V | V a | +---+---+ +---+---+ | | | ------>| | / | | +-|-+---+ +-|-+---+ | v V v 6 1 +---+---+ +---+---+ | | ----->| | / | +-|-+---+ +-|-+---+ | v v s +---+---+ | | / | +-|-+---+ v c Only calls to cons (cons (cons (cons c nil) (cons s nil)) (cons (cons 6 (cons 1 nil)))) 9. (define (list? thing) (or (null? thing) (and (pair? thing) (list? (cdr thing))))) Can't use CDR without checking it's a pair! 10. (mystery 'a 'b 'c 'd) .. -> mystery with x = a, args = (b c d) .... -> mystery with x = (b), args = ((c) (d)) .... <- mystery returns ((c) (d)) .. <- mystery returns ((c) (d)) ((c) (d)) apply needs to take in the procedure and a list of arguments when using the 'dot' args everything after the dot is put into a list. 11. (define (diagonal lst) (if (null? lst) '() (cons (caar lst) (diagonal (map cdr (cdr lst)))))) Here is a clever HOF version that uses ENUMERATE-INTERVAL: (define (diagonal L) (let ((indexlist (enumerate-interval 0 (- (length L) 1)))) (map (lambda (index) (list-ref (list-ref L index) index)) indexlist))) ENUMERATE-INTERVAL works like this: STk> (enumerate-interval 0 5) (0 1 2 3 4 5) 12. It won't work...it will always return you '() because you're always comparing it with the original list which has everything in it. 13. This function keeps all the toplevel sublists, appending them, and tosses out all atomic toplevel elements. By "toplevel" elements we mean ones that get counted by LENGTH. There are three cases: 1) The empty list. 2) The first element of the list is a list. 3) The first element of the list is not a list. Also you need to know which list constructor to use to build up your resulting list. (define (flatten-once L) (cond ((null? L) L) ((list? (car L)) (append (car L) (flatten-once (cdr L)))) (else (flatten-once (cdr L))))) In the HOF version, it is useful to break up the problem into a filtering stage followed by an append stage. (define (flatten-once L) (accumulate append (list) (filter list? L))) 14. So the correct solution to this problem is: (define (depth N L) (depth-helper N L 1)) (define (depth-helper N L D) (cond ((null? L) #f) ((not (pair? (car L))) (if (= (car L) N) D #f)) (else (or (depth-helper N (car L) (+ D 1)) (depth-helper N (cdr L) D))))) So here's also a solution...but.. (define (depth-helper N L D) (cond ((null? L) #f) ((not (pair? L)) (if (= N L) D #f)) (else (or (depth-helper N (car L) (+ D 1)) (depth-helper N (cdr L) D))))) So what's wrong with this solution? So take a call like: (depth 4 '(4)) what would this return with the solution I presented in class? Since (4) is not a pair it will go in the else clause and do a recursive call on the car, 4, and D+1....see something wrong? 4 is STILL on the top level. So that's why I did (car L) on the correct solution. 15. So cost trees look something like this: Given this tree... 1 / \ 3 2 --- \ / | \ \ 4 8 1 5 after a call to cost will return... 1 / \ 4 3 --- \ / | \ \ 8 12 5 8 a new tree! So for the mutual recursion version you have to handle trees and then the children of the trees (list of trees). So let's take this step by step first with a tree I will find an algorithm. I want to make a tree with the datum of the tree and somehow add that datum to the datum of it's children. So you know that cost will always return you a tree, make sure you return a tree!!! Okay let's go with this... (define (cost tree) (make-tree (datum tree) (cost-children (datum tree) (children tree))))) So I'm going to make a tree out of the datum of the tree and handle the children in a different procedure called cost-children. This procedure should return a list of trees. Why? because it's the second argument to make-tree which are the children which is a list of trees. I also want to add the current tree's datum with each of the children, so I passed in the datum of the current tree to use for cost-children. Alright now let's think about what to do with the children. When there's no children. I want just to return the empty list. Otherwise I want to somehow call cost on each of the children, but with each of the children's datum added to the parent's datum. So you basically make a new tree with the child's datum and the parent's datum added together and have the same children as before. (define (cost-children parent-datum list-of-trees) (if (null? list-of-trees) '() (cons (cost (make-tree (+ parent-datum (datum (car list-of-trees))) (children (car list-of-trees)))) (cost-children parent-datum (cdr list-of-trees))))) So you call cost on each of the children where they all have new datums. As for the solution without the helper this uses map. (define (cost tree) (make-tree (datum tree) (map (lambda (child) (cost (make-tree (+ (datum tree) (datum child)) (children child)))) (children tree)))) So as discussed in section we don't need the leaf? base case for this because map handles the no children case. Trace it out. See if it really works. =) Trust the recursion!!! 16. Selectors: (define get-name car) (define get-country cadr) (define get-events caddr) (define (get-participants event list-of-athletes) (cond ((null? list-of-athletes) '()) ((member? event (get-event (car list-of-athletes))) (se (get-name (car list-of-athletes)) (get-participants event (cdr list-of-athletes)))) (else (get-participants event (cdr list-of-athletes)))) ) 17. (define (diagonal lstsents) (if (null? lstsents) () (se (first (car lstsents)) (diagonal (chop (cdr lstsents)))))) (define (chop lstsents) ;; removes the first word from each sentence (if (null? lstsents) '() (cons (bf (car lstsents)) (chop (cdr lstsents))))) 18. *taken from Spring 2002 MT1* Part (a) You need to remember that from and to are just types and not tagged data. So saying (contents from) was a serious violation. (define (raise from to) (if (eq? from to) 1 (let ((next (get 'convert from))) (* (contents next) (raise (type-tag next) to))))) Part(b) (define (length-convert amount-from to) (let ((amount (contents amount-from)) (from (tag-type amount-from))) (attach-tag to (if (left? from to) (* amount (raise from to)) (/ amount (raise to from))))))