Problem #1
solution
Method Call Output Produced
------------------------------------------------
mystery(7); .7
mystery(246); 642.
mystery(195); .195
mystery(1234); 42.13
mystery(29548); 842.95
3 points for each
lose 1 point for a character of the output that is missing or an extra
character of output or a pair of transposed characters
-0 for quotes around output
Problem #2
solution
public void printPattern(int n) {
if (n < 0) {
throw new IllegalArgumentException();
} else if (n > 0) {
if (n == 1) {
System.out.print(".");
} else if (n / 2 % 2 == 0) {
System.out.print("[");
printPattern(n - 2);
System.out.print("]");
} else {
System.out.print("(");
printPattern(n - 2);
System.out.print(")");
}
}
}
1 header (non-void return is okay if consistent with a return, static is okay)
1 exception: correct test for n < 0 and correct exception being thrown
3 base cases
1 code to print nothing when n is 0 (requires testing structure)
2 code to print a dot when n is 1
4 basic idea: print ()'s or []'s around a recursive call
2 reasonable attempt: print either ()'s or []'s surrounding a recursive
call (print, recurse, print)
2 correct for either ()'s or []'s (requires a call on n-2)
2 have cases for both (looking for parallel code that does print/recurse/print)
1 parallel code for other
1 code matches first (this means, for example, that if they make a call on
n-1 for both, then they get this point)
3 have code for both ()'s and []'s that uses a correct test to distinguish
1 reasonable attempt involving n%4 or n/2 or n%2
2 correct test (examples below)
n / 2 % 2 == 0
n % 4 / 2 == 0
n % 4 == 0 || n % 4 == 1
n % 4 != 2 && n % 4 != 3
n % 4 < 2
1 pieces fit together with no extraneous code and no minor formatting errors
notes:
* Notice that minor formatting issues like print versus println are included in
the final point.
* All loop, extra data structure, string concatenation solutions go to question
leader.
Problem #3
Statement Output
------------------------------------------------------------
var1.method2(); compiler error
var2.method2(); Can 2/Can 3
var3.method2(); Can 2/Lamp 3
var4.method2(); Can 2/Clock 3
var5.method2(); compiler error
var6.method2(); Can 2/Clock 3
var1.method3(); compiler error
var2.method3(); Can 3
var3.method3(); Lamp 3
var4.method3(); Clock 3
var5.method3(); compiler error
var6.method3(); Clock 3
((Lamp)var6).method1(); runtime error
((Can)var1).method1(); compiler error
((Can)var1).method2(); Can 2/Bear 3/Can 3
((Bear)var1).method3(); Bear 3/Can 3
((Bear)var6).method1(); Bear 1
((Clock)var1).method1(); runtime error
((Clock)var4).method2(); Can 2/Clock 3
((Bear)var3).method1(); runtime error
1 pt each
-1 if no slashes anywhere
-0 if they put quotes around answers
Problem #4
before after code
-----------------------+-----------------------+-------------------------------
p->[1]->[2] | p->[1]->[2]->[3] | p.next.next = q;
| | q = null;
q->[3] | q |
-----------------------+-----------------------+-------------------------------
p->[1]->[2]->[3] | p->[1]->[3] | q = p.next;
| | p.next = p.next.next;
q | q->[2] | q.next = null;
-----------------------+-----------------------+-------------------------------
p->[1]->[2] | p->[2]->[3] | p.next.next = q;
| | ListNode temp = p.next;
q->[3]->[4] | q->[1]->[4] | p.next = q.next;
| | q = p;
| | p = temp;
| | p.next.next = null;
-----------------------+-----------------------+-------------------------------
p->[1]->[2]->[3] | p->[3]->[1] | ListNode temp = p.next.next;
| | temp.next = p;
| | q.next.next = p.next;
q->[4]->[5] | q->[5]->[2]->[4] | p.next = null;
| | p = temp;
| | q.next.next.next = q;
| | q = q.next;
| | q.next.next.next = null;
-----------------------+-----------------------+-------------------------------
2 problem 1
1 attempt: change 2 of (q, 1 ~.next)
1 correct
3 problem 2
1 attempt: change 2 of (q, 2 ~.next)
2 correct
4 problem 3
1 attempt: change 3 of (p, q, 3 ~.next)
1 better attempt: change all 5 of (p, q, 3 ~.next)
2 correct
6 problem 4
1 attempt: change 4 of (p, q, 5 ~.next)
1 better attempt: change 6 of (p, q, 5 ~.next)
4 correct
Notes
correctness is generally atomic except:
-1 per "setting to null" error if otherwise correct
-1 per exception thrown if otherwise correct
-1 if adding or subtracting a single ".next" somewhere makes it work
can lose up to 2 syntax points if they get correctness points, examples:
-1 not declaring temp variable to be of type ListNode (categorical)
-1 saying p.next() instead of p.next (categorical)
-1 per occurrence (max of 2) for "p.data" instead of "p" or equivalent
if they construct new list nodes:
-1 if they don't use them
lose all correctness for any subproblem that relies on the new nodes
if they use more than 2 temp variables:
-2 from correctness per subproblem
Problem #5
solution
public static void mirror2(Stack s) {
Queue q = new LinkedList();
while (!s.isEmpty())
q.add(s.pop());
while (!q.isEmpty())
s.push(q.remove());
while (!s.isEmpty())
q.add(s.pop());
for (int i = 0; i < q.size(); i++) {
int n = q.remove();
s.push(n);
q.add(n);
}
while (!s.isEmpty())
q.add(s.pop());
while (!q.isEmpty())
s.push(q.remove());
}
2 header (-1 per error, non-void return okay if consistent, static is okay)
2 constructs temporary queue using generics correctly (-1 per error)
4 loops that go s->q, q->s
2 reasonable attempt
2 correct ignoring bounds issues (-1 if just one mistake like saying
s.remove instead of s.pop)
4 fixed the problem of reverse order with extra s->q, q->s loops
2 reasonable attempt
2 correct ignoring bounds issues (-1 if just one mistake like saying
s.remove instead of s.pop)
4 expanding loop: some loop doubles the number of values
2 reasonable attempt: removing operation paired with 2 adding operations
2 approach can work, for example:
go through q, doing both an enqueue and a push
go through stack, enqueueing each value twice
go through q, adding each value twice
NOT go through stack, doing both an enqueue and a push
note: loop errors like using size() vs oldSize are okay for these points
9 Actually works. Simulate for:
bottom [1, 2, 3] top
score as follows:
9 [1, 2, 3, 3, 2, 1]--correct answer
6 [3, 2, 1, 1, 2, 3]--reverse but swapped
3 [1, 2, 3, 1, 2, 3]--copy but no reverse
3 [3, 2, 1, 3, 2, 1]--copy but both reversed
note: can fix one error for a cost of -2 if approved by the question leader
using size() vs oldSize in a for loop
Give to question leader all solutions that involve:
peek, foreach loop, iterator, or other illegal stack/queue operations
constructing a temporary structure other than a queue (e.g., a 2nd stack)
nonworking solution that gets 25 points
Problem #6
solutions
public void removeRange(int start, int stop) {
if (start < 0 || stop > size || start > stop) {
throw new IllegalArgumentException();
}
int delta = stop - start;
for (int i = stop; i < size; i++) {
elementData[i - delta] = elementData[i];
}
size -= delta;
}
public void removeRange(int start, int stop) {
if (stop - start < 0 || stop > size || start < 0) {
throw new IllegalArgumentException();
}
int newSize = start;
for (int i = stop; i < size; i++) {
elementData[newSize] = elementData[i];
newSize++;
}
size = newSize;
}
1 header (non-void okay if there is a return that is consistent)
2 exception
1 reasonable attempt
1 correct (all three cases, okay if extra case start==size)
5 loop
1 for loop using size or elementData.length
1 correct # of iterations: size - stop
3 correct copy
1 attempt: elementData[i] = elementData[j]
2 correct: alignment and delta
* alignment--first i is correct: elementData[start]
* delta is correct: j - i = stop - start
2 update size
1 attempt
1 correct (assuming # of iterations was correct)
Correct copying:
for (int i = 0; i < size - stop; i++)
elementData[i + start] = elementData[i + stop];
for (int i = stop; i < size; i++)
elementData[i - stop + start] = elementData[i];
int delta = stop - start;
for (int i = stop; i < size; i++)
elementData[i - delta] = elementData[i];
Notes: -3 if they use an extra structure (array, ArrayList, etc)
Problem #6
solutions
public void removeRange(int start, int stop) {
if (start < 0 || stop > size || start > stop) {
throw new IllegalArgumentException();
}
int delta = stop - start;
for (int i = stop; i < size; i++) {
elementData[i - delta] = elementData[i];
}
size -= delta;
}
public void removeRange(int start, int stop) {
if (stop - start < 0 || stop > size || start < 0) {
throw new IllegalArgumentException();
}
int newSize = start;
for (int i = stop; i < size; i++) {
elementData[newSize] = elementData[i];
newSize++;
}
size = newSize;
}
1 header (non-void okay if there is a return that is consistent)
2 exception
1 reasonable attempt
1 correct (all three cases, okay if extra case start==size)
5 loop
1 for loop using size or elementData.length
1 correct # of iterations: size - stop
3 correct copy
1 attempt: elementData[i] = elementData[j]
2 correct: alignment and delta
* alignment--first one correct: elementData[start]
* delta is correct: stop - start
2 update size
1 attempt
1 correct (assuming # of iterations was correct)
Correct copying:
for (int i = 0; i < size - stop; i++)
elementData[i + start] = elementData[i + stop];
for (int i = stop; i < size; i++)
elementData[i - stop + start] = elementData[i];
int delta = stop - start;
for (int i = stop; i < size; i++)
elementData[i - delta] = elementData[i];
Notes: -3 if they use an extra structure (array, ArrayList, etc)
-1 if they use elementData.length instead of size
4 setting middle range (sublist part)
int delta = stop - start;
for (int i = stop; i < size; i++)
elementData[i - delta] = elementData[i];
for (int i = stop; i < size; i++) {
elementData[i - stop + start] = elementData[i];
for (int i = from; i < to; i++)
result[i + list.length - to - from] = list[i];
1 reasonable attempt:
* separate loop or if/else branch for this case
* assignment and/or index range indicates that they are solving this
part of the problem (must be copying from list to result)
1 correct number of iterations: to - from
Stuart Reges
Last modified: Fri Sep 16 16:16:07 PDT 2011