CS275

HW 04

Higher Level Functions

Due: Wednesday, September 28

The goals for this assignment are to

 

Part I: Unrestricted Lambdas

  1. Use the unrestricted-lambda to write a procedure mag which takes any number of numerical arguments and returns the square root of the sum of the squares of its arguments. For example, (mag 3 4) returns 5.

  2. Define a procedure norm which takes any number of numerical arguments and returns a normalized list of its arguments. "Normalizing" is done by dividing each element by the magnitude of the wholel list (so the magnitude of the normalized list is 1). 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. For example, (apply-to add1 '(3 (4 5))) is (4 (5 6)).

  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 bags is 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 procedures: one to handle the case where the car of the list is an atom, and one where it is a pair. atom-f takes two arguments, which you can think of as the car of the list and the result of recursing on the cdr pair-f also takes two arguments, which you can think of as the result of recursing on the car and the result of recursing on the cdr.

  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))))