Learn from Prelim 1
If you have done well, congratulations! If you
have not done well, be sure to catch up and then you can show us at the next
exams what you have learned! Remember, Prelim 1 is worth only 20% so you have
plenty of opportunities to improve.
Question 1 (Trace, function scope)
This question was well done overall. Good Job!
Question 2 (Linear interpolation, iterating
through a vector, adjacent vector elements and keeping vector indices within
range)
Part (a): Most students recognized that the loop needed to stop after c
iterations since a vector of length c needs to be created, including the
endpoints a and b.
Most students also saw the need for some sort of stepsize or fraction variable
(delta or frac in the solutions) to either add to the left
endpoint a or to weight the endpoints a and b
in order to compute each value needed in the vector. One of the most common errors was
forgetting that if there are c points to be distributed on the number line,
there are c-1 intervals between the points. Whether you think of this problem as
the weighted sums of the two endpoints a and b (example
solution 1) or as moving in steps of a calculated fixed size across the interval
starting from a (example solution 2), it is key to consider
c-1 intervals. Finally, built-in functions were NOT allowed in this part of
the question; please be sure to read exam questions carefully.
Part (b): For a vector to be perfect or imperfect, every element in the
vector had to differ by no more than 5 from its neighbors. You can't tell that a vector
is perfect until after you have checked all the adjacent elements. A common
mistake was to print 'perfect' or 'imperfect' after every comparison between two
elements, before going working through the vector or finding the first difference greater
than 5. You should keep track of whether the whole vector is perfect, e.g., by finding
the first difference greater than 5, and print once at the end of the program.
Students did a good job realizing that a loop should be used to move through the
positions in the vector. The most efficient way to solve this problem recognizes
that once two elements are found that differ by more than 5, the whole vector is
imperfect and there is no need to continue checking subsequent elements of the vector.
To allow the loop to end early before reaching the end of the vector, when a pair
difference greater than 5 is found, you need a while loop with two continuation
criteria: the current index has not exceeded the length of the vector and the current
pair being checked has a difference no greater than 5.
Question 3 (Iterating over a vector, accumulation
and “best-so-far” patterns, if-construct)
- Students generally did a great job with part (a) and recognized that it was
important to initialize a variable to hold the maximum height so far, and then
update that value as appropriate (conditional) as each element of the vector h
is examined using a for-loop.
- Many students did well on part (b) as well, correctly using an if-statement
to identify the different cases (ranges of height). Some students dealt with the
sampling rate, which was the the number of samples per minute, incorrectly--the rate
already was per-minute so there was no need divide by
k (the number
of minutes).
- A few students used a while-loop to iterate over the height vector, continuing
while
h(k) was in some particular height range. The problem with this
approach is that all the values in the height vector might not be examined, since the
loop stops once a height value outside that range is found--but the remaining values
in the vector could still contain height values that are within the range of interest.
- The simplest method is to use a for-loop that iterates over the whole
height vector and checks the height at each time k, and then accumulates the
appropriate number of samples depending on that value of h(k) and whether or not
the velocity was greater than 110--see the example solution for this approach.
- Some students chose to use a while-loop but forgot to increment the loop variable,
which would lead to an infinite loop! Remember this: if you use a while-loop,
the loop condition should depend on some variable that will
be updated and eventually change to a value that would cause the loop to stop.
For example, if we use a loop that iterates while k < 10 (assuming k is initialized
to 1, for instance), we must remember to increment k on each iteration of the loop
(with a statement like k = k+1) so that the loop will eventually stop.
Question 4 (Generating random integers and real
numbers, indefinite iteration, function and function call)
Part (a):
Most students correctly generated a random real number in the specified range;
the integer part was more challenging. To deal with maxI, which was
a multiple of 10, some students subtracted 10 (which was wrong) instead
of dividing by 10. (If one really wants to subtract then one must subtract
repeatedly in order to be correct.) The posted solution shows a 1-statement
solution for this part, but other reasonable methods are acceptable. For example,
some students made a vector of the candidate values, generated a random integer in
the index range of the vector, and then used that random index to extract a value.
A solution that repeatedly generates a random integer in the range of [1..maxI]
until one that is a multiple of 10 is found is way too inefficient and a point was
deducted for that. You should know this about rand: it generates a
random real value in the range of 0 to 1, excluding 0 and excluding 1.
Part (b)
- Algorithm: a single while-loop does it. Some students used a
while-loop and a for-loop to keep track of the amount of water and
the number of time steps, respectively. This is incorrect. Remember
that when you have nested loops, at each value of the outer loop,
you do all the specified iterations of the inner loop. So if you use
an outer loop for water and an inner loop for time steps, then you are
saying, at some current amount of water, do all the steps, then at
the next amount of water, do all the steps, and so on. This is incorrect.
Instead, use a single while-loop with two continuation conditions, one
for the amount of water and the other for the number of steps.
- Many students got the big idea that you had to write multiple if/else conditions
to check each case separately. Also, nearly all knew that they had to generate a
random number in (0,1) to determine which condition is appropriate. Some, however,
generated a different random number for each case which is incorrect.
- In determining the water storage at each time step, some students forgot to
subtract the smaller value between the storage amount and the requested amount,
which led to a negative storage amount--wrong--in vector
S (if the
simulation stopped because too big a water release request was made). Another
common mistake was forgetting to update w, the current
storage, in addition to assigning S(k).
- Finally, consider simplifying (shortening) your code in conditional statements.
Instead of updating the storage amount under each condition, one could update it
AFTER all branches of the if-statement.
Question 5 (nested loops and grid pattern)
Most students recognized that nested loops could be used to lay out the grid
pattern (as seen in Projects 2 and 3). Most students also were successful in
choosing black versus white disks by writing correct boolean expressions that
check for the four edge cases. Some students miscalculated the number of
columns of disks.
The most difficult part of the problem was how to deal with a number of
disks that doesn't form a full grid. A number of approaches can be used to solve
the problem, the simpler (and more commonly used) approaches are
- Loop over the full grid including the spaces where there should be no disk;
keep track of how many disks have been drawn so far; draw a disk only if the
number of disks so far is less than or equal to
nd.
- Use nested loops to draw a full grid of disks in all but the last column,
followed by a single loop to draw just the disks that should be in the last column.
Another common error is in the caculation of the coordinates.
Break down long calculations into parts to more easily reason
about (and check) the result; i.e., you can reason about the individual parts
separately in order to understand whether the whole (the combination) is correct.
For the calculation of x and y (coordinates of the center of a disk), one can break
each calculation into two parts:
- the calculation of the y increment, i.e., the separation between the
CENTERS of two adjacent disks. This amount is 2 times the radius
ra
plus the gap g. Similarly you can determine the x increment.
- the calculation of the coordinate y, which would be some multiple of
the y increment determined in part 1. So in this part you focus on finding the
correct multiple.
Another approach is to start at some initial y value and then increase y
by the y increment calculated in part 1 after drawing each
disk. Again, deal wih the x value similarly. With this approach,
don't forget to reinitialize at the beginning of each column
(or row).
Statisics
Max: 100
Median: 84
Mean: 81.1
S.Dev: 15.0
% Given yourScore, action to take after prelim ...
if yourScore > 88
toDo= celebrate + later look at the solution
elseif yourScore > 73
toDo= redo problems + later check solution
else
toDo= meet with course staff to go over exam ...
+ stay caught up from now on ...
+ do NOT just read the solution--must redo problems
end