You are on page 1of 10

CS 3500 Fall 2014

Practice Midterm
To answer the first nine questions on this exam, you will need to refer to the Java code
starting on page 6.

1. Where n stands for the length of the parameter word, what is the asymptotic time complexity of the constructor Hangman(String) (line 61 on p. 6)?
A. O(1)

B. O(log n)

C. O(n)

D. O(n log n)

E. none of these

2. Where n stands for the length of the field secret, what is the asymptotic time complexity of method guess(char) (line 85 on p. 7)?
A. O(1)

B. O(log n)

C. O(n)

D. O(n log n)

E. none of these

3. Where n stands for the length of the field secret, what is the asymptotic time complexity of method isWon() (line 148 on p. 8)?
A. O(1)

B. O(log n)

C. O(n)

D. O(n log n)

E. none of these

4. Which of the following are class invariants of Hangman? Circle T if the statement is a
class invariant, and F if it is not.
(a) Array guess and string secret have the same length.

(b) The sum blanksRemaining + guessesRemaining is greater than 0.

T F

(c) The guessed character c (line 85 on p. 7) is not an element of set pastGuesses.


T F
(d) For any character c and valid index i, if guess[i] == c and c != _ then
secret.charAt(i) == c.

T F

(e) The same character is not guessed twice.

(f) Integer guessesRemaining is not 0.

5. Which of these are preconditions of method guess(char) (line 85 on p. 7)? For our purposes, preconditions are assertions that must hold when the method is invoked for it to
return the right result according to its purpose statement, but that are not guaranteed
by the class invariants alone. Circle T if the statement is a precondition, and F if it is
not.
(a) Array guess and string secret have the same length.

(b) Integer blanksRemaining is greater than 0.

(c) The size of set pastGuesses is greater than 0.

(d) The guessed character c (line 85 on p. 7) is not an element of set pastGuesses.


T F
(e) The guessed character c (line 85 on p. 7) is an uppercase letter.

(f) The same character is not guessed twice.

(g) Integer guessesRemaining is less than or equal to 7.

T F

6. Method Object.clone() makes a copy of an object, for objects that support it. Method
wordState() (line 139 on p. 8) returns guess.clone(). Why return a copy rather than
the original?

Page 2

7. Suppose we changed class Hangman as follows:


Delete the declaration of field blanksRemaining on line 49 (p. 6).
Replace the definition of method blanksRemaining() (line 176 on p. 9) with this:
public int blanksRemaining() {
int count = 0;
for (Character c : guess) {
if (c == _) {
++count;
}
}
return count;
}

Replace all other references to field blanksRemaining with an invocation of method


blanksRemaining() instead.
Discuss, briefly, the consequences of this change.

Page 3

8. The hash table lookup on line 97 (p. 7) takes constant time. What would happen to the
asymptotic time complexity of method guess (line 85 on p. 7) if pastGuesses were an
ArrayList instead of a HashSet?

9. Consider the for loop starting on line 105 (p. 7). Suppose that, instead of doing the
search ourselves, we used Javas String.indexOf(char) method, which returns the index of the char if found and -1 otherwise:
int index = secret.indexOf(c);
if (index >= 0) {
guess[index] = c;
goodGuess = true;
--blanksRemaining;
}

Discuss, briefly, the consequences of this change.

Page 4

10. Complete the definition of this method:


