Problem #4 Solution: public static void switchData(Scanner input) { String title = input.next(); System.out.print(title); while (input.hasNextInt()) { int n1 = input.nextInt(); if (input.hasNextInt()) { int n2 = input.nextInt(); System.out.print(" " + n2); } System.out.print(" " + n1); } System.out.println(); } 1 header (non-void return type ok if consistent with a return statement) 1 reads/prints title (println okay) 1 correct while loop (while hasNext or while hasNextInt) 1 reads two numbers inside loop for either even or odd case 3 correctly prints the two numbers 1 attempt (two print or println statements) 2 correct order (reversed) 2 properly handles case with odd number of numbers 1 attempt 1 correct 1 all formatting correct (all prints, spaces between numbers, println after loop) Problem #5 Solutions: public static int analyzeParagraphs(Scanner input) { int max = 0; while (input.hasNextLine()) { String line = input.nextLine(); int count = 0; while (!line.equals("<p>")) { count++; line = input.nextLine(); } System.out.println(count + "-line paragraph"); if (count > max) { max = count; } } return max; } public static int analyzeParagraphs(Scanner input) { int max = 0; int count = 0; while (input.hasNextLine()) { String line = input.nextLine(); if (line.equals("<p>")) { System.out.println(count + "-line paragraph"); count = 0; } else { count++; } if (count > max) { // can also appear after count++ max = count; } } return max; } 1 header 1 correct while loop (while hasNext or while hasNextLine) 1 reads and stores a line using nextLine() 3 loop that counts lines until "<p>" or if/else that handles "<p>" 1 attempt (inner loop or if/else with some kind of "<p>" test) 1 correctly counting number of lines in each paragraph 1 correct comparison (requires equals instead of ==) 1 println for "<count>-line paragraph" (generous: doesn't even require loop let alone correct count computation) 2 max computation 1 attempt (initialize to something, update inside loop) 1 all correct (initialize to 0, correct update in loop, returned after loop) Problem #6 Solutions: public static boolean sameGap(int[] list) { if (list.length >= 2) { int gap = Math.abs(list[0] - list[1]); for (int i = 2; i < list.length; i++) { int gap2 = Math.abs(list[i] - list[i - 1]); if (gap != gap2) { return false; } } } return true; } public static boolean sameGap(int[] list) { for (int i = 0; i < list.length - 2; i++) { int gap1 = Math.abs(list[i] - list[i + 1]); int gap2 = Math.abs(list[i + 1] - list[i + 2]); if (gap1 != gap2) { return false; } } return true; } 1 header 1 loop attempt (loop with bounds that involve array length) 2 gap attempt 1 computes a difference of two adjacent values 1 applies Math.abs to difference 4 correctly comparing gaps (requires first gap attempt point--can't be comparing something other than gaps) 2 correctly compares either adjacent gaps or first gap versus later gaps or equivalent 2 if they got previous 2 points, correct bounds/initialization so that each gap is included at least once and no array index out of bounds (-1 of OBOB, but lose both if off by 2)--will normally be a loop bounds issue for those comparing adjacent gaps and an outer if issue for those comparing a first gap versus later gaps 2 correctly returns true/false based on a test in a loop (requires some kind of test in a loop, but assume test works). This is generally atomic but can be worth 1 point for solutions that are close. For example, if their only error is that they forgot "return true" after the loop, they getf 1 point. Or their only error might be to fail to return true for an array of length less than 2, in which case they get 1 point. If they switch true/false or if they prematurely return true, they lose both points. Ask the question leader if you see something that might be close. Problem #7 Solutions: public static void split(ArrayList<Integer> list) { for (int i = 0; i < list.size(); i += 2) { int n = list.get(i); list.set(i, n / 2 + n % 2); list.add(i + 1, n / 2); } } public static void split(ArrayList<Integer> list) { for (int i = 0; i < list.size(); i += 2) { int n = list.remove(i); list.add(i, n / 2 + n % 2); list.add(i + 1, n / 2); } } 1 header (return type ok if consistent with a return statement, parameter must be ArrayList<Integer>) 4 loop over list 1 attempt (for loop using list.size() or list.length() or list.length) 1 correct bounds (starting at 0, going while < list.size(), must be size()) 2 increment i by 2 or loop goes backwards or using a second structure and correctly copying back after loop 2 expressions/code for splitting list.get(i) into two parts including odd case 1 attempt (testing value % 2, finding value / 2, array syntax okay) 1 correctly splits list.get(i) (must be get, must handle odd case, must be going into structure in correct order in odd case) 3 correctly replaces value with two new values 1 reasonable 2-step attempt using ArrayList methods including: add/add set/set array-style assign followed by add get(i) assign followed by add a single add or single set would not count 2 correct approach using ArrayList methods (set/add, remove/add/add)--can get 1/2 if they sometimes do it right Notes: -0 for list.get[i] instead of list.get(i) -2 for calling set/add/get without saying "list." (only apply this rule if their score goes up) Problem #8 Solution: public class Eagle extends Critter { private int count; private int max; public Eagle() { count = 0; max = 1; } public Action getMove(CritterInfo info) { count++; if (count == 2 * max) { count = 0; max++; } if (info.getFront() == Neighbor.EMPTY) { return Action.HOP; } else if (info.getFront() == Neighbor.WALL) { return Action.RIGHT; } else { return Action.INFECT; } } public Color getColor() { if (count < max) { return Color.RED; } else { return Color.BLUE; } } public String toString() { return "<>"; } } 1 class header 2 toString 1 header 1 returns "<>" 5 getMove 1 header 1 returns Action.HOP based on some kind of empty neighbor test 1 returns Action.RIGHT based on some kind of wall test 1 returns Action.INFECT in some of the other cases based on tests 1 all correct 7 getColor 1 header 1 returns Color.RED in some cases (generous) 1 returns Color.BLUE in some cases (generous) 1 declared a field for counting moves and incremented it in getMove or getColor 1 second field for current maximum 2 all correct (-1 if close) Problem #9 Solution: public static int[] reverseSublist(int[] list, int from, int to) { int[] result = new int[to - from]; for (int i = 0; i < result.length; i++) { result[i] = list[to - i - 1]; } return result; } 2 header (-1 per error) 4 constructing the new array 1 attempt (construct some new array) 1 better attempt (array of int, length within 2 of being right) 2 correct (array of int, size correct) 8 copying values from original to new array 2 for loop over new array 1 attempt (any for loop will do) 1 correct (from 0 to size of new array--requires new array) 2 copying from old array to result result[something] = list[something] 4 correctly reverses (-1 if expressions are OBOB) 1 returns their answer Notes: Students weren't supposed to use ArrayList or Arrays.copyOf or Collections.reverse--when in doubt, show to question leader Problem #10 Solutions: // startsWith approach public static int count(String target, String source) { target = target.toUpperCase(); source = source.toUpperCase(); int count = 0; for (int i = 0; i < source.length(); i++) { if (source.substring(i).startsWith(target)) { count++; } } return count; } // substring approach public static int count2(String target, String source) { int count = 0; for (int i = 0; i < source.length() - target.length() + 1; i++) { String sub = source.substring(i, i + target.length()); if (sub.equalsIgnoreCase(target)) { count++; } } return count; } // indexOf approach public static int count3(String target, String source) { target = target.toUpperCase(); source = source.toUpperCase(); int count = 0; while (source.length() > 0) { int pos = source.indexOf(target); if (pos == -1) { return count; } else { count++; source = source.substring(pos + 1); } } return count; } // CharAt approach public static int count4(String target, String source) { target = target.toUpperCase(); source = source.toUpperCase(); int count = 0; for (int i = 0; i < source.length() - target.length() + 1; i++) { boolean same = true; for (int j = 0; j < target.length(); j++) { if (target.charAt(j) != source.charAt(i + j)) { same = false; } } if (same) { count++; } } return count; } } } (not very good) Plus criteria (max +3) Good things that each get 1 point: 1 header 1 for loop using source length 1 count = 0 1 count++ 1 return count 1 substring of source or charAt 1 startsWith 1 .equals or .equalsIgnoreCase 1 toUpperCase or toLowerCase ------------------------------------------------------------------------------- (pretty good) Minus criteria (min + 4) Grade this way if you see: comparing target to substring of source using startsWith with substring of source using charAt with an inner loop using indexOf and substring or 2-argument indexOf
Stuart Reges
Last modified: Fri Sep 16 16:13:29 PDT 2011