Functional Problem Solving (CSC 151 2013F) : Labs
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning] [Grading]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Setup] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Davis (2013F)] [Rebelsky (2010F)] [Weinman (2012F)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)]
Summary: In this laboratory, you will explore the running time for a few algorithm variants.
a. Make a copy of analysis-lab.rkt, which contains most of the procedures you will
need for this lab.
b. Review the file to see what procedures are included. You may find it easiest to look at the list provided by the menu.
a. Add the following line to the beginning of list-append
(immediately after the line containing the lambda).
(write (list 'list-append front back)) (newline)
b. Determine how many times list-append is called when
reversing a list of length seven using list-reverse-1.
c. Add the following line to the kernel of list-reverse-2
(again, immediately after the line containing the lambda).
(write (list 'kernel remaining reversed)) (newline)
d. Determine how many times the kernel
is called when reversing a list of length seven using
list-reverse-2.
e. Comment out the lines that you just added by prefixing them with a semicolon.
In the reading, we analyzed two versions of rgb-brightest
by creating counters for each procedure, annotating the procedures
to count each time, and then seeing the results for different size
input. See if you can replicate our results.
You may find the following code helpful.
(define grey (lambda (n) (rgb-new n n n))) (define light-to-dark (map grey (list 255 192 128 64 0))) (define dark-to-light (reverse light-to-dark)) (define lots-of-greys (map grey (list 0 16 32 48 64 96 112 128 144 160 176 192 208 224 240 255)))
a. Add counters for list-append,
list-reverse-1, list-reverse-2
and any other things you think will be useful to count as we
analyze the various versions of list-reverse.
b. Annotate each of those procedures so that it increments the appropriate counter.
c. Find out how many times list-append is called
in reversing a list of seven elements by entering the following commands
in the interactions pane.
>(counter-reset! list-append-counter)>(list-reverse-1 (iota 7))>(counter-print! list-append-counter)
d. Did you get the same answer as in the first exercise? If not, why do you think you got a different result?
e. Find out how many times kernel is called in reversing
a list of seven elements.
f. Did you get the same answer as in exercise 1? If not, what difference do you see?
What if we care about calls to car,
cdr, and such? We'll need to create our
own versions of those procedures, along with counters. As a
start, we might write:
(define car-counter (counter-new "car"))
(define cdr-counter (counter-new "cdr"))
(define cons-counter (counter-new "cons"))
(define null?-counter (counter-new "null?"))
(define list-counters (list car-counter cdr-counter cons-counter null?-counter))
(define $car
(lambda (lst)
(counter-count! car-counter)
(car lst)))
(define $cdr
(lambda (lst)
(counter-count! cdr-counter)
(cdr lst)))
(define $cons
(lambda (val lst)
(counter-count! cons-counter)
(cons val lst)))
(define $null?
(lambda (val)
(counter-count! null?-counter)
(null? val)))
We then have to update all of our calls to car to
use $car instead.
(define list-reverse-1
(lambda (lst)
(if ($null? lst)
null
(list-append (list-reverse-1 ($cdr lst)) (list ($car lst))))))
Unfortunately, we can't quite do that for list,
because list takes a variable number of parameters.
So, we might rewrite the procedure to more explicitly use
cons.
(define list-reverse-1
(lambda (lst)
(if ($null? lst)
null
(list-append (list-reverse-1 ($cdr lst))
($cons ($car lst) null)))))
a. Find out how many total procedure calls are done in reversing a list
of length seven, using list-reverse-1, with the following.
>(for-each counter-reset! list-counters)>(list-reverse-1 (iota 7))>(for-each counter-print! list-counters)
b. How does the total number of calls seem to relate to the number of
calls to list-append?
c. Update list-reverse-2 and find out how many
total procedure calls (including calls to kernel)
when we use that procedure to reverse a list of length seven.
d. How does that number of calls seem to relate to the number of
calls to kernel?
a. Fill in the following chart to the best of your ability.
| List Length | rev1: Calls to list-append |
rev1: Total function calls | rev2: Calls to kernel |
rev2: Total function calls |
|---|---|---|---|---|
| 2 | ||||
| 4 | ||||
| 8 | ||||
| 16 |
b. Predict what the entries will be for a list size of 32.
c. Check your results experimentally.
d. Write a formula for the columns, to the best of your ability.
Here is a third version of rgb-brightest, which should already
be in your program.
(define rgb-brightest-3
(lambda (colors)
(let kernel ([brightest-so-far (car colors)]
[remaining-colors (cdr colors)])
(if (null? remaining-colors)
brightest-so-far
(kernel (rgb-brighter brightest-so-far (car remaining-colors))
(cdr remaining-colors))))))
a. Find out how many steps this procedure takes on lists of length 2, 4, 8, and 16 in which the elements are arranged from lightest to darkest.
b. Find out how many steps this procedure takes on lists of length 2, 4, 8, and 16 in which the elements are arranged from darkest to lightest. (You can reverse the lists from the previous step to create these lists.)
c. Find out how many steps this procedure takes on lists of length 2, 4, 8, and 16 in which the elements are in no particular order.
d. Predict the number of steps this procedure will take on each kind of list, where the length is 32.
Consider rgb-brightest-4, a variant of an efficient
version of rgb-brightest that has additional error
checking added.
(define rgb-brightest-4
(lambda (colors)
(when (not (all-rgb? colors))
(error "rgb-brightest: expects a list of colors; received" colors))
(if (null? (cdr colors))
(car colors)
(rgb-brighter (car colors)
(rgb-brightest-4 (cdr colors))))))
a. Predict the number of calls to rgb-brightest-4
in finding the brightest in a list of eight colors.
b. Check your hypothesis.
c. Predict the number of calls to all-rgb? in
finding the brightest in a list of eight colors.
d. Check your hypothesis.
Rewrite rgb-brightest-4 so that it continues to
check preconditions, but precondition checking does not exact such a
heavy penalty.
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning] [Grading]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Setup] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Davis (2013F)] [Rebelsky (2010F)] [Weinman (2012F)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)]
Samuel A. Rebelsky, rebelsky@grinnell.edu
Copyright (c) 2007-2013 Janet Davis, Samuel A. Rebelsky, and Jerod Weinman. (Selected materials are copyright by John David Stone or Henry Walker and are used with permission.)

This work is licensed under a Creative Commons Attribution 3.0 Unported License. To view a copy of this
license, visit http://creativecommons.org/licenses/by-nc/3.0/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.