To do:
Don't cheat. For programming assignments, this means: write your own code. Do not share even one line of code with another person, do not turn in even one line of code written by someone else, or based on code written by someone else!
For written homework assignments, this means: write up your solutions by yourself.
In the past, many cs141 students have been caught cheating. Generally they have been flunked, some have been suspended from school.
Collaboration is encouraged. In some areas of the course you may be at the bottom of a learning curve. This can be an uncomfortable place to be. The way out is: Get engaged with the ideas. Discuss the ideas and the problems with other people. As in learning a new language, recognize that progress takes practice and time.
Prove that for any two positive integers i and j with i < j, the g.c.d. of i and j-i is less than or equal to the g.c.d. of i and j.
This course has two separate parts:
algorithm | implementation |
---|---|
An algorithm is a high-level but complete specification of a method for solving a problem. Examples include mergesort, bubblesort, quicksort. You can specify an algorithm in pseudo-code if you like. Algorithms can be analyzed for correctness (does the algorithm give the right output for all inputs?) and asymptotic worst-case running time. (e.g. "given a list of n elements, in the worst case quicksort runs in time proportional to n"). |
language (C++, python, java, ...)
"getting the machine to do what you want" interpreting compiler error messages particular machine software design issues debugging coding skills Programs can be analyzed for correctness (is the program a faithful implementation of the algorithm, does it have bugs) and running time (e.g. "is it possible to speed up the program by a factor of two by recoding a particular section"). |
Lectures, recitation sections, written hwks, quizzes, and exams will be about algorithms. Second-half of labs will be about programming (C++).
1. Define the problem. Say precisely what the input is, and what the output should be for a given input.
2. Describe an algorithm --- a high-level, but complete description of how to process the input to produce the output.
3. Verify that your algorithm is correct, that on every possible input, the algorithm produces the correct output.
4. Determine the worst-case running time.
You want a correct algorithm with a reasonably fast running time.
Problem: greatest common divisor
A positive integer d is a divisor of a positive integer i if d divides i evenly. The greatest common divisor of i and j is the largest integer that evenly divides both i and j.
Algorithm 1:
gcd1(i,j) (assumption: i and j are positive integers) for k = 1 to i do: if int(i/k)*k = i and int(j/k)*k = j: then g = k return g
correctness: Easy to verify.
running time: Easy to see that it takes time proportional to i.
gcd2(i,j) if i == 1 or j == 1: return 1 if i == j: return i if i < j: return gcd2(i, j-i) else: return gcd2(i-j, j)
correctness: First, does the algorithm terminate? Yes, because max(i,j) decreases with each recursive call.
Next, does it always give the right output? Not so obvious.
Claim: if i < j, then the g.c.d. of i and j equals the g.c.d. of i and j-i.
Proof: divide into two parts:
From the claim, and the fact that the algorithm terminates, the correctness of the algorithm follows.
Some comments about /Proofs .
running time: The running time varies quite a bit, depending on i and j. For example, gcd2(i,2i) makes only a couple of recursive calls.
So let's consider the worst-case time. We already know that the number of recursive calls is at most max(i,j). Since each call requires a constant number of operations (other than the recursive part), this means that the total time is at most proportional to max(i,j).
On the other hand, gcd(i,2) makes i/2 calls. So the worst-case time is at least proportional to max(i,j).
We conclude that the worst-case time is proportional to max(i,j). This is no better than algorithm 1!!!
Continued in /Lecture2 .