Practice Final Solutions
CSCI E-50a, Fall 2005

HOME | JAVA | RESOURCES | FAQ

 
Practice Final Exam (PDF)
1 E We are looking for the situation where the expression !(a && b) && (a || b) evaluates to true. In order to get a true result when we have an &&, we must have both sides evaluate to true; this means that !(a && b) must be true, or if we remove the negation, that (a && b) must evaluate to false. Likewise, (a || b) must also evaluate to true. Let's draw a table to look at this:
   
a b a && b !( a && b) ( a || b ) !( a && b ) && ( a || b )
true true true false true false
true false false true true true
false true false true true true
false false false true false false

We can see that in order to have (a && b) evaluate to false, we must either have both values false, or one false and the other true. In order to have (a || b) evaluate to true, we must either have both values true, or one false and one true. The only options that match for both tables are to have one value true and one false - so choice E is the answer.
2 D Note that there are no curly braces included in the code - this means that each for loop will take the next statement (simple or compound) as its loop body. For the outer for loop, its body becomes the inner for loop (a compound statement). For the inner for loop, its body is the first print statement. The second println() statement therefore won't execute until all the printing of the asterisks is finished. Knowing this, we can get the answer with multiplication - for every time that the outer loop runs, the inner loop will do a complete cycle of 5. This means we will have 10 sets of 5, or a total of 50 asterisks printed, followed by the println().
3.  A In a switch statement, you should recall that once any case is matched, all the code from that point downward will execute unless a break statement is encountered, which stops the code execution. The problem with the code as written is that it has no break statements; therefore, if case 1 matches (the number is odd), both statements will print. To fix it, we need to have odd numbers print that statement, then stop - so we should include a break statement at the end of line 2, following the print statement.
4 E To evaluate these segments of code, you should try them with each of the three cases and see how they differ. Suppose x = 0 when the code begins... Segment 1 will have the while loop fail right away - x is NOT > 0 - and it will then print "x = 0". Segment 2 will begin by decrementing x to -1, then the test happens, it fails, and the loop ends. The print statement will therefore print "x = -1" - NOT the same between the two segments.

Suppose x = 1 when the code begins... Segment 1 will have the test in the while loop succeed, so x is decremented to 0, then the test is done again, and now it fails (0 is NOT > 0). The print statement will print "x = 0". In segment 2, beginning with x = 1, it initially decrements x to 0, then tests for x > 0, and the test fails. It will then print "x = 0", so these two segments have done the same thing.

Suppose x = -1 when the code begins... Segment 1 will test and fail, then print "x = -1". Segment 2 will decrement x to -2, then do the test and fail, and it will print "x = -2". Again we have a difference between segments. When we look at the answer choices, we see that option E lists both the first and third condition - so it is our answer.
5 Since we did not cover recursion this semester, it will not be on the final exam.
6 C When you are testing, you should try to evaluate all the boundary conditions, as well as samples of cases both inside and outside of them. In this case, our boundary conditions are 0, $10,000, and $20,000. Therefore, we want to test each of those values as well as something less than 0, something between 10,000 and 20,000, and something greated than 20,000. When you consider the options that you are given, the only one which tests all of these areas is option C.
7 A A look at the two lines of code should tell you that, assuming there are no compiler errors, the method returns a value that fits into an int variable, and there is nothing in the parentheses following its name, so it has no parameters. When you look at your options for answers, you'll see that the only one that matches these observations is choice A.
8.  E Choice A doesn't list the types of the variables, so it is not legal. Choice B tries to put the size of the array inside the square braces, but we don't do that when we list the array name, so it also is not legal. Choice C has two arguments and lists their types, but the second name contains an illegal character for a variable name: '+'. Choice D lists two variables with a type, but you are not allowed to list them with commas in a method declaration. Therefore, none of the options are legal and the answer is choice E.
9 B Remember that a linear search begins at the start of the array, and continues one by one through the elements to the end. A linear search can be done on any array, sorted or not, but we're told that this array is sorted. A binary search requires a sorted array, which we have. It begins by looking at the middle element. If that is not the item we want, it tests whether the desired item is greater than or less than the middle, and discards the part of the array where the item won't be found. The subarray then has its middle element checked, and if it doesn't match the item we want, we repeat the process.

If the value is not in the array, the binary search will be faster, because larger parts of the array are eliminated each time. If the element is the last element, we'll get to it sooner because the parts are eliminated more quickly. If the element is the middle element, a binary search will find it on the first test. However, if the item is the first element in the array, a sequential search will test the first element to begin, and will find it immediately - so the answer is choice B.
10. A We've spoken about the Java principle of data abstraction - making variables (or data members) private and methods public - as a means of making code easier to maintain and to modify. This doesn't necessarily affect the efficiency, and it doesn't impose any restrictions on making methods public or private, but it DOES allow us to change the names and data types of variables without requiring changes to code which uses the class - so choice A is the answer.
11. B To solve this problem, you'll simply need to work through the code line by line. We begin in main by creating n and setting it to 3. Next the method fum is called and passed the values 3 and 6, which are copied into the method's parameter (local) variables n and b. Inside the method the two values are multiplied together, then the result stored back inside n. The second statement in the method increments n by 1, and the third statement returns the value in n, which is 19 - so the result printed is 19 and the answer is choice B.
12. D Choice A combines the two strings into a third String using concatenation, which will work fine. Choice B tests to see if both String variables point to the same String object - testing with '==' checks memory addresses of objects, rather than contents. However, this also will work fine, and will print if they are indeed the same. Choice C compares the length of the two Strings, again a fine thing to do and one that won't cause any errors. Choice E first converts String s1 to upper case, then asks for the index of the String "blah". If the String is upper case, a lower-case String won't be found, but it won't cause an error. Choice D asks for the character at s1.length - however, we know that Strings index from 0 to length - 1, so this request will cause a StringIndexOutOfBoundsException, and the answer is D.
13. C This is similar to our situation in Choice B of the preceding question. As long as objects are of the same type, we can assign one variable to point to the same object that the other one points to. This is what the line of code in problem 13 does. Therefore, we can eliminate choices A and B, as there is no error caused. Choice D is incorrect - using the assignment operator for the object's reference variable doesn't change the contents of an object. Choice C is the correct answer - and this eliminates choice E.
14. B Choice A is not legal, because we can't put the size of an array into the left side of the declaration. Choice C tries to do the same thing, just changes the order slightly. Choice D fails to include the square brackets on the left side of the declaration, and they are required. Choice B is correct Java code - which rules out Choice E.
15. In the code given the array is passed into the method. However, arrays are passed by reference just as objects are, so the LOCAL parameter variable 'a' holds a reference to the original array. When the new array is created and then assigned to 'a', it discards 'a's reference to the original parameter array and makes a LOCAL assignment to the new array - the original array is unchanged. The method is void, so nothing is returned, and when the method ends, 'a' and the new array go away.

