Computer Science A
2021 FRQ 1
- FRQ Question Overview
- Part A: scoreGuess()
- Code Runner Challenge
- Scoring Guidelines Part A
- Part B: findBetterGuess()
- Code Runner Challenge
- Scoring Guidelines Part B
FRQ Question Overview
This question involves the WordMatch class, which stores a secret string and provides methods that compare other strings to the secret string. You will write two methods in the WordMatch class.
The WordMatch class has:
- A private instance variable
secretthat stores the secret string - A constructor that initializes the secret string
- Two methods to implement:
scoreGuessandfindBetterGuess
Part A: scoreGuess()
Write the WordMatch method scoreGuess. To determine the score to be returned, scoreGuess finds the number of times that guess occurs as a substring of secret and then multiplies that number by the square of the length of guess. Occurrences of guess may overlap within secret.
Assume that the length of guess is less than or equal to the length of secret and that guess is not an empty string.
Example 1: WordMatch game = new WordMatch("mississippi");
| guess | Occurrences | Calculation | Return Value |
|---|---|---|---|
| “i” | 4 | 4 × 1 × 1 = 4 | 4 |
| “iss” | 2 | 2 × 3 × 3 = 18 | 18 |
| “issipp” | 1 | 1 × 6 × 6 = 36 | 36 |
| “mississippi” | 1 | 1 × 11 × 11 = 121 | 121 |
Example 2: WordMatch game = new WordMatch("aaaabb");
| guess | Occurrences | Calculation | Return Value |
|——-|————-|————-|————-|
| “a” | 4 | 4 × 1 × 1 = 4 | 4 |
| “aa” | 3 | 3 × 2 × 2 = 12 | 12 |
| “aaa” | 2 | 2 × 3 × 3 = 18 | 18 |
| “aabb” | 1 | 1 × 4 × 4 = 16 | 16 |
| “c” | 0 | 0 × 1 × 1 = 0 | 0 |
// CODE_RUNNER: Write the scoreGuess() method that returns the score based on substring occurrences
Code Runner Challenge
Methods and Control Structures - String manipulation
View IPYNB Source
// Main.java
public class Main {
public static void main(String[] args) {
// Test Part A
System.out.println("=== Test Case 1: 'mississippi' ===");
WordMatch game1 = new WordMatch("mississippi");
System.out.println("scoreGuess('i'): " + game1.scoreGuess("i") + " (expected: 4)");
System.out.println("scoreGuess('iss'): " + game1.scoreGuess("iss") + " (expected: 18)");
System.out.println("scoreGuess('issipp'): " + game1.scoreGuess("issipp") + " (expected: 36)");
System.out.println("scoreGuess('mississippi'): " + game1.scoreGuess("mississippi") + " (expected: 121)");
System.out.println();
System.out.println("=== Test Case 2: 'aaaabb' ===");
WordMatch game2 = new WordMatch("aaaabb");
System.out.println("scoreGuess('a'): " + game2.scoreGuess("a") + " (expected: 4)");
System.out.println("scoreGuess('aa'): " + game2.scoreGuess("aa") + " (expected: 12)");
System.out.println("scoreGuess('aaa'): " + game2.scoreGuess("aaa") + " (expected: 18)");
System.out.println("scoreGuess('aabb'): " + game2.scoreGuess("aabb") + " (expected: 16)");
System.out.println("scoreGuess('c'): " + game2.scoreGuess("c") + " (expected: 0)");
// Optional: quick Part B demo
System.out.println();
System.out.println("findBetterGuess('iss', 'i'): " + game1.findBetterGuess("iss", "i"));
}
}
// CODE_RUNNER: Methods and Control Structures - String manipulation
class WordMatch {
/** The secret string. */
private String secret;
/** Constructs a WordMatch object with the given secret string of lowercase letters. */
public WordMatch(String word) {
secret = word;
}
/** Returns a score for guess, as described in part (a).
* Precondition: 0 < guess.length() <= secret.length()
*/
public int scoreGuess(String guess) {
int count = 0;
int guessLen = guess.length();
// Loop through all possible starting positions in secret
for (int i = 0; i <= secret.length() - guessLen; i++) {
if (secret.substring(i, i + guessLen).equals(guess)) {
count++;
}
}
return count * guessLen * guessLen;
}
/** Part (b): returns the better guess based on scoreGuess.
* If scores tie, return the lexicographically smaller guess.
*/
public String findBetterGuess(String guess1, String guess2) {
int s1 = scoreGuess(guess1);
int s2 = scoreGuess(guess2);
if (s1 > s2) return guess1;
if (s2 > s1) return guess2;
// tie-breaker: lexicographically smaller
if (guess1.compareTo(guess2) <= 0) return guess1;
return guess2;
}
}
Main.main(null);
Scoring Guidelines Part A
5 points total:
- 1 point - Compares
guessto a substring ofsecret- Must use a proper string comparison method (
.equals()or.indexOf()) - Will NOT earn point if using
==instead of.equals()
- Must use a proper string comparison method (
- 1 point - Uses a substring of
secretwith correct length for comparison withguess- Substring must be the same length as
guess - Can still earn point even if using
==instead of.equals()
- Substring must be the same length as
- 1 point - Loops through all necessary substrings of
secret(no bounds errors)- Must not skip overlapping occurrences
- Loop bounds must be correct to avoid IndexOutOfBoundsException
- 1 point - Counts number of identified occurrences of
guesswithinsecret- Must be in context of a condition involving both
secretandguess - Can earn point even if count is initialized incorrectly or not at all
- Can earn point even if occurrences are identified incorrectly
- Must be in context of a condition involving both
- 1 point - Calculates and returns correct final score (algorithm)
- Formula: count × (length of guess)²
- Will NOT earn point if:
- Count is initialized incorrectly or not at all
- Fails to use a loop
- Fails to compare
guessto multiple substrings ofsecret - Counts the same matching substring more than once
- Uses a changed or incorrect guess length when computing the score
Common Mistakes:
- Using
==instead of.equals()for string comparison - Incorrect loop bounds causing array/string index errors
- Not checking all overlapping occurrences
- Forgetting to initialize count variable
- Incorrect score calculation (not squaring the length)
Part B: findBetterGuess()
Write the WordMatch method findBetterGuess, which returns the better guess of its two String parameters, guess1 and guess2.
Rules:
- If the
scoreGuessmethod returns different values forguess1andguess2, then the guess with the higher score is returned. - If the
scoreGuessmethod returns the same value forguess1andguess2, then the alphabetically greater guess is returned.
Example: WordMatch game = new WordMatch("concatenation");
| Method Call | Return Value | Explanation |
|---|---|---|
game.scoreGuess("ten") |
9 | 1 × 3 × 3 |
game.scoreGuess("nation") |
36 | 1 × 6 × 6 |
game.findBetterGuess("ten", "nation") |
“nation” | Since scoreGuess returns 36 for “nation” and 9 for “ten”, the guess with the greater score, “nation”, is returned. |
game.scoreGuess("con") |
9 | 1 × 3 × 3 |
game.scoreGuess("cat") |
9 | 1 × 3 × 3 |
game.findBetterGuess("con", "cat") |
“con” | Since scoreGuess returns 9 for both “con” and “cat”, the alphabetically greater guess, “con”, is returned. |
// CODE_RUNNER: Write the findBetterGuess() method that returns the better of two guesses
Code Runner Challenge
Methods and Control Structures - String manipulation
View IPYNB Source
// Main.java
public class Main {
public static void main(String[] args) {
System.out.println("=== Testing with 'concatenation' ===");
WordMatch_B game = new WordMatch_B("concatenation");
System.out.println();
System.out.println("--- Part A Tests ---");
System.out.println("scoreGuess('nation'): " + game.scoreGuess("nation") + " (expected: 36)");
System.out.println("scoreGuess('con'): " + game.scoreGuess("con") + " (expected: 9)");
System.out.println("scoreGuess('cat'): " + game.scoreGuess("cat") + " (expected: 9)");
System.out.println();
System.out.println("--- Part B Tests ---");
System.out.println("findBetterGuess('con', 'cat'): " +
game.findBetterGuess("con", "cat") + " (expected: con)");
}
}
// CODE_RUNNER: Methods and Control Structures - String manipulation
class WordMatch_B {
private String secret;
public WordMatch_B(String word) {
secret = word;
}
// Part A
public int scoreGuess(String guess) {
int count = 0;
int index = secret.indexOf(guess);
while (index != -1) {
count++;
index = secret.indexOf(guess, index + 1);
}
return count * guess.length() * guess.length();
}
// Part B
public String findBetterGuess(String guess1, String guess2) {
int score1 = scoreGuess(guess1);
int score2 = scoreGuess(guess2);
if (score1 > score2) {
return guess1;
} else if (score2 > score1) {
return guess2;
} else {
return (guess1.compareTo(guess2) > 0) ? guess1 : guess2;
}
}
}
Main.main(null);
Scoring Guidelines Part B
4 points total:
- 1 point - Calls
scoreGuessto get scores forguess1andguess2- Will NOT earn point if:
- Fails to include parameters in the method calls
- Calls the method on an object or class other than
this(implicit or explicit)
- Will NOT earn point if:
- 1 point - Compares the scores
- Will NOT earn point if:
- Only compares using
==or!=(must use relational operators) - Fails to use the result of the comparison in a conditional statement
- Only compares using
- Will NOT earn point if:
- 1 point - Determines which of
guess1andguess2is alphabetically greater- Can still earn point even if the comparison is reversed
- Will NOT earn point if:
- Reimplements
compareToincorrectly - Uses result of
compareToas if boolean (must compare to 0)
- Reimplements
- 1 point - Returns the identified
guess1orguess2(algorithm)- Can still earn point even if:
- Calls
scoreGuessincorrectly - Compares strings incorrectly
- Calls
- Will NOT earn point if:
- Reverses a comparison
- Omits either comparison (score or alphabetical)
- Fails to return a guess in some case
- Can still earn point even if:
Common Mistakes:
- Not calling
scoreGuessfor both guesses - Using
==or!=only without checking which score is greater - Incorrect use of
compareTo()(treating return value as boolean) - Reversing the logic of comparisons
- Missing return statements in some code paths
- Not handling the tie-breaker case (equal scores)