;;; ============================================== ;;; CMPU-101, Fall 2009 ;;; Code used in class ;;; Nov. 10, 2009 ;;; ============================================== (load "asmt-helper.txt") ;;; ============================================== (problem "SQUARE-ALL*") ;;; SQUARE-ALL* ;;; ---------------------------------------------- ;;; INPUT: LISTY, a possibly-hierarchical list of numbers ;;; OUTPUT: A list whose structure is the same as LISTY ;;; but each element has been squared. (define square-all* (lambda (listy) (cond ;; Base Case: LISTY is empty ((null? listy) ()) ;; Recursive Case: FIRST of LISTY is a list ((list? (first listy)) ;; CONS the answers returned by the recursive function calls (cons (square-all* (first listy)) (square-all* (rest listy)))) ;; Recursive Case: First of LISTY is a number (#t ;; Just like in the square-all function for flat lists... (cons (* (first listy) (first listy)) (square-all* (rest listy))))))) (tester '(square-all* '((2 3) 1 (((3) 4))))) (tester '(square-all* '((4 2) 3 (8 (7))))) ;;; ================================================= (problem "SUM*") ;;; SUM* ;;; --------------------------------------------- ;;; INPUT: LISTY, a possibly hierarchical list of numbers ;;; OUTPUT: The sum of all the numbers in LISTY, regardless ;;; of where they appear in LISTY. (define sum* (lambda (listy) ;; For fun: (printf "... LISTY = ~A~%" listy) (cond ;; Base Case: LISTY is empty ((null? listy) 0) ;; Recursive Case: FIRST of LISTY is a LIST ((list? (first listy)) ;; recursive function calls: ;; (sum* (first listy)) -- sum all elts in FIRST of LISTY ;; (sum* (rest listy)) -- sum all elts in REST of LISTY (+ (sum* (first listy)) (sum* (rest listy)))) ;; Recursive Case: FIRST of LISTY is a number (#t ;; Just like we did with flat lists... (+ (first listy) (sum* (rest listy))))))) (tester '(sum* '((1) ((2) (((3) 4) (5 6))) -10))) (tester '(sum* '(1 (2 (3) 4) ((5) 6)))) ;;; ================================================= (problem "MAP*") ;;; MAP* ;;; ------------------------------------------- ;;; INPUTS: FUNC, a function that takes one input ;;; LISTY, a possibly-hierarchical list of ;;; the kinds of inputs FUNC likes ;;; OUTPUT: A list whose structure is just like LISTY's, ;;; but whose elements result from applying ;;; FUNC to the corresponding elements of LISTY. (define map* (lambda (func listy) (cond ;; Base Case: LISTY is EMPTY ((null? listy) ()) ;; Recursive Case: FIRST of LISTY is a LIST ((list? (first listy)) ;; Note that there are two recursive function calls... (cons (map* func (first listy)) (map* func (rest listy)))) ;; Recursive Case: FIRST of LISTY is NOT a LIST (#t ;; This is just like what we did with MAPPY on flat lists... (cons (func (first listy)) (map* func (rest listy))))))) (define square (lambda (x) (* x x))) (tester '(map* square '((1) ((2) 3) ((4 (5)))))) (tester '(map* (lambda (x) (* x x)) '((1) ((2) 3) ((4 (5)))))) (newline) (tester '(map* (lambda (x) (* x x x)) '(3 (4) ((3) 10 (9)) 8))) (newline) (define facty (lambda (n) (if (<= n 0) 1 (* n (facty (- n 1)))))) (tester '(map* facty '(1 2 (3 4) ((5) 6) 7))) ;;; ================================================== (problem "FLATTEN*") ;;; FLATTEN* ;;; ----------------------------------------- ;;; INPUT: LISTY, a possibly-hierarchical list ;;; OUTPUT: A flat list containing the same elements ;;; as LISTY, and in the same order that they ;;; appear when LISTY is displayed by drScheme. (define flatten* (lambda (listy) (cond ;; Base Case: LISTY is EMPTY ((null? listy) ()) ;; Recursive Case: FIRST of LISTY is a LIST ((list? (first listy)) ;; We use APPEND to concatenate the flat lists returned ;; by the two recursive function calls... ;; (e.g., (append '(1 2 3) '(4 5)) ==> (1 2 3 4 5)) (append (flatten* (first listy)) (flatten* (rest listy)))) ;; Recursive Case: FIRST of LISTY is NOT a LIST (#t ;; CONS (first listy) onto the flat list returned by ;; the recursive function call... ;; (e.g., (cons 8 '(1 2 3 4)) ==> (8 1 2 3 4)) (cons (first listy) (flatten* (rest listy))))))) (tester '(flatten* '((4) (3 8) (9 ((2) 6))))) (tester '(flatten* '((2) (33 4) 5))) ;;; =============================================== (problem "DEPTH*") ;;; DEPTH* ;;; ------------------------------------------------------ ;;; INPUT: LISTY, a possibly-hierarchical list ;;; OUTPUT: The depth of LISTY (i.e., the maximum ;;; level of nesting of lists within lists) ;;; ------------------------------------------------------ ;;; NOTE: Each left parenthesis increases the depth; ;;; Each right parenthesis decreases the depth. ;;; NOTE: () has depth 0 by general agreement. ;;; NOTE: (a b c) has depth 1. ;;; NOTE: (a (b) c) has depth 2. And so on. (define depth* (lambda (listy) (cond ;; Base Case: LISTY is EMPTY ((null? listy) 0) ;; Recursive Case: FIRST of LISTY is a LIST ((list? (first listy)) ;; Note: Need to add 1 to answer returned by ;; recursive function call on FIRST of LISTY ;; because it is one cons cell deeper than ;; REST of LISTY. (max (+ 1 (depth* (first listy))) (depth* (rest listy)))) ;; Recursive Case: FIRST of LISTY is NOT a LIST (#t ;; The FIRST of LISTY is at depth 1... (max 1 (depth* (rest listy))))))) (tester '(depth* '(a (b (c) d) e))) (tester '(depth* '((1) 1))) (tester '(depth* '((2) (3 4 5) ((67) 8)))) ;;; =================================================== (problem "SHAPE*") ;;; SHAPE* ;;; --------------------------------------------- ;;; INPUT: LISTY, a possibly hierarchical list ;;; OUTPUT: A list that results from removing all ;;; non-list elements from LISTY, wherever ;;; they appear. ;;; --------------------------------------------- ;;; In the Interactions Window, the output of this ;;; function will have the same structure of parentheses ;;; as the input, but will not have any of the data. ;;; Example: (shape* '((1) ((2)) 3)) ==> (() (())) (define shape* (lambda (listy) (cond ;; Base Case: LISTY is EMPTY ((null? listy) ()) ;; Recursive Case: FIRST of LISTY is a LIST ((list? (first listy)) ;; NOTE: We use CONS to create the same cons-cell structure ;; we were given... (cons (shape* (first listy)) (shape* (rest listy)))) ;; Recursive Case: FIRST of LISTY is NOT a LIST (#t ;; Ignore the FIRST of LISTY!! (shape* (rest listy)))))) (tester '(shape* '((2) (3 4 5) ((67) 8)))) (tester '(shape* '((1) ((2)) 3))) (tester '(shape* '((a) ((b c) d) ((e) f))))