Laboratory: Vectors Summary: In this laboratory, you will explore various aspects of the Vector data type that Scheme provides as an alternative to lists.
Preparation Open the reference on vectors in a new tab or window.
Exercises
Exercise 1: Create a Simple Vector a. In the Interaction pane, type in a vector literal that denotes a vector containing just the two elements 3.14159 and 2.71828. How does MediaScript display the value of this vector? b. Create a vector that contains the same two values by using the vector procedure. c. Create a vector that contains the same two values by using the make-vector and vector-set! procedures.
Exercise 2: Modifying Lists and Vectors Consider the following code. (That is, read it, don't enter it.) > (define aardvark (list 1 2 3 4)) > (define baboon aardvark) > (define aardvark (cons 5 (cdr aardvark))) > (define chinchilla (vector 1 2 3 4)) > (define dingo chinchilla) > (vector-set! chinchilla 0 5) a. What do you expect the output of the following commands to be? > (list-ref aardvark 0) _____ > (list-ref baboon 0) _____ b. Verify your answer experimentally. (That is, you can type in the commands now.) c. What do your results suggest about Scheme? d. What do you expect the output of the following commands to be? (That is, think about the answer; don't just type it in.) > (vector-ref chinchilla 0) _____ > (vector-ref dingo 0) _____ e. Verify your answer experimentally. (You can type the commands now.) f. What do your results suggest about vectors and lists in Scheme?
Exercise 3: From Lists to Vectors In the reading on vectors, we saw that it was possible to implement list->vector and vector->list by using more primitive operations (particularly vector-set! and vector-length). Here's the definition of list->vector and its kernel. The design of list->vector is a bit subtle. Explain what the kernel does. If you're not completely sure, you may want to add a call to display inside the kernel, as in (display (list 'l2v-kernel! lst pos vec)) (newline)
Exercise 4: Darkening Vector-Based Palettes It is possible to represent a collection of colors (a palette) as a vector. Why would we do so? Well, once we've chosen a palette, we can represent an image as a collection of indices into that palette. Such a representation is typically much more compact than representing each color with the full RGB triplet. For example, here is a palette that represents the colors in the rainbow. (define rainbow-palette (list->vector (map color->rgb (list "red" "orange" "yellow" "green" "blue" "indigo" "violet")))) Write a procedure, (palette-darker! palette), that, given a vector of RGB colors, makes each color in the palette slightly darker. (Note that you will not build a new vector. Rather, you will replace each color in the existing vector by the darker version. That means you should not be using vector->list or list->vector in your implementation.) You can test your procedure by converting the vector back to a list and then converting the RGB colors back to strings > (palette-darker! rainbow-palette) > (map rgb->string (vector->list rainbow-palette))
Exercise 5: Building Palettes Here is a procedure that builds a list-based palette from an image by randomly selecting n values from the image. Using this procedure as a guide to creating colors, and list->vector as a guide to building vectors, write (palette-fill! palette image), which fills palette with colors randomly selected from the image. (Why don't we have an n as a parameter? Because you should use the palette size for the number of colors to fill in.)
For Those With Extra Time
Extra 1: Summing Vectors Write a procedure, (vector-sum numbers), which takes one argument, a vector of numbers, and returns the sum of the elements of that vector. You can use vector->list from the reading as a pattern for vector-sum; only a few judicious changes are needed. However, you should not use vector->list as a helper.
Extra 2: Filling Vectors Write your own version of vector-fill!. Remember that vector-fill! takes two parameters, a vector and a value, and puts that value in every position of the vector. Note: You may find that you want to do two things for a particular position: fill the value at that position and recurse. Remember that when you want to sequence actions if a test succeeds, you should use a cond rather than an if.
Extra 3: Rotating Vectors Write a procedure, (vector-rotate! vec) that rotates the elements in vec. That is, rotate! puts the initial element of vec at the end, the element at position 1 in position 0, the element at position 2 in position 1, and so on and so forth.
Extra 4: Reversing Vectors a. Write a procedure, (vector-reverse vec), that creates a new vector whose elements appear in the reverse order of the elements in vec. b. Write a procedure, (vector-reverse! vec), that reverses vec in place. That is, instead of producing a new vector, it rearranges the elements within vec.
Extra 5: Rotating Vectors, Revisited Write a procedure, (vector-rotate! vec amt), that rotates the values in vec by amt positions. That is, the first amt values in vec move to the end, the value in position amt moves to position 0, the value in position amt+1 moves to position 1, and so on and so forth.
Extra 6: The Darkest Color, Revisited Write a procedure, (palette-darkest palette), that takes one argument, a vector of colors, and returns the darkest color in that vector. You can assume that every position in the vector contains a color. You will need the definitions of rgb-brightness and rgb-darker-of-two.
Extra 7: Patterns of Recursion In a number of previous exercises, you wrote procedures that iterated over the vector, changing values as you went. (For example, vector-fill! and palette-complement! both had this form.) Summarize the form of a procedure that recurses over vectors, setting the value at each position to a new value.
Notes
Notes on Extra 2: Filling Vectors Just as in the case of list->vector, you will probably want to define a helper procedure that fills only part of the vector. Your termination condition will certainly be different and should probably involve the length of the vector.