Sprint View

2021 FRQ 1

8 min read

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 secret that stores the secret string
  • A constructor that initializes the secret string
  • Two methods to implement: scoreGuess and findBetterGuess

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);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Scoring Guidelines Part A

5 points total:

  1. 1 point - Compares guess to a substring of secret
    • Must use a proper string comparison method (.equals() or .indexOf())
    • Will NOT earn point if using == instead of .equals()
  2. 1 point - Uses a substring of secret with correct length for comparison with guess
    • Substring must be the same length as guess
    • Can still earn point even if using == instead of .equals()
  3. 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
  4. 1 point - Counts number of identified occurrences of guess within secret
    • Must be in context of a condition involving both secret and guess
    • Can earn point even if count is initialized incorrectly or not at all
    • Can earn point even if occurrences are identified incorrectly
  5. 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 guess to multiple substrings of secret
      • 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 scoreGuess method returns different values for guess1 and guess2, then the guess with the higher score is returned.
  • If the scoreGuess method returns the same value for guess1 and guess2, 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);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Scoring Guidelines Part B

4 points total:

  1. 1 point - Calls scoreGuess to get scores for guess1 and guess2
    • 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)
  2. 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
  3. 1 point - Determines which of guess1 and guess2 is alphabetically greater
    • Can still earn point even if the comparison is reversed
    • Will NOT earn point if:
      • Reimplements compareTo incorrectly
      • Uses result of compareTo as if boolean (must compare to 0)
  4. 1 point - Returns the identified guess1 or guess2 (algorithm)
    • Can still earn point even if:
      • Calls scoreGuess incorrectly
      • Compares strings incorrectly
    • Will NOT earn point if:
      • Reverses a comparison
      • Omits either comparison (score or alphabetical)
      • Fails to return a guess in some case

Common Mistakes:

  • Not calling scoreGuess for 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)

Course Timeline