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<Integer> 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<Integer> 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<Integer> 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<Integer> 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<Integer>) 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 = "<I>"; return Action.INFECT; } else { int flip = r.nextInt(2); if (flip == 0) { display = "<L>"; return Action.LEFT; } else { display = "<R>"; 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 (<I> for INFECT, <L> for LEFT, <R> 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