CS307 Spring 2006 Midterm 1 Solution and Grading Criteria Explanation of grading terms. LE = Logic error AIOBE = Array Index Out of Bounds Exception GCE = Gross Conceptual Error. The answer does not really address the question that was asked. 1. Unless partial credit per answer sheet must have answer as stated or -2. Ignore differences in spacing / lines. A. 4 -3 B. 2 16 C. Infinite Loop. (Infinite was the intended answer, but as one sharp student pointed out you get roll oever to a negative number fairly quickly. The actual output is -1970444362. Any answer that states "some negative number" or mentions rollover gets full credit. D. 2 4 15 E. 2 -1 F. Exception or Runtime Error or Null Pointer Exception. (Just error = -1) G. 14 H. 6 43 2 (6 4 3 2 okay) I. 102 61 J. false K. Syntax error (just error -1) L. 200 70 202 71 M. 170 70 169 70 N. Yes. Size implements the Comparable interface and thus object variables of type Comparable may point at objects of type Size. This is polymorphism. (Or words to that effect.) O. Yes. If C is null, a null pointer exception will occur. 2. This was a fairly simple array processing questions. The biggest problems I saw were minor errors in the logic for figuring if the difference was less than or equal to 10. Something had to be done becuase it was not known which concentration was larger. public boolean[] checkConcentrations(int[] time1, int[] time2){ assert time1 != null & time2 != null && time1.length == time2.length; boolean[] result = new boolean[time1.length]; for(int i = 0; i < result.length; i++){ int diff = time1[i] - time2[i]; result[i] = diff >= -10 && diff <= 10; } return result; } Criteria: Create resulting array 2 Loop through array: attempt 3 correct 3 Find difference between concentrations: attempt 4 correct 4 Set corresponding element of resultint array 3 return result 1 3. This was a challenging problem due to the algorithm that most people tried to implement. The most popular approach was to try to determine how many zeros started the row and then ensure everything after that was not a zero. Many people made the mistake of simple counting the number of zeros in the row. The other part of the algorithm was to determine that there was only 1 row with each number of leading zeros. Many people used a boolean array to track this. There is a clever solution that was not obvious from the problem statement. In this approach the columns are examined not the rows. This is easier becuase one does not have to worry about runs of zeros. Instead column 0 should have 1 non zero element, column 1 should have 2 non zero elements and so forth. When examining the columns the order of zeros and non zeros does not matter. This leads to a much simpler solution. //solution 1. Look at columns instead of rows public boolean couldBeUpperTriangular2(){ assert numRows() > 1 && numRows() == numCols(); boolean goodSoFar = true; int numNonZeros ; for(int col = 0; col < numCols() && goodSoFar; col++){ numNonZeros = 0; for(int row = 0; row < numRows(); row++){ if( getVal(row,col) != 0 ) numNonZeros++; } goodSoFar = numNonZeros == col + 1; } return goodSoFar; } //solution 2. Check run lengths of zeros and non zeros and no repeats of number of zeros to start row public boolean couldBeUpperTriangular(){ assert numRows() > 1 && numRows() == numCols(); boolean[] foundRows = new boolean[myCells.length]; boolean goodSoFar = true; //check all the rows until all checked or not possible for(int row = 0; row < numRows() && goodSoFar; row++){ int column = 0; //find how many zeros start the row while( getVal(row, column) == 0 && column < numCols() - 1 ) column++; int numZeros = column; //ensure rest of row are not zeros boolean rowGood = true; while( column < numCols() && rowGood ){ rowGood = getVal(row, column) != 0; column++; } if( rowGood && !foundRows[numZeros]) foundRows[numZeros] = true; else goodSoFar = false; } return goodSoFar; } //solution 3. Similar approach to 2, but doesn't use an array of booleans. Instead add another loop and search for a row with the proper number of starting zeros. I find this solution the most confusing. public boolean couldBeUpperTriangular3(){ assert numRows() > 1 && numRows() == numCols(); boolean goodSoFar = true; boolean foundProperRow; boolean switchedToNonZeros; int numZeros; for(int numberOfZerosNeeded = 0; numberOfZerosNeeded < numRows() && goodSoFar; numberOfZerosNeeded++){ foundProperRow = false; for(int row = 0; row < numRows() && !foundProperRow && goodSoFar; row++){ numZeros = 0; switchedToNonZeros = false; for(int col = 0; col < numCols() && goodSoFar; col++){ if(getVal(row,col) == 0) if(!switchedToNonZeros) numZeros++; else goodSoFar = false; else switchedToNonZeros = true; } foundProperRow = numberOfZerosNeeded == numZeros; } goodSoFar = goodSoFar && foundProperRow; } return goodSoFar; } Criteria Loop through rows attempt 4 correct 4 In a given row count number of starting 0s attempt 4 correct 4 In a given row check that no zeros exist in the row after the first non zero attempt 3 correct 3 Ensure no two rows have the same number of leading zeros attempt: 4 correct: 4 4. class CallingPlan{ private String name; private double baseCost; private int baseMinutes; private double costPerMinuteOverBase; //pre: n != null, bc > 0, bm > 0, cpmob > 0 public CallingPlan(String n, double bc, int bm, double cpmob){ name = n; baseCost = bc; baseMinutes = bm; costPerMinuteOverBase = cpmob; } // pre: minutes >= 0 public double predictedCost(int minutes){ double result = baseCost; if(minutes > baseMinutes) result += (minutes - baseMinutes) * costPerMinuteOverBase; return result; } //pre: other != null, minutes >= 0 public boolean thisPlanIsCheaper(CallingPlan other, int minutes){ return predictedCost(minutes) < other.predictedCost(minutes); } } Criteria Instance Vars 5 (-2 if not private) Cosntructor 5 predictedCost method 5 cheaper method 5 (-3 if 2 CallingPlans as parameters) -1 per missing prencondtion on constructor and methods. (Can be comment or assert) okay if predicetdCost prints out expected cost instead of returning. Question was not clear on this point. minor problems in a method -2 Don't take off for minor syntax errors such as braces, semi colons, slightly mispelled identifiers if intent is clear.