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("")) {
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("
")) {
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 "
" or if/else that handles "
"
1 attempt (inner loop or if/else with some kind of "
" test)
1 correctly counting number of lines in each paragraph
1 correct comparison (requires equals instead of ==)
1 println for "-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 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 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)
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