Problem #1
Expression Value
---------------------------------------------------
38 % 10 / 3 + 5/3 3
23.0 / 2 - 3 * 0.25 10.75
8 - 3 + "=" + 8 / 3 + 8 + 3 "5=283"
(34 / 10 * 2.0 + 5) / 2 5.5
5 % 8 + 8 % 5 - 17 % 4 7
1 point each, type has to match (2.0 vs 2, using quotes for string)
-------------------------------------------------------------------------------
Problem #2:
Original List Final List
--------------------------------------------------------------
{2, 3, 1} {2, 1, 1}
{2, 6, 5, 2} {2, 4, 1, 2}
{3, 9, 7, 9} {3, 6, 1, 9}
{2, 4, 5, 6, 8} {2, 2, 3, 3, 8}
{1, 5, 8, 4, 8, 9} {1, 4, 4, 4, 4, 9}
2 points for each answer
-1 for each wrong number
-1 for each missing number
any given answer can't go negative
-------------------------------------------------------------------------------
Problem #3:
b d d b
b 1 a 1 b 1 b 1
c 2 a 2 c 2 b 2
1/2 point each, round up their score
-1 if columns and/or rows are labeled but in the right order
-2 if columns and/or rows are labeled and in the wrong order
-1 per extra column or row (max -2)
-1 if two columns transposed or two rows transposed
-2 if you need to transpose twice
-2 if rows and columns are transposed
-0 for quotes or lack of spaces or capital letters
-0 for solid lines between that separate columns or rows
-------------------------------------------------------------------------------
Problem #4
Solution:
public static void reportRunningSum(Scanner input) {
double sum = input.nextDouble();
double max = sum;
System.out.print("running sum = " + sum);
while (input.hasNextDouble()) {
sum += input.nextDouble();
System.out.print(" " + sum);
if (sum > max) {
max = sum;
}
}
System.out.println();
System.out.println("max sum = " + max);
}
1 header (non-void return type ok if consistent with a return statement)
1 correct while loop (while hasNextDouble)
4 computing running sums
1 reasonable attempt to initialize sum and to update inside the loop
(either one completely correct or both partly correct)
1 correctly initializes sum and updates inside the loop
1 attempt at printing sums (requires loop)
1 correct printing of sums (print leading text before loop, print next
value inside loop, println after loop, spaces between numbers, all
numbers printed exactly once)
4 computing max sum
2 initialize sum to first value or equivalent
1 attempt to update max inside loop and print max after loop (either one is
completely correct or both are partly correct)
1 correct update and printing of max (requires loop, must be println)
-------------------------------------------------------------------------------
Problem #5
Solution:
public static void reportBlankLines(Scanner input) {
int line = 0;
int count = 0;
while (input.hasNextLine()) {
String text = input.nextLine();
line++;
if (text.length() == 0) {
System.out.println("line " + line + " is blank");
count++;
}
}
System.out.println("total blank lines = " + count);
}
1 header (non-void return type ok if consistent with a return statement)
1 correct while loop (while hasNextLine)
1 reads a line using nextLine() and either stores it or immediately tests it
for empty string (doesn't have to be a correct test for this point)
2 counter to keep track of line number
1 attempt
1 correct
2 report each blank line
1 attempt
1 correct (requires correct test: line.length()==0 or line.equals(""))
2 reports total number of blank lines
1 attempt (requires 2 of: initialize counter, properly increments counter,
prints value of counter after loop)
1 correct
-------------------------------------------------------------------------------
Problem #6
Solutions:
public static void switchPairs(int[] list) {
for (int i = 0; i < list.length - 1; i += 2) {
int temp = list[i];
list[i] = list[i + 1];
list[i + 1] = temp;
}
}
public static void switchPairs(int[] list) {
for (int i = 0; i < list.length; i++) {
if (i % 2 == 1) {
int temp = list[i];
list[i] = list[i - 1];
list[i - 1] = temp;
}
}
}
1 header (non-void return type ok if consistent with a return statement)
4 loop that accesses each pair
1 reasonable attempt to loop over array (some for loop over array length)
1 code in loop accesses pairs: list[i]/list[i+1] or list[i]/list[i-1]
2 combination of loop bounds, loop update, and any test leads the loop to
access each of the n pairs for an array of length 2n once (-1 if obob)
3 swaps each pair for even length
1 reasonable attempt to swap two array elements
1 correctly swaps two array elements
1 pieces fit together: loop and swapping code manages to swap each adjacent
pair in an array of length 2n (no double jeopardy with minor loop
problems that they lost points for previously)
2 works for odd length
1 reasonable attempt to deal with extra value that is not part of a pair
1 correctly avoids treating the extra value as part of a pair
Note: ArrayList solutions and solutions that construct an extra structure like
a temp array go to the question leader.
-------------------------------------------------------------------------------
Problem #7
Solutions:
// inserting evens earlier in the list
public static void oddsToBack(ArrayList list) {
int lastEven = -1;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) % 2 == 0) {
int n = list.remove(i);
lastEven++;
list.add(lastEven, n);
}
}
}
// moving odds to the end, remembering a count of odds
public static void oddsToBack(ArrayList list) {
int odds = 0;
for (int i = 0; i < list.size() - odds; i++) {
if (list.get(i) % 2 != 0) {
int n = list.remove(i);
list.add(n);
i--;
odds++;
}
}
}
// keeping track of how many values to process and decrementing it for each
// odd that has been moved to the end
public static void oddsToBack(ArrayList list) {
int size = list.size();
for (int i = 0; i < size; i++) {
if (list.get(i) % 2 != 0) {
int n = list.remove(i);
list.add(n);
i--;
size--;
}
}
}
canonical bad strategy but otherwise correct solution:
public static void oddsToBack(ArrayList list) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) % 2 != 0) {
list.add(list.get(i));
list.remove(i);
// adding i-- fixes 2-in-a-row, but leads to infinite loop
}
}
}
1 header (return type ok if consistent with a return statement, parameter must
be ArrayList)
2 loop to access list elements
1 attempt (loop using list.size() or list.length() or list.length)
1 correct (list.size(), no obob)
4 moving odd/even values
1 reasonable attempt to test for odd/even (array notation okay)
1 either a reasonable attempt to add the value to an appropriate spot in
the list (moving it earlier for evens, later for odds) or a reasonable
attempt to remove the value based on a test (single call on set is okay)
1 both a reasonable attempt to add the value to an appropriate spot in
the list (moving it earlier for evens, later for odds) and a reasonable
attempt to remove the value based on a test (calls on set not okay)
1 all three of these are correct (array notation NOT okay, don't worry for
this point about whether there is an error in where they add values back
to the list as long as evens go earlier and odds go later)
3 correct strategy for moving values that doesn't miss any values and that
doesn't go into an infinite loop
1 reasonable attempt (either process backwards or have a second counter or
decrement loop counter when they have found a value to move)
2 correct (doesn't miss 2 in a row, doesn't go into an infinite loop,
preserves relative order of odds/evens, pieces fit together; -1 for minor
error like OBOB)
Notes:
Saying list.size without parens or using brackets on method calls (list.get[i],
list.remove[i]) are syntax mistakes. They get one free syntax mistake, max -2
for syntax.
-2 for calling set/add/get/remove without saying "list." (only apply this rule
if their score goes up)
extra data structure goes to question leader
Problem #8
Solution:
public class Iguana extends Critter {
private Random r;
private String display;
private int count;
public Iguana() {
r = new Random();
display = "<->";
}
public Action getMove(CritterInfo info) {
count++;
if (info.getFront() == Neighbor.OTHER) {
display = "";
return Action.INFECT;
} else {
int flip = r.nextInt(2);
if (flip == 0) {
display = "";
return Action.LEFT;
} else {
display = "";
return Action.RIGHT;
}
}
}
public Color getColor() {
if (count % 2 == 0) {
return Color.BLUE;
} else {
return Color.RED;
}
}
public String toString() {
return display;
}
}
1 class header
4 declaring fields and constructor
1 field to count moves (declared, incremented somewhere)
1 field for storing last move (declared, used somewhere)
1 field for Random object (declared, used somewhere)
1 they have a constructor with a correct header that correctly initializes
a Random object and that includes any other initialization to non-default
values
4 toString
1 correct header and returns "<->" initially
3 changes correctly after getMove is called
1 attempt: returns a value that is based on a field that they are
trying to use to record the last move
2 correct: field is updated correctly ( for INFECT, for LEFT,
for RIGHT)
4 getMove
1 header
1 has cases for returning INFECT, LEFT, RIGHT
2 correct move (INFECT when enemy in front, otherwise randomly choose
between LEFT and RIGHT, -1 if close)
2 getColor
1 reasonable attempt to return either Color.RED or Color.BLUE
1 all correct (correct header, starts with blue, use a counter or
equivalent that is updated once per move to switch)
notes:
-1 if they have code after a return (e.g., setting a field)
-1 if any field is not private
-1 if they update any fields outside of getMove
-1 if they make a field static
-------------------------------------------------------------------------------
Problem #9
Solutions:
public static int[] splitPairs(int[] list) {
int half = list.length / 2;
int[] result = new int[list.length];
for (int i = 0; i < list.length; i++) {
if (i % 2 == 0) {
result[i / 2] = list[i];
} else if (list.length % 2 == 0) {
result[i / 2 + half] = list[i];
} else {
result[i / 2 + half + 1] = list[i];
}
}
return result;
}
public static int[] splitPairs(int[] list) {
int half = list.length / 2;
int[] result = new int[list.length];
for (int i = 0; i < list.length; i++) {
if (i % 2 == 0) {
result[i / 2] = list[i];
} else {
result[i / 2 + half + list.length % 2] = list[i];
}
}
return result;
}
public static int[] splitPairs(int[] list) {
int half = list.length / 2;
int[] result = new int[list.length];
for (int i = 0; i < half; i++) {
result[i] = list[2 * i];
}
if (list.length % 2 == 1) {
result[half] = list[list.length - 1];
half++;
}
for (int i = half; i < list.length; i++) {
result[i] = list[2 * (i - half) + 1];
}
return result;
}
public static int[] splitPairs(int[] list) {
int[] result = new int[list.length];
int j = 0;
for (int i = 0; i < list.length; i+= 2) {
result[j] = list[i];
j++;
}
for (int i = 1; i < list.length; i+= 2) {
result[j] = list[i];
j++;
}
return result;
}
1 header
2 constructing a new int array of appropriate size
1 attempt (construct some new array mostly ignoring syntax)
1 correct (array of int, size correct)
4 copying first value from each pair to result (even case)
2 correct number of iterations: code is inside a loop that executes
length/2 times (-1 if obob)
2 correct expressions (-1 if obob or otherwise close):
5 copying second value from each pair to result (even case)
2 correct number of iterations: code is inside a loop that executes
length/2 times (-1 if obob)
3 correct expressions (-1 if obob or otherwise close):
2 works for odd case (shifts 2nd group of values 1 to the right)
1 reasonable attempt
1 correct
1 returns their answer (requires construct attempt)
Notes:
ArrayList solutions or extra data structures solutions go to question leader
Syntax errors are capped at -2.
Problem #10
Solutions:
public static String acronym(String s) {
boolean inWord = false;
s = s.toUpperCase();
String result = "";
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == ' ' || ch == '-') {
inWord = false;
} else if (!inWord) {
inWord = true;
result += ch;
}
}
return result;
}
public static String acronym(String s) {
String s2 = "";
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '-') {
s2 += " ";
} else {
s2 += ch;
}
}
Scanner input = new Scanner(s2.toUpperCase());
String result = "";
while (input.hasNext()) {
result += input.next().charAt(0);
}
return result;
}
-------------------------------------------------------------------------------
Can get up to 3 points for any of the following good things:
1 correct header
1 for loop using string length
1 getting one char from source string with charAt or substring(i, i + 1)
1 testing whether a character in the source string is a space or dash
1 initializing a local string to an empty string
1 appending a character from source string to local string
1 uppercasing the source string or a local string
1 returning a local string
-------------------------------------------------------------------------------
To go to round 2, a solution needs one of the following:
* testing adjacent characters for space/dash versus !space/dash
* constructing a Scanner from the string, calling next
-------------------------------------------------------------------------------
Without replacing dashes with spaces, the Scanner solution gets 5 points
Deductions:
-3 major error
-2 medium error
&& vs ||
need to delete nontrivial code of theirs
fails on delimiters composed of just dashes
fails on strings that begin with a letter
fails on strings that end with a dash
-1 minor error
OBOB (you can fix code by changing one expression by +1 or -1)
charAt or length instead of s.charAt, s.length
testing whether character is null instead of ' '
didn't return result
-0 minor syntax errors
String result = s.charAt(0);
String new = ... (reserved word)
s.length vs s.length()
string/char confusion (==, .equals)
-4 requires mutable strings...attempting to do String replace for a Scanner
solution by saying something like:
s.charAt(i) = ' ';
Stuart Reges
Last modified: Fri Sep 16 16:16:07 PDT 2011