Skip to main content

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

a. Open the reference on vectors in a new tab or window.

b. Make a copy of vectors-lab.rkt, which contains much of the code from the reading.

Exercises

Exercise 1: Modifying Lists and Vectors

Suppose we are considering two names for the same collection (list or vector) and want to try to change the first element. Consider the following code. (That is, read it, don’t enter it.)

> (define aardvark (list 1 2 3 4))
> (define baboon (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. Check your answer experimentally. (That is, you can type in the commands now.)

c. What do you expect to happen to aardvark and baboon if we write the following?

> (define aardvark (cons -2 (cons -1 (cddr aardvark))))

d. Check your answer experimentally.

e. What do your results suggest about Scheme?

f. 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)
_____

g. Check your answer experimentally. (You can type the commands now.)

h. What do you expect the results of the following to be?

> (let* ([emu (list 1 2 3 4)]
         [frog emu]
         [emu (cons 5 (cdr emu))])
    (list emu frog))

i. Check your answer experimentally.

j. What do you expect the results of the following to be?

> (let* ([gibbon (vector 1 2 3 4)]
         [hippo gibbon])
    (vector-set! gibbon 0 5)
    (list gibbon hippo))

k. Check your answer experimentally.

l. What do your results to all of these experiments suggest about vectors and lists in Scheme?

Exercise 2: 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 the recursion pattern(s) and number-vector-largest as a starting point. If you do, be sure to cite your sources appropriately.

You may not convert your vector into a list.

Exercise 3: 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->irgb
        (list "red" "orange" "yellow" "green" "blue" "indigo" "violet"))))

Write a procedure, (palette-darker! palette), that, given a vector of integer-encoded RGB colors, makes each color in the palette slightly darker (i.e., using irgb-darker).

Note that you will not build a new vector. Rather, you will replace each color in the existing vector by the darker version. You may use the recursion pattern(s) from the reading and number-vector-divide! as a starting point. If you do, be sure to cite your sources appropriately.

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 4: Filling Vectors

Write your own version of vector-fill!; call it my-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 recur. Remember that when you want to sequence multiple actions if a test succeeds, you should use a cond or when rather than an if.

For Those With Extra Time

Extra 1: 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 2: 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 3: 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 4: 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.

;;; Procedure:
;;;   irgb-brightness
;;; Parameters:
;;;   color, an integer-encoded RGB color
;;; Purpose:
;;;   Computes the brightness of color on a 0 (dark) to 100 (light) scale.
;;; Produces:
;;;   brightness, an integer
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   If color1 is likely to be perceived as lighter than color2,
;;;     then (irgb-brightness color1) > (irgb-brightness color2).
;;;   0 <= brightness <= 100
(define irgb-brightness
  (lambda (color)
    (round (* 100 (/ (+ (* 0.30 (irgb-red color))
                        (* 0.59 (irgb-green color))
                        (* 0.11 (irgb-blue color)))
                      255)))))

;;; Procedure:
;;;   irgb-darker-of-two
;;; Parameters:
;;;   color1, an integer-encoded RGB color.
;;;   color2, an integer-encoded RGB color.
;;; Purpose:
;;;   Find the darker of color1 and color2.
;;; Produces:
;;;   darker, an RGB color.
;;; Preconditions:
;;;   irgb-brightness is defined.
;;; Postconditions:
;;;   darker is either color1 or color2
;;;   (irgb-brightness darker) <= (irgb-brightness color1)
;;;   (irgb-brightness darker) <= (irgb-brightness color2)
(define irgb-darker-of-two
  (lambda (color1 color2)
    (if (< (irgb-brightness color1) (irgb-brightness color2))
        color1
        color2)))

Extra 5: 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 recurs over vectors, setting the value at each position to a new value, much like the recursion patterns given in the reading.