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
- Give you a deeper understanding of functions
- Give you a deeper understanding of recursion
Put the following comment at the top of your Dr. Racket file:
; Homework 4
; your name
.
Part I: Unrestricted Lambdas
- 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.
- 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
- 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.
- 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.
- 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))))
- 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.
- Use Fold to write (rev lat), which returns the reversal of lat.
- 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))).
- Use fold to write a procedure weigh which takes a baggage list and returns the total weight.
- Use fold to write a procedure heaviest which returns the bag of maximum weight. Assume that no weights are negative.
- 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.
- 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).
- 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))))