CSE 142 SUMMER 2011 FINAL EXAMINATION SOLUTIONS

CSE 142 SUMMER 2011 FINAL EXAMINATION SOLUTIONS 1. Reference Semantics Mystery (12 points) What does the following program print? import java.util.*; ...
35 downloads 3 Views 279KB Size
CSE 142 SUMMER 2011 FINAL EXAMINATION SOLUTIONS 1. Reference Semantics Mystery (12 points) What does the following program print? import java.util.*; public class ReferenceMystery { public static void main(String[] args) { int x = 1; int[] arr = new int[6]; mystery(x + 1, arr); System.out.println(x + ": " + Arrays.toString(arr)); x += 3; arr[5] = mystery(x, arr); System.out.println(x + ": " + Arrays.toString(arr)); } public static int mystery(int x, int[] a) { a[x - 2] = 3; if (a[x] == 0) { a[x] = 12; x++; } a[x + 1] = 7; System.out.println(x + ": " + Arrays.toString(a)); return x; } }

3: 1: 4: 4:

[3, [3, [3, [3,

0, 0, 0, 0,

12, 0, 7, 0] 12, 0, 7, 0] 3, 0, 7, 7] 3, 0, 7, 4]

1 of 11

2. Inheritance Mystery (10 points) Assume that the following classes have been defined: public class Picard extends Kirk { public String toString() { return super.toString() + " D"; } public void methodB() { System.out.print("Picard B "); super.methodA(); }

public class Sisko extends Kirk { public String toString() { return "DS9"; } public void methodA() { System.out.print("Sisko A "); } }

} public static class Kirk extends Janeway { public String toString() { return "Enterprise"; }

public class Janeway { public String toString() { return "Voyager"; } public void methodA() { System.out.print("Janeway A "); }

public void methodA() { super.methodA(); System.out.print("Kirk A "); }

public void methodB() { System.out.print("Janeway B "); methodA(); }

} }

Given the classes above, what output is produced by the following code? Janeway[] captains = { new Kirk(), new Picard(), new Sisko(), new Janeway() }; for (int i = 0; i < captains.length; i++) { captains[i].methodB(); System.out.println(); captains[i].methodA(); System.out.println(); System.out.println(captains[i]); System.out.println(); }

Janeway B Janeway A Kirk A Janeway A Kirk A Enterprise Ï Picard B Janeway A Kirk A Janeway A Kirk A Enterprise D Janeway B Sisko A Sisko A DS9 Ï Janeway B Janeway A Janeway A Voyager

2 of 11

3. File I/O Mystery (8 points) Consider the following method: public static void ioMystery(Scanner input) { while (input.hasNext()) { String str = input.next(); int num = input.nextInt(); for (int i = 0; i < num; i++) { System.out.print(str + " "); } System.out.println(""); } } Given the input files below, what output is produced by each of the following method calls? If no output is produced, leave the box blank. If the call would throw an exception at any point, write “error”. input1.txt* a3 b 4 c 1

input2.txt hi 2 15 4 supercalifragilisticexpialidocious

input3.txt

input4.txt x 3 y z

0

Scanner scan = new Scanner(new File("input1.txt")); ioMystery(scan);

ÏÏa a a ÏÏb b b b ÏÏc OR “error”

Scanner scan = new Scanner(new File("input2.txt")); ioMystery(scan);

ÏÏhi hi ÏÏ15 15 15 15 ÏÏ

Scanner scan = new Scanner(new File("input3.txt")); ioMystery(scan);

Scanner scan = new Scanner(new File("input4.txt")); ioMystery(scan);

x x x “error”

*Some students were given conflicting information about whether or not there was a space between the ‘a’ and the ‘3’ in input1.txt. As a result, the correct answer based on either assumption was accepted.

3 of 11

4.

Programming (10 points) Write a static method summarize that takes a single integer array parameter. The method should print out a summary of the array, describing sequences of repeated values as the number of occurrences and the value. The method should then return the number of such sequences that occurred in the array. The following table shows the behavior of summarize: If arr1 is:

Then summarize(arr1) prints:

And returns:

