Functional Problem Solving (CSC 151 2015F) : Assignments
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Taking Notes] [Rubric] [Remote Access]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Labs] [Outlines] [Readings] - [Examples] [Handouts]
Reference: [Setup] [VM] [Errors] - [Functions A-Z] [Functions By Topic] - [Racket] [Scheme Report (R5RS)] [R6RS] [TSPL4]
Related Courses: [Curtsinger (2015F)] [Davis (2013F)] [Rebelsky (2015S)] [Weinman (2014F)]
Misc: [Submit Questions] - [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] - [Issue Tracker (Course)]
Due: 10:30 p.m., 8 September 2015
Summary: We consider some initial problems that you will solve with the Scheme programming language.
Purposes: To get you used to writing Scheme. To get you started thinking about algorithm design. To encourage you to do work outside of class.
Collaboration: You must work with assigned partners on this assignment. The partner assignments were made in class the day this was assigned. You may discuss this assignment with anyone, provided you credit such discussions when you submit the assignment.
Wrapper (Prologue): Individually read through this assignment and make sure that you understand what is required. Then use the form available at http://bit.ly/151hw2pro to indicate (a) how long you think this assignment will take and (b) what you think will be the most challenging aspect of this assignment.
Wrapper (Epilogue): When you are done with the assignment, fill out the form available at http://bit.ly/151hw2epi to indicate (a) how long the assignment took, (b) what the most challenging part of the assignment was, and (c) something important you learned from doing the assignment. If you find that the assignment took much less or much more time than you expected, also include (d) a note as to what might have led to that difference.
Submitting the main assignment: Email your
answer to <grader-151-01@cs.grinnell.edu>. The title (subject) of
your email should have the form
CSC 151 Assignment 2: Exploring Algorithms and the e-mail
should contain your answers to all parts of the assignment. Scheme
code and your answer for problem 4 should be in the body of the message.
For the Scheme code, you need only submit the
contents of assignment2.rkt.
Warning: So that this assignment is a learning experience for everyone, we may spend class time publicly critiquing your work.
In this assignment, we will work incrementally to build some portions of a program that calculate an overall score from several judges for a diver's performance. In addition, we want the program to work for the scores provided for any diver, so we will generalize the operations with a form of subroutine.
Furthermore, we want the output to be easily readable and meaningful, so we will do some numeric processing to convert the precise scores into something more humanly intelligible.
Finally, swimmers' times will also be measured, and we will need a way to add times together.
So far we have learned that named subroutines take named parameters. While we have not yet learned how to write our own subroutines (procedures), we do have an easy way to import named values from different programs.
Say we define the file contestantA.rkt with the
following contents representing each judge's score for the first contestant.
#lang racket (provide (all-defined-out)) (define judge1 7) (define judge2 10) (define judge3 5) (define judge4 8) (define judge5 6) (define judge6 9) (define judge7 8) (define judge8 6)
If the file assignment2.rkt is saved in the
same folder as contestantA.rkt, we can load the
data and, say, calculate the average of the first two judges' scores
as follows.
#lang racket (require (file "contestantA.rkt")) (/ (+ judge1 judge2) 2)
Running this program would likely produce the following result.
17/2
Of course, that's incomplete as a score. To find the complete score
in a way that is robust to outliers, we will calculate the average
of six judges' scores after dropping the lowest and highest score,
and call it robust-average. The following steps will
help you solve the problem incrementally.
1. Write a definition that assigns the name total-score to
a computed total of all the scores. (That is,
total-score should remain correct, even if we change the
values associated with judge1 through judge8.)
2. Write a definition that assigns the name average-score
to a computed average of the scores by the usual means.
3. Write a definition that assigns the name highest-score
to a computed highest score.
4. Write a definition that assigns the name lowest-score
to a computed lowest score.
5. Write a definition that assigns the name
robust-average to the robust average score (that is,
the score that results from dropping the lowest and highest scores
and then averaging the result).
6. To complete the notion that assignment2.rkt
operates like a subroutine, create a few more contestant files, change
the require statement, and verify that the results you
generate are different and correct.
The averaged scores you may have seen so far may not be all that pretty. Instead of the 22/3 you might get for contestant A, we'd probably prefer 7.3 (which is an approximation of 7.3333333333333..., the decimal representation of 22/3).
You may recall that we have a number of mechanisms for rounding real
numbers to integers, such as ceiling and
floor. But what if we want to round not to an integer,
but to only one digit after the decimal point? Scheme does not
include a built-in operation for doing that kind of rounding.
Nonetheless, it is fairly straightforward.
1. Add instructions to your program that calculate a version of
robust-average rounded to the nearest tenth.
2. Now, let's generalize your instructions to round to an arbitrary number of digits after the decimal point.
Suppose precision is a non-negative integer and
robust-average is the value you computed above.
Write
another set of instructions for rounding robust-average
to use exactly precision digits after the decimal point.
>(your-instructions ... robust-average ... precision ...)
As you write your instructions, you may find the
function useful. expt(expt b p)
computes bp.
The swim team also needs a program to tally the times for members'
events. Suppose the values time-1-min,
time-1-sec, time-2-min, and
time-2-sec represent the times of two swimmers -
swimmer 1 took time-1-min minutes and
time-1-sec seconds and swimmer 2
took time-2-min minutes and
time-2-sec. You can assume that all of these times
are sensible values (i.e., positive integers, with seconds in the range
0 to 59, inclusive).
Write a definition that assigns the names
time-total-min and time-total-sec to the
computed sum of the two times. For example,
if swimmer one took 2 minutes and 15 seconds and swimmer two took
2 minutes and 11 seconds, then the total time is 4 minutes and 26
seconds. Similarly, if swimmer one took 2 minutes and 35 seconds
and swimmer two took 2 minutes and 36 seconds, then the total time
is 5 minutes and 11 seconds. As the second example suggests, you
will need to keep the seconds' sum in a sensible range.
In many of your expressions above, you relied on Scheme's built-in addition operation. But what if Scheme didn't know how to add numbers? We'd have to teach it to do so. Don't worry, we're not going to make you write a Scheme program to add numbers. However, it is useful to think about how you describe addition, say to a species that we discover is sentient, but has never thought about mathematics.
Write English instructions that teach someone how to add two one-digit or two-digit non-negative whole numbers. You should not assume that your audience has any intrinsic understanding of what the numbers represent, although you can ask them to determine whether there is only one digit (e.g., the number 5) or two digits (e.g., the number 42) and to make a choice based on that question. You may assume that your audience knows some basic concepts, such as left and right.
Hint: You may find it easier to start by thinking about how you'd teach someone to add two one-digit numbers.
We will primarily evaluate your work on correctness (does your code compute what it's supposed to and are your procedure descriptions accurate); clarity (is it easy to tell what your code does and how it acheives its results; is your writing clear and free of jargon); and concision (have you kept your work short and clean, rather than long and rambly).