CS307 Spring 2009 Midterm 1 Solution and Grading Criteria. Grading acronyms ABA - Answer by Accident AIOBE - Array Index out of Bounds Exception may occur BOD - Benefit of the Doubt. Not certain code works, but, can't prove otherwise ECF - Error carried forward. Gacky or Gack - Code very hard to understand even though it works or solution is not elegant. (Generally no points off for this.) GCE - Gross Conceptual Error. Did not answer the question asked or showed fundamental misunderstanding NAP - No answer provided. No answer given on test NN - Not necessary. Code is unneeded. Generally no points off NPE - Null Pointer Exception may occur OBOE - Off by one error. Calculation is off by one. 1. Answer as shown or -2 unless question allows partial credit. No points off for differences in spacing and capitalization. If quotes included, okay. A. 20 5 B. false C. [3, 1] (comma differences and brace differences okay, just need 3 and 1 in that order.) D. exception. (All that requires is exception or runtime error or ArrayIndexOutOfBounds error. Just error is -2.) E. assertions (or assert statements) 1 point if statement / throw IllegalArgumentException 1 point (or words to that effect) F. 2 G - I. Can be other than valid / invalid. Some way of saying declaration is okay or not. Explanations NOT needed G. 1: invalid (GroundUnit does not implement Movable) 2: invalid (Can't instantiate (create) objects that are interfaces) H. 1: valid, 2: invalid (Object variables can't refer to types that are ancestors) I. 1: valid, 2: invalid (Same as G.1.) J. genI 20 K. MaxI 15 L. The code does not compile because the Tank class does not have a default constructor. (Or words to that effect. -1 allowed if answer is close.) M. 4 N. TexII 25 O. The code does not compile because the declared type of the variable m5 is Movable so only methods from that type (interface) can be called. (Or words to that effect. -1 allowed if answer is close.) ------------------------------------------------------------------------------- 2. Comments: A simple problem of implementing a class with some interesting twists such as handling the sign and putting the digits in reverse order. Common problems: Suggested Solution: public class LargeInt{ private int[] digits; private int numDigits; private boolean isPositive; private static final int EXTRA_CAP = 5; public LargeInt(String num){ isPositive = num.charAt(0) != '-'; digits = new int[num.length() + EXTRA_CAP]; numDigits = num.length(); if( !isPositive ) numDigits--; for(int i = 0; i < numDigits; i++){ digits[i] = num.charAt( num.length() - i - 1 ) - '0'; } } } Point breakdown: Class header: 2 points instance vars private: 1 point array of ints for digits: 1 point int for number of digits or size: 1 point variable to track if positive or not: 1 point class constant for extra space: 1 point Constructor header: 2 points set sign variable: 3 points (partial credit possible) create array to hold digits with extra capacity: 2 points set number of digits variable: 2 points store digits in array least significant bit in index 0: attempt 2 points, correct 2 points ------------------------------------------------------------------------------- 3.Comments: This problem had two parts. First the algorithm for expanding the original IntList and repeating digits correctly. Second dealing with the abstraction of the IntList and its internal storage container which was a native array of ints. Common problems - The biggest challenge algorithmically was tracking the index in the original IntList's container and the index in the new IntLists container which were different. I think the simplest approach was to have two separate variables, although many students did come up with a correct formula to calculate the index in the result. - Lots of misunderstanding between an IntList and a native array of ints. They are not the same thing. (The array is not the list.) - a couple of people wrote their own add method which is fine, but making it public meant you had to handle the case when their was not enough storage capacity even if you set aside enough in your getExpansion method. Since the method is public it could be called from other places and capacity may not exist. - It was necessary to correctly set the listSize variable for the resulting IntList - using container.length instead of size() or listSize. The internal array could have extra capacity and those elements were not part of the list and should not be copied. Suggested Solution: public IntList getExpansion(int numReps){ assert numReps > 0; IntList result = new IntList(); result.container = new int[this.size() * numReps]; int indexInResult = 0; for(int i = 0; i < size(); i++){ for(int j = 0; j < numReps; j++){ result.container[indexInResult] = this.container[i]; indexInResult++; } } result.listSize = this.size() * numReps; return result; } An alternate solution using the add method is possible, but then the add method (and possibly resize) also need to be implemented. Point breakdown - create resulting IntList: 3 points - resulting IntList's container (native array of ints) is sufficient size: 2 points - resulting IntList's listSize variable correctly set: 2 points - iterate through elements of this (calling object): attempt, 4 points, correct, 4 points - iterate through repetitions. attempt, 4 points. correct, 4 points - return result: 2 points ------------------------------------------------------------------------------- 4. Comments: This problem was more algorithmic in nature than number 3. The goal was to find a row in the other MathMatrix in which every element is the same multiple of the corresponding element in the specified row of the calling MathMatrix object. Common problems: - a lot of people just checked corresponding elements to see if the one in the other MathMatrix was a multiple of the element in the specified row in this MathMatrix. It was required that every element be the same multiple. So for example 2 4 6 is a multiple (2) of 1 2 3 but 3 10 9 is not a multiple of 1 2 3. - Checking to see if the same quotient from integer division was obtained, but not checking to see if remainder was 0. This is necessary for it to be integer multiple. - The problem required you to not check elements unnecessarily. Most student realized to return true once one row was found, but a lot of students would continue to check a given row when one column is bad. Once one bad pair is found there is no need to check the rest of the row. - A lot of people made a copy of the target row. This was unnecessary, but points were not taken off. - More confusion between a MathMatrix object and the 2d array of ints named cells that is part of the MathMatric object - The number of rows were not necessarily the same so it was necessary to iterate through the number of rows in other, otherwise rows could be missed or an ArrayIndexOutOfBounds error could occur. Suggested Solution: public boolean hasMultipleOfRow(MathMatrix other, int tgtRow){ boolean foundGoodRow = false; int row = 0; while(!foundGoodRow && row < cells.length){ int multiple = other.cells[row][0] / this.cells[tgtRow][0]; int col = 0; boolean colGood = true; while(colGood && col < cells[0].length){ colGood = multiple * this.cells[tgtRow][col] == other.cells[row] [col]; col++; } foundGoodRow = colGood; row++; } return foundGoodRow; } Alternate solution using break, multiple returns and modulus operator: public boolean hasMult(MathMatrix other, int tgtRow){ for(int row = 0; row < cells.length; row++){ int flag = 1; int mult = other.cells[row][0] / this.cells[tgtRow][0]; for(int col = 0; col < cells[0].length; col++){ flag = 1; int multCheck = other.cells[row][col] / this.cells[tgtRow][col]; int rem = other.cells[row][col] % this.cells[tgtRow][col]; if( multCheck != mult || rem != 0 ){ flag = -1; break; } } if(flag == 1) return true; } return false; } Points breakdown - iterate through rows of other: attempt, 3 points, correct, 3 points - for current row check if first element is integer multiple: 3 points - iterate through columns of current row: attempt, 3 points, correct 3 points - check to see if current element is same integer multiple as first element: 3 points - stop checking current row if bad element (column) found: 2 points - stop checking when good row found: 2 points - access other.cells correctly: 3 points