Problem #1
solution
Method Call Output Produced
------------------------------------------------
mystery(9); =9
mystery(42); 24=
mystery(703); 30=7
mystery(5821); 12=58
mystery(83105); 013=85
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
solutions
public static int weave(int x, int y) {
if (x < 0 || y < 0) {
throw new IllegalArgumentException();
}
if (x == 0 && y == 0) {
return 0;
} else {
return 100 * weave(x / 10, y / 10) + 10 * (x % 10) + y % 10;
}
}
public static int weave(int a, int b) {
if (a < 0 || b < 0) {
throw new IllegalArgumentException();
}
if (a < 10 && b < 10) {
return a * 10 + b;
} else {
return weave(a / 10, b / 10) * 100 + weave(a % 10, b % 10);
}
}
ways to test if a non-negative integer x is a 1-digit number:
x < 10
x / 10 == 0
x % 10 == x
1 header
2 exception
1 reasonable attempt
1 correct
5 base case
1 reasonable attempt to test x or y for 0 or 1-digit
1 reasonable attempt to test x and y for 0 or 1-digit
2 correct test: either both 0 or both 1-digit or equivalent
1 correct return (requires correct test):
if (x == 0 && y == 0) { return 0; }
if (x < 10 && y < 10) { return 10 * x + y; }
note: -1 from correctness if there are extra base cases that don't work
7 recursive case
6 correct expression elements:
100 * weave(x / 10, y / 10) + 10 * (x % 10) + y % 10;
+---+ +-------------------+ +--+ +------+ +----+
1 2 1 1 1
1 pieces fit together:
* this is in an else branch relative to a base case or has a test that
makes some kind of sense
* they are adding together at least 2 of these elements
* they are returning the sum of the elements they are adding together
* no extraneous code or other recursive cases that don't work
notes:
* All loop, extra data structure, string solutions go to question leader.
* If they have 2 or more recursive cases, give them the max of the "correct
expression elements" rather than the sum
Problem #3
Statement Output
------------------------------------------------------------
var1.method1(); Cat 1
var2.method1(); Bell 1/Candle 1
var3.method1(); Bell 1/Candle 1
var1.method2(); Candle 2/Cat 1
var2.method2(); Book 2
var3.method2(); Candle 2/Bell 1/Candle 1
var4.method2(); compiler error
var5.method2(); Candle 2/Cat 1
var6.method2(); Book 2
var1.method3(); compiler error
var2.method3(); Book 3
var3.method3(); compiler error
((Cat)var5).method3(); Cat 3
((Bell)var1).method3(); compiler error
((Bell)var4).method1(); runtime error
((Cat)var1).method3(); Cat 3
((Candle)var4).method1(); Candle 1
((Book)var5).method3(); runtime error
((Bell)var6).method3(); compiler error
((Candle)var4).method2(); Candle 2/Candle 1
1 pt each
-1 if no slashes anywhere
-0 if they put quotes around answers
Problem #4
before after code
-----------------------+-----------------------+-------------------------------
p->[1] | p->[1]->[3] | p.next = q.next;
| | q.next = null;
q->[2]->[3] | q->[2] |
-----------------------+-----------------------+-------------------------------
p->[1] | p->[2]->[1] | ListNode temp = p;
| | p = q;
q->[2]->[3] | q->[3] | q = q.next;
| | p.next = temp;
-----------------------+-----------------------+-------------------------------
p->[1] | p->[1]->[3] | p.next = q.next;
| | q.next.next.next = q;
q->[2]->[3]->[4] | q->[4]->[2] | q = q.next.next;
| | q.next.next = null;
| | p.next.next = null;
-----------------------+-----------------------+-------------------------------
p->[1]->[2] | p->[2]->[4] | p.next.next = q.next;
| | q.next.next.next = q;
q->[3]->[4]->[5] | q->[5]->[3]->[1] | q.next = p;
| | q = p.next.next.next;
| | p = p.next;
| | p.next.next = null;
| | q.next.next.next = null;
-----------------------+-----------------------+-------------------------------
2 problem 1
1 attempt: change 2 of (2 ~.next)
1 correct
3 problem 2
1 attempt: change 2 of (p, q, 1 ~.next)
2 correct
4 problem 3
1 attempt: change 3 of (q, 4 ~.next)
1 better attempt: change all 5 of (q, 4 ~.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
solutions
// shifting loop going forwards, decrementing size, decrementing i
public void removeAll(int n) {
for (int i = 0; i < size; i++) {
if (elementData[i] == n) {
for (int j = i; j < size - 1; j++) {
elementData[j] = elementData[j + 1];
}
size--;
i--;
}
}
}
// shifting loop going forwards, decrementing size, if/else for i
public void removeAll(int n) {
int i = 0;
while (i < size) {
if (elementData[i] == n) {
for (int j = i + 1; j < size; j++) {
elementData[j - 1] = elementData[j];
}
size--;
} else {
i++;
}
}
}
// nice O(n) solution that moves values not equal to n earlier in array
public void removeAll(int n) {
int newSize = 0;
for (int i = 0; i < size; i++) {
if (elementData[i] != n) {
elementData[newSize] = elementData[i];
newSize++;
}
}
size = newSize;
}
// shifting loop going backwards, handles 2-in-a-row even with count
public void removeAll(int n) {
int count = 0;
for (int i = size - 1; i >= 0; i--) {
if (elementData[i] == n) {
for (int j = i; j < size - 1; j++) {
elementData[j] = elementData[j + 1];
}
count++;
}
}
size -= count;
}
1 header (non-void return type okay if consistent with a return)
3 finding values to be removed
1 loop attempt: within OBOB of examining size values or all values
1 loop with correct bounds
1 test whether elementData[i] == target value
6 correctly removes values with an inner loop
1 reasonable attempt to shift a new value into elementData[i] (doesn't
require a loop)
1 inner loop that correctly shifts if array has excess capacity (correct
bounds, pieces fit together)
1 reasonable attempt to reset size for values it finds
1 inner loop works correctly when array is full and resetting of size is
done correctly (resets size in this case and only this case and in a way
that causes the outer loop to examine one fewer element)
2 correctly handles the two-in-a-row case (as in i-- or while/if/else)
Notes: -3 if they use an extra structure (array, ArrayList, etc)
single loop solutions that might work graded separately
Problem #6
solution
public void makeSortedSequence(Queue q) {
Stack s = new Stack();
if (!q.isEmpty()) {
int last = q.remove();
s.push(last);
int oldSize = q.size();
for (int i = 0; i < oldSize; i++) {
int next = q.remove();
if (next < last) {
q.add(next);
} else {
s.push(next);
last = next;
}
}
while (!q.isEmpty()) {
s.push(q.remove());
}
while (!s.isEmpty()) {
q.add(s.pop());
}
while (!q.isEmpty()) {
s.push(q.remove());
}
while (!s.isEmpty()) {
q.add(s.pop());
}
}
}
1 header (non-void return okay if consistent, static is okay)
2 constructs temporary stack using generics correctly (-1 per error)
3 basic loops (generous)
1 a loop that goes q->s and a later loop that goes s->q
1 a later loop that goes q->s
1 a later loop that goes s->q
3 correctly handles first value and empty queue
1 special test for empty queue (loop test is not enough) so that the method
does nothing in that case and doesn't throw an exception
1 reasonable attempt to remove first value and store it in a variable
1 correctly removes first value, stores it in a variable, and places it
where the sequence goes (either to the stack or the end of the queue)
note: they get these points if they initialize last to Integer.MIN_VALUE
and don't generate an exception for the empty list
1 one of their loops over the queue makes a reasonable attempt to send some
values to the stack and some values to the end of the queue
5 correctly identifies the sequence
1 reasonable attempt to see if next value is greater than or equal to the
last sequence value (not enough to test adjacent values)
2 they are looping over the queue using the old size value so that they
know when to stop or equivalent (-1 if OBOB)
2 pieces fit together for their code to correctly identify the sorted
sequence and to process each value of the queue exactly once (requires
that they are removing one value at a time from the queue and correctly
updating a previous value, but no double jeopardy with processing of
first value and using size instead of old size; -1 if minor error like
greater-than versus greater-than-or-equal)
10 combination of stack/queue loops leads to correct sequence (requires that
they have a loop over the queue that reads one value at a time and sends
that value either to the stack or to the end of the queue...fix errors they
have already lost points for). Simulate this case:
front [100, 1, 200, 2, 300, 3, 400, 4] back
10 [100, 200, 300, 400, 1, 2, 3, 4] F1 F2
8 [4, 3, 2, 1, 400, 300, 200, 100] R2 R1
6 [1, 2, 3, 4, 100, 200, 300, 400] F2 F1
4 [400, 300, 200, 100, 4, 3, 2, 1] R1 R2
4 [4, 3, 2, 1, 100, 200, 300, 400] R2 F1
2 [400, 300, 200, 100, 1, 2, 3, 4] R1 F2
2 [100, 200, 300, 400, 4, 3, 2, 1] F1 R2
2 [1, 2, 3, 4, 400, 300, 200, 100] F2 R1
Notes:
-3 from the 10 correctness points if it isn't O(n)
no parens for calls like q.remove() is a syntax mistake (could be free)
naming errors where you can infer what they meant are -1 each, max -2:
while (!s.isEmpty()) { q.add(s.remove()); }
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
Stuart Reges
Last modified: Fri Sep 16 16:16:07 PDT 2011