CS275

HW 04

Higher Level Functions

Due: Monday, March 3

You should do this lab individually; not in a team. As usual, you can talk to anyone you wish about it as long as you write your own code.

The goals for this assignment are to

Put the following comment at the top of your Dr. Racket file:

; Homework 4 
your name 
.

Part I: Unrestricted Lambdas

  1. Use the unrestricted-lambda to write a procedure mag which computes the magnitude of a vector of any length. (For the purposes of this exercise, we are using the term "vector" to mean "list of numbers". So mag is expecting a bunch of numbers, as in (mag 3 4) or (mag 2 4 6 8 5).) Use helper procedures as necessary.

  2. Define a procedure norm which takes a list of reals as its argument and returns a normalized list. Recall normalizing is done by dividing each element of the list by the magnitude. Use mag from Exercise 1 to compute the magnitude and map to perform the normalizing.

Part 2: Map and Apply

  1. Consider a list, not necessarily flat, of numbers, such as ( (1 (2)) (((4))) 5). Use map and apply to write a procedure (sum L) that sums all of the numbers in such a list.

  2. Again consider a general list of numbers and a function f of one argument. Use map and apply to write a procedure (apply-to f L) that builds a new list with the same structure as L, only f is applied to each of the elements of L to get the values in the new list.

  3. Write the procedure (element-of? a L) that returns true if atom a is an element of (not-necessarily flat) list L.

Part 3: Fold. Fold is not defined in our version of Scheme so you'll need to include it in your file:

    (define fold (lambda (f base lat)
               ( letrec ([h (lambda (L)
                                  (cond
                                        [(null? L) base]
                                        [else (f (car L) (h (cdr L)))]))])
                       (h lat))))
  1. Use Fold to write (index a lat), which returns the 0-based index of atom a in lat, or -1 if a is not an element of lat.

  2. Use Fold to write (rev lat), which returns the reversal of lat.

  3. Assume bagsis globally defined to be an association list containing sublists of two elements. Each sublist represents the name of a piece of luggage and its respective weight, where the caris the name of the piece of luggage and thecadr is the weight. Such a list might look like this:
                          (define bags '((duffle 8) (garment-bag 2) (briefcase 5) (valise 7) (steamer-trunk 65))).
    1. Use fold to write a procedure weigh which takes a baggage list and returns the total weight.
    2. Use fold to write a procedure heaviest which returns the bag of maximum weight. Assume that no weights are negative.
    3. Use fold to write a procedure which filters out luggage with invalid weights (negative or zero weights) and returns a filtered list.

Part 4: Deep-fold Fold is designed to work with flat lists. Here is a generalization of it that works with general list:

    (define deep-fold (lambda (atom-f pair-f base lyst)
               ( letrec ([h (lambda (L)
                                  (cond
                                        [(null? L) base]
                                        [(pair? (car L)) (pair-f (h (car L)) (h (cdr L)))]
                                        [else (atom-f (car L) (h (cdr L)))]))])
                       (h lyst))))

This takes two proceduresL one to handle the case where the car of the list is an atom, and one where it is a pair.

  1. Use deep-fold to write (member* a L), which returns true if atom a is an element of general list L, in terms of deep-fold. Of course, member* is functionally the same as the element-of procedure from question (5).

  2. Use deep-fold to write procedure (apply-to* f L) which returns a new list structured just like L, only procedure f is applied to each of its elements.
    (apply-to* add1 '((1 2) (3 ((4))))) returns ((2 3) (4 ((5))))