Sprint View

2016 FRQ Q1

10 min read
  • Code Runner Challenge
  • Code Runner Challenge
  • Code Runner Challenge
  • Code Runner Challenge

Part (a): RandomStringChooser Class

A RandomStringChooser object is constructed from an array of non-null String values. When first constructed, all strings are considered available.

The getNext method behavior:

  • Returns a randomly chosen string from the available strings
  • Once a string is returned, it is no longer available for subsequent calls
  • If no strings are available, returns “NONE”

Example behavior:

Code Runner Challenge

RandomStringChooser

View IPYNB Source

String[] wordArray = {"wheels", "on", "the", "bus"};
RandomStringChooser sChooser = new RandomStringChooser(wordArray);
for (int k = 0; k < 6; k++)
{
    System.out.print(sChooser.getNext() + " ");
}

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Possible output: bus the wheels on NONE NONE

Requirements:

  • Include an appropriate constructor
  • Include any necessary methods
  • All instance variables must be private
  • Do not alter the parameter passed to the constructor (but you may copy the array contents)

// CODE_RUNNER: <challenge text>

Code Runner Challenge

RandomLetterChooser

View IPYNB Source
// CODE_RUNNER: RandomStringChooser

import java.util.Arrays;

class RandomStringChooser
{
    // Declare private instance variables here
    

    // Constructor: accepts an array of non-null String values
    public RandomStringChooser(String[] arr)
    {
        // TODO: student implementation
    }
    
    // getNext method: returns a randomly chosen available string, or "NONE" if none available
    public String getNext()
    {
        // TODO: student implementation
        return null;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("=== RandomStringChooser Test Cases ===");

        String[] words = {"apple", "banana", "cherry"};
        RandomStringChooser chooser = new RandomStringChooser(words);

        System.out.println("Initial words: " + Arrays.toString(words));

        String r1 = chooser.getNext();
        System.out.println("Call 1 -> " + r1 + " | Expected: one of the words");

        String r2 = chooser.getNext();
        System.out.println("Call 2 -> " + r2 + " | Expected: different unused word");

        String r3 = chooser.getNext();
        System.out.println("Call 3 -> " + r3 + " | Expected: last unused word");

        String r4 = chooser.getNext();
        System.out.println("Call 4 -> " + r4 + " | Expected: NONE");

        if ("NONE".equals(r4)) {
            System.out.println("✔ Test Passed: NONE returned when no strings left");
        } else {
            System.out.println("✘ Test Failed: Expected NONE when exhausted");
        }
    }
}

Main.main(null);

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Part (b): RandomLetterChooser Class

The following partially completed RandomLetterChooser class is a subclass of the RandomStringChooser class. You will write the constructor for the RandomLetterChooser class.

Code Runner Challenge

Solution RandomStringChooser

View IPYNB Source

public class RandomLetterChooser extends RandomStringChooser
{
    /** Constructs a random letter chooser using the given string str.
     * Precondition: str contains only letters.
     */
    public RandomLetterChooser(String str)
    { /* to be implemented in part (b) */ }
    
    /** Returns an array of single-letter strings.
     * Each of these strings consists of a single letter from str. Element k
     * of the returned array contains the single letter at position k of str.
     * For example, getSingleLetters("cat") returns the
     * array { "c", "a", "t" }.
     */
    public static String[] getSingleLetters(String str)
    { /* implementation not shown */ }
}

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

The following code segment shows an example of using RandomLetterChooser.

Code Runner Challenge

Solution RandomLetterChooser

View IPYNB Source

RandomLetterChooser letterChooser = new RandomLetterChooser("cat");
for (int k = 0; k < 4; k++)
{
    System.out.print(letterChooser.getNext());
}

Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

The code segment will print the three letters in “cat” in one of the possible orders. Because there are only three letters in the original string, the code segment prints “NONE” the fourth time through the loop. One possible output is shown below:

actNONE

Assume that the RandomStringChooser class that you wrote in part (a) has been implemented correctly and that getSingleLetters works as specified. You must use getSingleLetters appropriately to receive full credit.

Complete the RandomLetterChooser constructor below.

Requirements:

  • Constructs a random letter chooser using the given string str.
  • Precondition: str contains only letters.