Problem 16
PART 1
The problem asks you to use an initializer for the board pictured on page 9 of the practice final, not individual assignment statements. Note that "START" is occupying eloement 0 of the array, and "FINISH" is not part of the array, but instead holds the length of the array. We are placing -1 in spaces that have no chutes or ladders, and for positions which do, the end location of the chute or ladder. This is how our board looks:
      int [ ] board = { -1, -1, -1, -1, 12, -1, -1, -1, 2, -1, -1, -1, -1, 7, -1 };
Space 4 has a ladder that goes to space 12, so element 4 of the array holds the 12, space 8 has a chute that goes to space 2 so element 8 holds a 2, and space 13 has a chute that goes to space 7 so element 13 holds the 7.
PART 2
You should keep in mind that the board used for the game may have a different configuration (different length, or different locations of chutes and ladders) than the board which you declared in Part 1. We are also not currently planning for more than one player.

The game begins by setting up the different variables that will be needed, and then goes into a loop until the player reaches FINISH. The completed code looks like this (with missing parts filled in):
class Chute
{
    public static void main( String [] args )
    {
        //  Your declaration of board would go here, although
        //  it might be a different game configuration 
        //  than was used in Part 1 of this problem.
 	
        int finish = board.length;
        //  NOTE there is no array element at location 
        //  [finish].  The variable finish stores an index
        //  that is one beyond the end of the array
        //  i.e., the gray box marked Finish just after the
        //  final board position.
 	
        boolean gameOver = false;
        int rollCount = 0;
        int pos = 0;
        int move;
 
        while( ! gameOver )
        {
            do {
                move =(int)(Math.random() * 6 + 1);      // answer (a)
                System.out.println("Rolled a " + move);
                rollCount++;
            } while (pos + move > finish );               // answer (b)
 		  
            pos += move;
            System.out.println("Now at position " + pos);
 
            if(pos == finish )                             // answer (c)
            {
                System.out.println("You have finished!");
                gameOver = true;
            }
            else if(board[pos] != -1 && board[pos] < pos ) // answer (d)
            {
                pos = board[pos];
                System.out.println("Down the chute to " + pos );
            }
            else if(board[pos] > pos )                    // answer (e)
            {
                pos = board[pos];
                System.out.println("Climbed the ladder to position " + pos );
            }
        }  // end of the while loop
 
        System.out.println("You threw the dice " + rollCount + " times!");
    }
}
(a) The game begins by needing to roll a possible move. We're using a single dice, so our outcomes will be between 1 and 6. Therefore, we multiply Math.random() by 6 (which gives us a range of 0 - 5), and add 1 to have a range of 1 - 6.

(b) The rules state specifically, however, that the player may not go past the finish point, so each time we roll a possible move, we need to test that the new position is less than 'finish'. So long as it is NOT, we want to continue to roll moves, until we get a move that can be played. The do-while will roll the initial move, then tests to see if it will NOT be a valid one (if the current position + the move would be greater than the finish location); if it is, we continue to roll.

(c) After obtaining a valid move and exiting the do-while, we make the change to the position, and print the new location. We next need to check on three possibilities: that we have reached finish, that we've moved to a location with a chute, or that we've moved to a location with a ladder. The initial 'if' tests to see if we've reached the finish space, and if so prints a message and sets the gameOver variable to true, so that the while loop will exit.

(d) Next we need to check for the presence of a chute. Since we set up the board with -1 in all spaces without chutes or ladders, we first make sure that the board array's value stored at our position is not -1; if it is, we're on a normal space. If, however, the value is not -1 AND the value is less than the current position, we have a chute, so we need to change the player's position and print a message for the chute. Keep in mind that we may use boards with different configurations of chutes and ladders, so we need to check in a way that works for any board, rather than just testing specific positions.

(e) Finally, we need to check for the presence of a ladder. The board array's value in the current position will be greater than the position if we have a ladder, so we only need to test for that, and if a ladder is there, change the player's position and print the message.
Part f: Changing the code to allow continual moves if there are ladders linking to each other would look like the following:
    else
    {
         while( board[pos] > pos )                    // answer (e)
         {
              pos = board[pos];
              System.out.println("Climbed the ladder to position " + pos );
         }
    }

TOP | HOME | JAVA | RESOURCES | FAQ

© 2009, The President and Fellows of Harvard College
Please send comments to The Webmaster
URL: http://www.fas.harvard.edu/~libe50a/practicefinal.html
Last modified: Monday, 07-Jan-2008 15:39:06 EST