Q1: each part was worth 2 points a)b1 || b2 b)Math.sqrt(A*A + B*B) c)array[0] % 2 + array[1] % 2 + array[2] % 2 == 1 (alternatively could do combination of && with ||) d)words != null && words.size() > 0 && words.get(0).equals("Hello") e) for (int i=1; i <= 100; i++) { System.out.println(i); } Q2: each answer was worth 1 point: Did it change? no no yes no yes yes no {{0,1}, {2,4}} What is printed to the screen? 200 3.0 (if you wrote 4.0 it was correct too since there's no way to know which parameter to the constructor is x or y) Q3: each phase was worth 2 points. If you messed up the answers in a phase then the subsequent phases were graded assuming your prior phase was correct. That is, if you messed up phase 1, you could still get phase 2 or 3 right as long as your answers were consistent. Phase 1 30 30 1 31 Phase 2 31 22 53 Phase 3 30 31 22 53 Q4: Each part was worth 3 points. Generally 2 points were given for explanation + 1 point for code. If the code made it clear enough you understood the problem then no explanation was needed. a)There were actually 2 bugs here. Either was sufficient for full credit. First bug is an integer division error in computePercentageLosses. It will always return 0 unless numWins = 0. To fix this, you should cast numLosses to a double. The second bug is the > was backwards. If the canadiensRecord > mapleLeafsRecord it means the % of canadien losses was greater. In this case the Canadiens had a worse record. b)The problem is a scope issue. When you write String[] rooms = new String[3]; You are creating a new variable rooms and assigning to it a new array. Thus the rooms that is a property of the House object still is null. To fix, simply remove the String[] before rooms on line 5. c)This is a "has-a" vs "is-a" question. On line 5 of WebCT, the grades object is of type StudentGrades. A StudentGrades object does not have a length. It has an int[] which has a length, but no length property directly. To fix it, you should call getNumRecords() by writing grades.getNumRecords() instead of grades.length. Alternatively, you could make private int[] grades public and then write grades.grades.length although this is not good design since properties should always be private. (It was fine for full credit though) d)The issue is the method header warns that an exception will be thrown but it's not caught. To fix it, you should put everything into a try catch: try { ......//lines 6 through 10 } catch (NotEnoughFundsException e) { System.out.println("There are not enough funds."); } To repeat this, you can put it into a loop: boolean isSuccesful = false; while (!isSuccessful) { try { //lines 6 through 10 here isSuccessful = true; } catch (NotEnoughFundsException e) { System.out.println("Please retry"); } } Catching all exceptions was fine as well. e)hasActor is a static method. actors is a non-static property. Since non-static properties have to be accessed ON an object, you have to either make the method non-static (by deleting the word static) or create an object and then access actors on it. In this case, the best idea is definitely to remove static and then writing actors.length would be the same as this.actors.length 5)Most people did quite well on this question. public static int h(int n) { if (n <= 2) { return 1; } if (n % 2 == 0) { return h(n-1) + n; } //else return h(n-2) + 2 * n; } 6)Most people did well on this question as well. public class MetroStation { private String name; private double xPosition; private double yPosition; public MetroStation(String stationName, double x, double y) { this.name = stationName; this.xPosition = x; this.yPosition = y; } public String getName() { return this.name; } public double getXPosition() { return this.xPosition; } public double getYPosition() { return this.yPosition; } public boolean equals(MetroStation other) { //in practice, we'd want to check that other != null, but //it wasn't needed for this question return this.name.equals(other.name); } } 7)Results on this question were good. import java.util.ArrayList; //-1 if you forgot this public class MetroLine { String colour; ArrayList stations; public MetroLine(String c) { this.stations = new ArrayList(); this.colour = c; } public void addStation(MetroStation m) { this.stations.add(m); } public boolean hasStation(MetroStation m) { return this.stations.contains(m); //could also use a loop for this } public String getLineColour() { return this.colour; } public MetroStation getFirstStop() { if (this.stations.size() == 0) { return null; } return this.stations.get(0); } public MetroStation getPriorStop(MetroStation m) { int location = this.stations.indexOf(m); if (m == 0) { return null; } return this.stations.get(m-1); } public MetroStation getNextStop(MetroStation m) { int location = this.stations.indexOf(m); if (m == this.stations.size() -1) { return null; } return this.stations.get(m+1); } } 8)This question was mixed. This was definitely the hardest question on the exam. Jorg and I thought for quite some time about the fairest way to mark this question and came up with the following. Part of the assumption in this was that everyone had gotten a good chance to prove they understood getters/setters/class structure/headers/ etc on the prior 2 questions. -constructor + addline (2 points total) -headers + class structure (4 points total. This almost amounted to a curve in some sense as almost everyone got these 6 points) -getDistanceTravelled (3 points) -findNearestStation (4 points) -getNeighboringStations(4 points) -findPath (1 point) -findPathHelper (7 points. This was a bit more than the other methods but it was the hardest method. In addition as we gave the step by step, most people who attempted this ended up getting at least a few points for base cases) import java.util.ArrayList; public class SubwaySystem { ArrayList lines; public SubwaySystem() { lines = new ArrayList(); } public void addLine(MetroLine newLine) { lines.add(newLine); } public double getDistanceTravelled(ArrayList path) { double sum = 0; for (int i=1; i < path.size(); i++) { sum = sum + MapUtility.distanceBetweenPoints(path.get(i-1).getXPosition(), path.get(i-1).getYPosition(), path.get(i).getXPosition(), path.get(i).getYPosition()); } return sum; } public MetroStation findNearestStation(double x, double y) { MetroStation best = lines.get(0).getFirstStop(); double minDistance = MapUtility.distanceBetweenPoints(x,y, best.getXPosition(), best.getYPosition()); for (int i=0; i < lines.size(); i++) { //could also use a while loop instead for (MetroStation stop = lines.get(i).getFirstStop(); stop != null; stop = lines.get(i).getNextStop(stop)) { double newDistance = MapUtility.distanceBetweenPoints(x,y, stop.getXPosition(), stop.getYPosition()); if (minDistance > newDistance) { best = stop; minDistance = newDistance; } } } return best; } public ArrayList getNeighboringStations(MetroStation station) { ArrayList neighbors = new ArrayList(); for (int i = 0; i < this.lines.size(); i++) { if (this.lines.get(i).hasStation(station)) { MetroStation next = this.lines.get(i).getNextStation(station); if (next != null) { neighbors.add(next); } MetroStation prior = this.lines.get(i).getPriorStation(station); if (prior != null) { neighbors.add(prior); } } } return neighbors; } public ArrayList findPath(MetroStation start, MetroStation finish) { return findPathHelper(start, finish, new ArrayList()); } private ArrayList findPathHelper(MetroStation start, MetroStation finish, ArrayList partialPath) { if (partialPath.contains(start)) { return null; //worth 1 point } if (start.equals(finish)) { return partialPath; //worth 1 point } ArrayList neighbors = getNeighboringStations(start); //worth 1 point ArrayList bestPath = null; //keeping track of min correctly worth 1 point double minDistance = 100000; //big number to start for (int i=0; i < neighbors.size(); i++) {//loop header was worth 1 point //next 3 lines were worth 2 points for the recursion ArrayList duplicatePath = MapUtility.duplicate(partialPath); duplicatePath.add(start); ArrayList currentPath = findPathHelper(neighbors.get(i), finish, duplicatePath); //the next part counted towards the keeping track of min properly worth 1 point if (currentPath != null) { double pathDistance = getDistanceTravelled(currentPath); if (bestPath == null || pathDistance < minDistance) { bestPath = currentPath; minDistance = pathDistance; } } } return bestPath; } } 9) Generally, this question was good too. A few people left it blank, but most people heeded the pre-exam warning to make sure to leave time for this question. import java.util.ArrayList; import java.util.Scanner; public class MontrealMaps { public static void main(String[] args) { try { SubwaySystem montreal = MapUtility.generate(); //it was OK to write new SubwaySystem() instead although not intended originally. Scanner reader = new Scanner(System.in); System.out.println("Enter your location x and y"); double myX = reader.nextDouble(); double myY = reader.nextDouble(); System.out.println("Enter where you want to go x and y"); double goalX = reader.nextDouble(); double goalY = reader.nextDouble(); MetroStation nearMe = montreal.findNearestStation(myX, myY); MetroStation nearGoal = montreal.findNearestStation(goalX, goalY); if (nearMe.equals(nearGoal)) { System.out.println("It's faster to walk there."); return; } ArrayList path = montreal.findPath(nearMe, nearGoal); if (path == null) { System.out.println("There is no path on the metro, you'll have to walk"); } else { MapUtility.printPath(path); } } catch (Exception e) { //NotEnoughFundsException or IOException were fine also. System.out.println("Error, not enough funding"); } }