// CODE_RUNNER: <challenge text>

// CODE_RUNNER: RandomLetterChooser

class RandomLetterChooser
{
    // Declare private instance variables here
    

    // Constructor: accepts a non-empty String
    public RandomLetterChooser(String str)
    {
        // TODO: student implementation
    }
    
    // getNext method: returns a randomly chosen available letter,
    // or "NONE" if no letters remain
    public String getNext()
    {
        // TODO: student implementation
        return null;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("=== RandomLetterChooser Test Cases ===");

        String input = "cat";
        RandomLetterChooser chooser = new RandomLetterChooser(input);

        System.out.println("Input string: " + input);

        String r1 = chooser.getNext();
        System.out.println("Call 1 -> " + r1 + " | Expected: one of [c, a, t]");

        String r2 = chooser.getNext();
        System.out.println("Call 2 -> " + r2 + " | Expected: different unused letter");

        String r3 = chooser.getNext();
        System.out.println("Call 3 -> " + r3 + " | Expected: last unused letter");

        String r4 = chooser.getNext();
        System.out.println("Call 4 -> " + r4 + " | Expected: NONE");

        if ("NONE".equals(r4)) {
            System.out.println("✔ Test Passed: NONE returned when no letters left");
        } else {
            System.out.println("✘ Test Failed: Expected NONE when exhausted");
        }
    }
}

Main.main(null);

Original FRQ Packet

Original Rubric Guide

Part (a) — RandomStringChooser

1) Starting point (empty):

public class RandomStringChooser {
    // nothing implemented yet
}

Task: Declare private instance variables to hold a copy of the choices and the number available.

Solution:

private String[] choices;
private int available;

Explanation: We keep a copy of the input array so we don’t modify the caller’s array; available tracks how many entries are still selectable.


2) Task: Implement constructor that copies the parameter array and initializes available.

Solution:

public RandomStringChooser(String[] arr) {
    choices = java.util.Arrays.copyOf(arr, arr.length);
    available = choices.length;
}

Explanation: Arrays.copyOf makes a new array with the same contents; this satisfies the rubric requirement not to alter the passed-in array reference.


3) Task: Implement getNext to return a random available string or “NONE” if none remain.

Solution:

public String getNext() {
    if (available == 0) return "NONE";
    int r = (int)(Math.random() * available);
    String res = choices[r];
    // replace chosen spot with last available element
    choices[r] = choices[available - 1];
    choices[available - 1] = null; // optional
    available--;
    return res;
}

Explanation: Choosing r from 0..available-1 gives each available item equal chance. Swapping the last available element into r removes the chosen element in O(1) time without shifting.


4) Final combined Part (a) class (paste-ready):

// CODE_RUNNER: Solution RandomStringChooser

import java.util.Arrays;

class RandomStringChooser
{
    private String[] choices;
    private int available;

    // Constructor: accepts an array of non-null String values
    public RandomStringChooser(String[] arr)
    {
        choices = Arrays.copyOf(arr, arr.length);
        available = choices.length;
    }

    // getNext method: returns a randomly chosen available string, or "NONE" if none available
    public String getNext()
    {
        if (available == 0) {
            return "NONE";
        }

        int r = (int)(Math.random() * available);
        String res = choices[r];
        choices[r] = choices[available - 1];
        choices[available - 1] = null;
        available--;
        return res;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("=== RandomStringChooser Test Cases ===");

        String[] words = {"apple", "banana", "cherry"};
        RandomStringChooser chooser = new RandomStringChooser(words);

        System.out.println("Initial words: " + Arrays.toString(words));

        String r1 = chooser.getNext();
        System.out.println("Call 1 -> " + r1 + " | Expected: one of the words");

        String r2 = chooser.getNext();
        System.out.println("Call 2 -> " + r2 + " | Expected: different unused word");

        String r3 = chooser.getNext();
        System.out.println("Call 3 -> " + r3 + " | Expected: last unused word");

        String r4 = chooser.getNext();
        System.out.println("Call 4 -> " + r4 + " | Expected: NONE");

        if ("NONE".equals(r4)) {
            System.out.println("✔ Test Passed: NONE returned when no strings left");
        } else {
            System.out.println("✘ Test Failed: Expected NONE when exhausted");
        }
    }
}