/**
* Finds the index of the smallest positive increase in values.
* That is, we consider the changes between adjacent elements,
* and find the smallest positive change, if there is one. Then
* it returns the index of the element after the change. If the
* smallest increase is not unique, it returns the index of the
* first such occurrence.
*
* For example,
{@code findSmallestIncrease(Arrays.asList(9, 1, 3, 2, 7))}
*
returns
{@code 2}, because the smallest increase is from
*
* 1 to 3, and 2 is the index of 3 in the array.
*
* @param list the list to search
* @return the index of (after) the largest increase
* @throws IllegalArgumentException if there is no increase
*/
public static int findSmallestIncrease(ArrayList<Integer> list) {

Page 5

36
37
38
39

/ **
* A class for playing the game hangman.
*/

public final class Hangman {

40

// The secret string we are trying to guess:

41

private final String secret;

42

// The users guess so far, with {@code _ } for blanks:

43

private final char[] guess;

44

// The set of incorrect characters guessed so far:

45

private final Collection<Character> pastGuesses = new HashSet<>();

46

// The number of guesses remaining before the game is lost:

47

private int guessesRemaining = GUESS_LIMIT;

48

// The number of characters yet to guess:

49

private int blanksRemaining;

50
51

/ **
* The number of wrong guesses allowed before the game is lost.
*/

52
53
54

public static final int GUESS_LIMIT = 7;

55
56

/ **
* Creates a new hangman game with the given secret word.
*
* @param word the secret word
*/

57
58
59
60
61
62
63
64

public Hangman(String word) {


if (word.length() == 0) {
throw new IllegalArgumentException("Word cannot be empty.");
}

65

for (char c : word.toCharArray()) {


checkValidCharacter(c);
}

66
67
68
69

secret
guess
blanksRemaining

70
71
72

= word;
= new char[word.length()];
= word.length();

73

Arrays.fill(guess, _);

74
75

Page 6

76

/ **
* Handles a guess that the given character is in the secret word.
*
* @param c the guess
* @return whether the guess was correct
* @throws IllegalStateException the game is over
* @throws IllegalArgumentException the character has already
been guessed
*
/
*

77
78
79
80
81
82
83
84
85
86

public boolean guess(char c) {


checkValidCharacter(c);

87

if (isLost()) {
throw new IllegalStateException("You already lost.");
}

88
89
90
91

if (isWon()) {
throw new IllegalStateException("You already won.");
}

92
93
94
95
96

// Note: HashSet.contains is constant time.

97

if (pastGuesses.contains(c)) {
throw new IllegalArgumentException("Already guessed: " + c);
}

98
99
100

pastGuesses.add(c);

101
102

boolean goodGuess = false;

103
104

for (int i = 0; i < secret.length(); ++i) {


if (secret.charAt(i) == c) {
guess[i] = c;
goodGuess = true;
--blanksRemaining;
}
}

105
106
107
108
109
110
111
112

if (!goodGuess) {
--guessesRemaining;
}

113
114
115
116

return goodGuess;

117
118

119

Page 7

120
121
122
123
124
125
126
127
128
129
130

/ **
* Raises an exception if the given character is not a valid
* word character. Uppercase letters are valid; others are not.
*
* @param c the character to check
*/

private static void checkValidCharacter(char c) {


if (! Character.isUpperCase(c)) {
throw new IllegalArgumentException("Illegal character: " + c);
}
}

131
132
133
134
135
136
137
138
139
140
141

/ **
* Returns the current state of the word we are guessing.
* Blanks (characters that havent been guessed yet) are
* represented by {@code _ }.
*
* @return
*/

public char[] wordState() {


return guess.clone();
}

142
143
144
145
146
147
148
149
150

/ **
* Returns whether the game has been won.
*
* @return whether the game has been won.
*/

public boolean isWon() {


return blanksRemaining == 0;
}

151
152
153
154
155
156
157
158
159

/ **
* Returns whether the game has been lost.
*
* @return whether the game has been lost.
*/

public boolean isLost() {


return guessesRemaining == 0;
}

Page 8

160

/ **
* Returns the number of guesses remaining before the game is
* lost.
*
* @return the number of guesses remaining
*/

161
162
163
164
165
166
167
168

public int guessesRemaining() {


return guessesRemaining;
}

169
170

/ **
* Returns the number of character positions left to guess to win
* the game.
*
* @return the number of blanks
*/

171
172
173
174
175
176
177
178

public int blanksRemaining() {


return blanksRemaining;
}

179
180
181

public class HangmanExamples {


Hangman game = new Hangman("APPLE");

182
183
184
185
186
187
188
189
190
191
192

@Test
public void exampleLose() {
assertTrue(game.guess(A));
assertFalse(game.guess(B));
assertFalse(game.guess(C));
assertFalse(game.guess(D));
assertTrue(game.guess(E));
assertFalse(game.guess(F));
assertFalse(game.guess(G));
assertFalse(game.guess(H));

193

assertFalse(game.isWon());
assertFalse(game.isLost());

194
195
196

assertFalse(game.guess(I));
assertFalse(game.isWon());
assertTrue(game.isLost());

197
198
199
200

Page 9

@Test
public void exampleWin() {
assertArrayEquals(new char[] {_,_,_,_,_},
game.wordState());
assertEquals(7, game.guessesRemaining());
assertEquals(5, game.blanksRemaining());

201
202
203
204
205
206
207

assertTrue(game.guess(P));
assertArrayEquals(new char[] {_,P,P,_,_},
game.wordState());
assertEquals(7, game.guessesRemaining());
assertEquals(3, game.blanksRemaining());

208
209
210
211
212
213

assertFalse(game.guess(Q));
assertArrayEquals(new char[] {_,P,P,_,_},
game.wordState());
assertEquals(6, game.guessesRemaining());
assertEquals(3, game.blanksRemaining());

214
215
216
217
218
219

assertTrue(game.guess(E));
assertTrue(game.guess(A));
assertFalse(game.guess(I));
assertArrayEquals(new char[] {A,P,P,_,E},
game.wordState());
assertEquals(5, game.guessesRemaining());
assertEquals(1, game.blanksRemaining());

220
221
222
223
224
225
226
227

assertFalse(game.isWon());
assertFalse(game.isLost());

228
229
230

assertTrue(game.guess(L));
assertTrue(game.isWon());
assertFalse(game.isLost());

231
232
233

234
235

Page 10

You might also like