[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

1 1's

2 2's

3 3's

4

[5, 5, 5, 5, 5, 2, 2, 5, 5]

5 5's

2 2's

2 5's

[1, 2, 1, 3, 1, 4]

1 1's

1 2's

1 1's

[10, 11, 11, 10]

1 10's

[7]

1 7's

2 11's

4 4's

3 1 3's

1 1's

1 10's

1 4's

6 3 1

You should reproduce this output format exactly. You may assume the array has at least one value, and you need not worry about singular or plural. public static int summarize(int[] arr) { int counter = 1; int last = arr[0]; int groups = 1; for (int i = 1; i < arr.length; i++) { if (arr[i] == last) { counter++; } else { System.out.print(counter + " " + last + "'s counter = 1; last = arr[i]; groups++; } } // make sure to print the last group System.out.println(counter + " " + last + "'s return groups;

");

");

}

4 of 11

5. Critters (10 points) Write a complete class called Panther that extends the Critter class from Homework 8. Add any fields, constructors, methods, etc. necessary to implement the behavior. Panther objects have two modes: foraging and hunting. A Panther that is foraging continues foraging until it finds food. When food is encountered, the Panther should eat it, and then switch to hunting mode. The Panther then continues hunting until it gets into a fight, at which point it returns to foraging mode. A Panther is in foraging mode when it is initially created. Panthers behave as follows:

   

when foraging, display as black; when hunting, red when foraging, roar when attacked; when hunting, scratch always move in a random direction, but never stand still (i.e. never return Direction.CENTER) o each direction should be equally likely all other behaviors should be the Critter default

public class Panther extends Critter { private boolean hunting; private Random rand;

public Direction getMove() { int check = rand.nextInt(4); if (check == 0) { return Direction.NORTH; } else if (check == 1) { return Direction.EAST; } else if (check == 2) { return Direction.SOUTH; } else { // check == 3 return Direction.WEST; } }

public Panther() { hunting = false; rand = new Random(); } public boolean eat() { boolean shouldEat = !hunting; hunting = true; return shouldEat; } public Attack fight(String opponent) { if (hunting) { hunting = false; return Attack.SCRATCH; } else { return Attack.ROAR; } }

public Color getColor() { if (hunting) { return Color.RED; } else { return Color.BLACK; } } }

5 of 11

6. Array Mystery (9 points) Consider the following method: public static void arrayMystery(int[] arr) { for (int i = 0; i < arr.length / 2; i++) { if (arr[i] >= arr[2 * i]) { arr[2 * i] *= 2; } } }

Indicate in the right-hand column what values would be stored in the array after the method mystery executes if the integer array in the left-hand column is passed as a parameter to mystery. Array

Final Contents of Array

int[] a1 = { 17 }; arrayMystery(a1);

_[17]________________________

int[] a2 = { 3, 3 }; arrayMystery(a2);

_[6, 3]______________________

int[] a3 = { 1, 2, 3, 4 }; arrayMystery(a3);

_[2, 2, 3, 4]________________

int[] a4 = { 5, 5, 5, 5, 5 }; arrayMystery(a4);

_[20, 8, 6, 5, 10, 12]_______

int[] a5 = { 10, 8, 3, 5, 5, 12 }; arrayMystery(a5);

_[10, 5, 10, 5, 5]___________

6 of 11

7. Programming (12 points) Assume the following method exists: // returns true if the two integers are mirrors of each other // (i.e. one has the same digits in reverse order of the other) public static boolean areMirrors(int num1, int num2) For example: Call areMirrors(3, 3) areMirrors(321, 123) areMirrors(25, 50) areMirrors(101, 101)

Returns true true false true

Write a static method areDeepMirrors that takes two integer arrays as parameters and returns true if the two arrays are deep mirrors of each other. Two integer arrays are deep mirrors of each other if each contains the mirrors of the elements of the other in reverse order. The following table shows some sample calls to areDeepMirrors: If arr1 is: [ 123, 321 ] [ 1, 2, 3 ] [ 12, 5, 71 ] [ 15, 10 ] [ 12, 11, 13 ] [ 7 ]

And arr2 is: [ 123, 321 ] [ 3, 2, 1 ] [ 17, 5, 21 ] [ 10, 15 ] [ 21, 11, 31 ] [ 7 ]

areDeepMirrors(arr1, arr2) returns: true true true false false true

public static boolean areDeepMirrors(int[] arr1, int[] arr2) { int length = arr1.length; for (int i = 0; i < length; i++) { if (!areMirrors(arr1[i], arr2[length - 1 - i])) { return false; } } return true; }

7 of 11

8. Programming (21 points) In the game of glibwon, each player takes 10 rounds trying to score as many points as possible. In each round, a player can score up to ten points. If a player scores ten points in a round, it is called a mark. There are two types of marks, both worth ten points—skerits and seraps. If a player scores a serap, he or she gets 10 points, and also gets a bonus equal to his or her score in the next round. If a player scores a skerit, he or she gets 10 points and a bonus equal to twice his or her score in the next round. If a player gets a mark in the 10th round, they get an extra round to earn their bonus points.

(a) (14 points) Write a static method scoreGame that scores a game of glibwon for a single player. The method should take a single string argument that is a player’s name followed by his or her score for each round. Non-marks are represented by a digit (0-9), seraps are represented by a slash (/), and skerits are represented by an X. The method should print out the player’s name, their score, and the number of marks earned, then return the player’s score. The following table shows some possible calls to scoreGame. If str is: Brett 8 Will 9 Chris X Maia 8 Dian 9

9 9 X 8 9

7 / X 9 8

9 X 8 9 7

/ 8 9 X /

8 7 6 / 9

X 8 7 7 8

9 8 X 8 7

8 / 5 9 7

7 9 8 / 8 X 8

Then scoreGame(str) prints: Brett: 111 (2 marks) Will: 123 (3 marks) Chris: 149 (4 marks) Maia: 123 (3 marks) Dian: 109 (2 marks)

And returns: 111 123 149 123 109

You should match this output format exactly. You may assume the string is properly formatted and represents a proper game (i.e. either 10 or 11 round). You do not need to worry about singular or plural. // while loop solution public static int scoreGame(String scoreString) { int score = 0, marks = 0; int bonus = 1; Scanner scoreScan = new Scanner(scoreString); String name = scoreScan.next(); while (scoreScan.hasNext()) { if (scoreScan.hasNextInt()) { // regular score int round = scoreScan.nextInt(); score += round * bonus; bonus = 1; } else { // mark score += 10 * bonus; marks++; String mark = scoreScan.next(); if (mark.equals("X")) { bonus = 3; } else { // mark.equals("/") bonus = 2; } } } System.out.println(name + ": " + score + " (" + marks + " marks)"); return score; }

8 of 11

// for public int int int

loop solution static int scoreGame(String scoreString) { score = 0; bonus = 1; marks = 0;

Scanner scoreScan = new Scanner(scoreString); String name = scoreScan.next(); for (int i = 0; i < 10; i++) { if (scoreScan.hasNextInt()) { // regular score int round = scoreScan.nextInt(); score += round * bonus; bonus = 1; } else { // mark score += 10 * bonus; marks++; String mark = scoreScan.next(); if (mark.equals("X")) { bonus = 3; } else { // mark.equals("/") bonus = 2; } } } // mark in last round -> extra round if (bonus != 1) { int round = scoreScan.nextInt(); score += round * bonus; } System.out.println(name + ": " + score + " (" + marks + " marks)"); return score; }

9 of 11

(b)

(7 points) Using scoreGame, write a static method scoreTeam that takes a Scanner for an input file as a parameter. The input file will contain a team name on the first line, followed by glibwon games for each player on the team. The method should print out each player’s score, and then print the team’s total score. For example, if the input file team142.txt contains the following: Team CSE 142 Brett 8 9 7 9 / 8 X 9 8 7 Will 9 9 / X 8 7 8 8 / 9 Chris X X X 8 9 6 7 X 5 8 Maia 8 8 9 9 X / 7 8 9 / 8 Dian 9 9 8 7 / 9 8 7 7 X 8 Then the call scoreTeam(new Scanner(new File(“team142.txt”)) would output: Brett: 111 (2 marks) Will: 123 (3 marks) Chris: 149 (4 marks) Maia: 123 (3 marks) Dian: 109 (2 marks) Team CSE 142 Total: 615 You should match this output format exactly. You may assume scoreGame works correctly, regardless of what you wrote in part (a). public static void scoreTeam(Scanner scoreSheet) { String teamName = scoreSheet.nextLine(); int total = 0; while (scoreSheet.hasNextLine()) { total += scoreGame(scoreSheet.nextLine()); } System.out.println(); System.out.println(teamName + " Total: " + total); }

10 of 11

9. Classes and Objects (8 points) Suppose that you are provided with a pre-written class BankAccount as described at right. (The method headers are shown, but the bodies are omitted to save space.) Assume that the fields, constructor, and methods shown are implemented. You may refer to them or use them in solving this problem if necessary. Write an instance method named checkMinBalance that will be placed inside the BankAccount class to become a part of each BankAccount object's behavior. The checkMinBalance takes two parameters: a minimum balance and a fee amount. If the BankAccount object’s balance is below the minimum balance, the fee is deducted and false is returned. Otherwise, true is returned. The balance should not drop below zero—if there is not enough money in the account to cover the fee, set the balance to be zero.

// // // //

public class BankAccount { private String id; private double balance; private int transactions; // Constructs a BankAccount // object with the given id, and // 0 balance and transactions. public BankAccount(String id) // returns the field values public double getBalance() public String getID() // Adds the amount to the balance // if it is between 0-500. // Also counts as 1 transaction. public void deposit(double amount)

For example, given the following object: BankAccount myAccount = new BankAccount("Brett"); myAccount.deposit(100.00); myAccount.deposit(25.00); myAccount.deposit(40.00); myAccount.deposit(10.00);

At this point, the account has a balance of $175.00. If the following call were made:

A BankAccount keeps track of a user's money balance and ID, and counts how many transactions (deposits/withdrawals) are made.

// Subtracts the amount from // the balance if the user has // enough money. // Also counts as 1 transaction. public void withdraw(double amount) // your method would go here }

myAccount.checkMinBalance(150.00, 15.00) then the account would remain in its current state, and the method would return true. If this call were then made: myAccount.checkMinBalance(200.00, 25.00) then the account would have $25 deducted, leaving a balance of $150.00. The method would return false.

public boolean checkMinBalance(int minBalance, int fee) { if (balance < minBalance) { balance = Math.max(balance - fee, 0); return false; } return true; }

11 of 11