Main.main(null);

Explanation: This completes the rubric for Part (a): private instance variables, safe constructor copying, and a correct getNext implementation.

Part (b) — RandomLetterChooser

1) Starting point (empty / placeholder constructor only):

public class RandomLetterChooser extends RandomStringChooser {
    public RandomLetterChooser(String str) {
        // empty
    }

    public static String[] getSingleLetters(String str) {
        // empty
    }
}

Task: Convert the string into a String[] of single-letter strings and pass it to the superclass so we reuse Part (a) behavior.

Solution (constructor):

public RandomLetterChooser(String str) {
    super(getSingleLetters(str));
}

Explanation: RandomStringChooser already implements the random removal logic. Passing the single-letter array to super(...) avoids duplication and meets the rubric.


2) Task: Implement getSingleLetters to return single-character String elements for each character in str.

Solution:

public static String[] getSingleLetters(String str) {
    String[] letters = new String[str.length()];
    for (int i = 0; i < str.length(); i++) {
        letters[i] = str.substring(i, i + 1);
    }
    return letters;
}

Explanation: substring(i, i+1) yields a String containing the single character at index i. This meets the precondition (str contains only letters) and produces the required String[] format.


3) Final combined Part (b) class (paste-ready):

// CODE_RUNNER: Solution RandomLetterChooser

import java.util.Arrays;

class RandomStringChooser
{
    private String[] choices;
    private int available;

    public RandomStringChooser(String[] arr)
    {
        choices = Arrays.copyOf(arr, arr.length);
        available = choices.length;
    }

    public String getNext()
    {
        if (available == 0) {
            return "NONE";
        }

        int r = (int)(Math.random() * available);
        String res = choices[r];
        choices[r] = choices[available - 1];
        choices[available - 1] = null;
        available--;
        return res;
    }
}

class RandomLetterChooser extends RandomStringChooser
{
    public RandomLetterChooser(String str)
    {
        super(getSingleLetters(str));
    }

    public static String[] getSingleLetters(String str)
    {
        String[] letters = new String[str.length()];
        for (int i = 0; i < str.length(); i++) {
            letters[i] = str.substring(i, i + 1);
        }
        return letters;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        System.out.println("=== RandomLetterChooser Test Cases ===");

        String input = "cat";
        RandomLetterChooser chooser = new RandomLetterChooser(input);

        System.out.println("Input string: " + input);

        System.out.println("Call 1 -> " + chooser.getNext() + " | Expected: one of [c, a, t]");
        System.out.println("Call 2 -> " + chooser.getNext() + " | Expected: different unused letter");
        System.out.println("Call 3 -> " + chooser.getNext() + " | Expected: last unused letter");
        System.out.println("Call 4 -> " + chooser.getNext() + " | Expected: NONE");
        
    }
}

Main.main(null);

Explanation: With getSingleLetters and the super call, Part (b) reuses Part (a)’s behavior and satisfies the rubric step-by-step.

Usage example (both classes together):

String[] words = {"wheels", "on", "the", "bus"};
RandomStringChooser rsc = new RandomStringChooser(words);
for (int i = 0; i < 6; i++) System.out.print(rsc.getNext() + " ");

RandomLetterChooser rlc = new RandomLetterChooser("cat");
for (int i = 0; i < 4; i++) System.out.print(rlc.getNext());

Part (a): RandomStringChooser

Total: 7 points

Intent: Define implementation of a class to choose a random string.

  • +1 Uses correct class, constructor, and method headers
  • +1 Declares appropriate private instance variable(s)
  • +1 Initializes all instance variable(s) Point lost if parameter is not used in any initialization Implements getNext (4 points total)
  • +1 Generates a random number in the proper range Point lost for improper or missing cast
  • +1 Chooses a string from an instance variable using the generated random number
  • +1 Updates state appropriately Point lost if constructor parameter is altered
  • +1 Returns the chosen string or “NONE” as appropriate

Part (b): RandomLetterChooser

Total: 2 points

Intent: Define implementation of a constructor of a class that extends RandomStringChooser.

  • +1 getSingleLetters(str)
  • +1 super(getSingleLetters(str)); Point lost if not the first statement in the constructor

Course Timeline