The correct answer is (a). I will first show that (the if direction), and then I will show that these are the only xs that work (the only if direction). The book gives a reasonable demonstration that the formula holds for 0 < x < 1, so I will take that as a given. When x = 0 we have:
By definition, we know that 0a = 0 for any number a, so all terms but the first are zero. The first term is just the empty product (which can also be written )--a product of zero numbers--which is defined to be the multiplicative identity, 1 (similarly the empty sum, , is defined to be the additive identity, 0). Thus,
Now spose -1 < x < 0. Then
It remains to show that the formula is false for values of x not in the interval (-1,1). Spose x > 1. Then all terms in the series are positive and non-decreasing, thus the series cannot converge to the finite (and negative) value 1/(1-x). If x < -1 then the series can be rewritten as . Each term is positive and non-decreasing, and the quantity (1+x) is finite and non-zero, so again the series cannot converge to the finite value 1/(1-x). Now we have two special cases: . If x = 1 then clearly the series diverges to . If we defined , then the formula would be true in this case, but we don't. As Steve said in class, and ``undefined'' are not the same. If x = -1 then the partial sums of the series alternate between 1 and 0. So the average value is 1/2 = 1/(1-(-1)), but the series doesn't converge so the formula doesn't hold.
Which of the following formulas has the smallest value?
Just FYI:
Using the same rule again, we get:
2 (25+1) + 5 = 128 + 5 = 133
So, letter (e) is the smallest.
.
So, letter (a) is the greatest.
Note: I am including two versions of (a) in the solutions to reflect the original (a1) and updated (a2) versions of the homework. As written on the quiz, (a) was not a correct answer. The five people who answered (a) should pay special attention to this solution because, due to an error on our part, they were not required to redo this problem on their homework.
Choices (a1), (b) and (d) evaluate to a3 + 4ab2 while (a2) and (c) do not. Hence (a2) and (c) are the two correct answers.
Which of the following does not equal 1?
Note: The expressions ought to have been parenthesized for clarity, as shown above. The proper way to think about ``mod'' (from a theory standpoint) is as a mode or environment, rather than as a function. Thus in parts (a) and (d) we are dealing with the ring of integers modulo 2 (which just has two elements), in parts (b) and (c) we are dealing with the ring of integers modulo 10 (10 elements), and in part (e) we are dealing with the ring of integers modulo 1999 (you guessed it--1999 elements). In the solutions below I will use to denote equivalence modulo M.
Thus (b) and (e) are the two choices which are not equivalent to 1.
I don't think this one really needs much of a solution. The answer, of course, is (e). Any one of the other choices may be a perfectly valid reason to choose one implementation over the other depending on the situation. As an example, if you know ahead of time how many elements will be in your queue and you are concerned about speed, then it's probably best to use a circular array. If, however, you don't know ahead of time how many elements you will have, or if your memory is too fragmented to hold a large array, then it's probably best to use a linked list.
The following pseudocode uses the functions C, F, and G.
if (C()) { for i = 1 to n for j = 1 to n F() } else { F() G() }
In terms of the runtime of C, F, and G (T(C), T(F), and T(G), respectively) the asymptotic bound on the runtime of this code must be equivalent to which of the following?
There are a few reasonable answers to this. I will use a conservative upper bound based on the sum of the time to evaluate the conditional, the time to evaluate one branch, and the time to evaluate the other branch. The actual running code cannot do more work than this, so it is a valid upper bound.
I'll set up a pair of sums to find out how long the loop takes in the first branch, and add the times for F and G (since they occur in sequence) for the second branch.
Time for conditional = T(C)
Time for first branch
Time for second branch = T(F) + T(G)
All told then, this is O(T(C) + T(F) + T(G) + n2 T(F)), but T(F) is o(n2 T(F)), so we can drop T(F) (but may not drop n2 T(F)). The final time then is O(T(C) + T(G) + n2 T(F)).
Note that any of C, F, and G may read input or access global variables; so, their runtime is not necessarily constant.
if and only if and based on the definition of . So, and and and . There must be some constant c1 such that for sufficiently large N and another (not necessarily equal) constant c2 such that for sufficiently large N. (And the same holds with constants d1 and d2 for .) Now, on to the options:
Notice, however, that if the two functions are equal (or even just have the same coefficient for their high order term) their difference is .
(since ). So, . But, (since ). So, , and, by definition, .
sum = 0; for (i = 0; i < n; i++) for (j = 0; j < i; j++) sum++;
The ``sum++'' line takes constant time, and the loops set up the following formula:
Dropping lower order terms and coefficients, this is . Now, on to the answers:
Pointers to the column and row headers save time traversing through the row and column lists to find those headers, but they take extra space in each node. However, if the data is large to start with, the pointers add very little extra memory requirement to each node. Therefore, an excellent time to use pointers to the headers is when time is precious (because they speed up the cross list), memory is cheap (because they require storage), but the actual information stored at each element is large (because then the memory hit -- which is cheap anyway -- is also relatively small).
for (i = 1; i * i <= n; i++) if (n % i = 0) cout << i << ' '; cout << endl;
The loop repeats as long as or equivalently or . The conditional inside each loop takes constant time whether it executes or not. So, the code takes:
So, only is a tight upper bound on the code.
T(n) = T(n - 1) + n
T(1) = 1
Note: A number of people answered that since we add n things, and each of them is about n, . This is handwaving, and in the future you will need to be a bit more careful to get full marks on a question. Actually (as we'll show), the sum is , and it's not obvious that you can think of this as , particular for a lower bound.
Note 2: A question like this is asking for a proof, so arguing by eliminating the choices that the questions gives is not really sufficient. Also, many people who did this had very vague justifications (e.g. it's ``clearly'' much greater than ).
Here's a solution.
So, after k recursive substitutions of the formula, we get
And after n-1 recursive substitutions (keeping in mind that T(1)=1),
Now, (there's no need to justify this formula, since we just learned it as a fact in class).
Thus, we have
So, (d) is the correct answer. You could get away with a bit less of the english text, and introducing k is not necessary as long as you demonstrate the pattern before going to the formula.
template <class T> class Templ public: T min (T x, T y) { if (x < y) return x; else return y; } };
What can we say about class T?
(a) is correct. If we're comparing X with Y using operator <, then the class T must have that operator defined (technically, as one student pointed out, it could have operator < defined as a friend function.).
We never used == or called a 'less' method, so we can't say that it necessarily has those functions defined.
is true if and only if:
The correct answer is (a). I will first show that (the if direction), and then I will show that these are the only xs that work (the only if direction). The book gives a reasonable demonstration that the formula holds for 0 < x < 1, so I will take that as a given. When x = 0 we have:
By definition, we know that 0a = 0 for any number a, so all terms but the first are zero. The first term is just the empty product (which can also be written )--a product of zero numbers--which is defined to be the multiplicative identity, 1 (similarly the empty sum, , is defined to be the additive identity, 0). Thus,
Now spose -1 < x < 0. Then
It remains to show that the formula is false for values of x not in the interval (-1,1). Spose x > 1. Then all terms in the series are positive and non-decreasing, thus the series cannot converge to the finite (and negative) value 1/(1-x). If x < -1 then the series can be rewritten as . Each term is positive and non-decreasing, and the quantity (1+x) is finite and non-zero, so again the series cannot converge to the finite value 1/(1-x). Now we have two special cases: . If x = 1 then clearly the series diverges to . If we defined , then the formula would be true in this case, but we don't. As Steve said in class, and ``undefined'' are not the same. If x = -1 then the partial sums of the series alternate between 1 and 0. So the average value is 1/2 = 1/(1-(-1)), but the series doesn't converge so the formula doesn't hold.
Note: this question was removed from the quiz and homework.
Which of the following formulas has the smallest value?
Just FYI:
Using the same rule again, we get:
2 (25+1) + 5 = 128 + 5 = 133
So, letter (e) is the smallest.
Which of the following formulas has the greatest value?
.
So, letter (a) is the greatest.
Which of the following is not equal to a3 + 4ab2?
Note: I am including two versions of (a) in the solutions to reflect the original (a1) and updated (a2) versions of the homework. As written on the quiz, (a) was not a correct answer. The five people who answered (a) should pay special attention to this solution because, due to an error on our part, they were not required to redo this problem on their homework.
Choices (a1), (b) and (d) evaluate to a3 + 4ab2 while (a2) and (c) do not. Hence (a2) and (c) are the two correct answers.
Note, this question has two correct answers. If you got either right on the quiz, you were correct. Otherwise, find and justify both for the homework.
Which of the following does not equal 1?
Note: The expressions ought to have been parenthesized for clarity, as shown above. The proper way to think about ``mod'' (from a theory standpoint) is as a mode or environment, rather than as a function. Thus in parts (a) and (d) we are dealing with the ring of integers modulo 2 (which just has two elements), in parts (b) and (c) we are dealing with the ring of integers modulo 10 (10 elements), and in part (e) we are dealing with the ring of integers modulo 1999 (you guessed it--1999 elements). In the solutions below I will use to denote equivalence modulo M.
Thus (b) and (e) are the two choices which are not equivalent to 1.
What is the best way to implement a queue?
I don't think this one really needs much of a solution. The answer, of course, is (e). Any one of the other choices may be a perfectly valid reason to choose one implementation over the other depending on the situation. As an example, if you know ahead of time how many elements will be in your queue and you are concerned about speed, then it's probably best to use a circular array. If, however, you don't know ahead of time how many elements you will have, or if your memory is too fragmented to hold a large array, then it's probably best to use a linked list.
Note, this question has no correct answer on the quiz. You should find and justify the correct answer for homework.
The following pseudocode uses the functions C, F, and G.
if (C()) { for i = 1 to n for j = 1 to n F() } else { F() G() }
In terms of the runtime of C, F, and G (T(C), T(F), and T(G), respectively) the asymptotic bound on the runtime of this code must be equivalent to which of the following?
There are a few reasonable answers to this. I will use a conservative upper bound based on the sum of the time to evaluate the conditional, the time to evaluate one branch, and the time to evaluate the other branch. The actual running code cannot do more work than this, so it is a valid upper bound.
I'll set up a pair of sums to find out how long the loop takes in the first branch, and add the times for F and G (since they occur in sequence) for the second branch.
Time for conditional = T(C)
Time for first branch
Time for second branch = T(F) + T(G)
All told then, this is O(T(C) + T(F) + T(G) + n2 T(F)), but T(F) is o(n2 T(F)), so we can drop T(F) (but may not drop n2 T(F)). The final time then is O(T(C) + T(G) + n2 T(F)).
Note that any of C, F, and G may read input or access global variables; so, their runtime is not necessarily constant.
Given that and which of the following is not true?
if and only if and based on the definition of . So, and and and . There must be some constant c1 such that for sufficiently large N and another (not necessarily equal) constant c2 such that for sufficiently large N. (And the same holds with constants d1 and d2 for .) Now, on to the options:
Notice, however, that if the two functions are equal (or even just have the same coefficient for their high order term) their difference is .
(since ). So, . But, (since ). So, , and, by definition, .
Which of the choices below is a correct upper bound on the running time of this code?
sum = 0; for (i = 0; i < n; i++) for (j = 0; j < i; j++) sum++;
The ``sum++'' line takes constant time, and the loops set up the following formula:
Dropping lower order terms and coefficients, this is . Now, on to the answers:
Under which conditions would you want to store a reference to each row and column header in each element of a cross list?
Pointers to the column and row headers save time traversing through the row and column lists to find those headers, but they take extra space in each node. However, if the data is large to start with, the pointers add very little extra memory requirement to each node. Therefore, an excellent time to use pointers to the headers is when time is precious (because they speed up the cross list), memory is cheap (because they require storage), but the actual information stored at each element is large (because then the memory hit -- which is cheap anyway -- is also relatively small).
What is a tight upper bound on the running time of this code?
for (i = 1; i * i <= n; i++) if (n % i = 0) cout << i << ' '; cout << endl;
The loop repeats as long as or equivalently or . The conditional inside each loop takes constant time whether it executes or not. So, the code takes:
So, only is a tight upper bound on the code.
Which choice below is a tight asymptotic bound for a function with the following runtime characteristics?
T(n) = T(n - 1) + n
T(1) = 1
Note: A number of people answered that since we add n things, and each of them is about n, . This is handwaving, and in the future you will need to be a bit more careful to get full marks on a question. Actually (as we'll show), the sum is , and it's not obvious that you can think of this as , particular for a lower bound.
Note 2: A question like this is asking for a proof, so arguing by eliminating the choices that the questions gives is not really sufficient. Also, many people who did this had very vague justifications (e.g. it's ``clearly'' much greater than ).
Here's a solution.
So, after k recursive substitutions of the formula, we get
And after n-1 recursive substitutions (keeping in mind that T(1)=1),
Now, (there's no need to justify this formula, since we just learned it as a fact in class).
Thus, we have
So, (d) is the correct answer. You could get away with a bit less of the english text, and introducing k is not necessary as long as you demonstrate the pattern before going to the formula.
Given the following templated class:
template <class T> class Templ public: T min (T x, T y) { if (x < y) return x; else return y; } };
What can we say about class T?
(a) is correct. If we're comparing X with Y using operator <, then the class T must have that operator defined (technically, as one student pointed out, it could have operator < defined as a friend function.).
We never used == or called a 'less' method, so we can't say that it necessarily has those functions defined.
What is the flaw in the following inductive proof?