FRQ 1

  • This FRQ has you working the AppointmentBook class, which allows someone to book appointments in 8 periods, each of which has minutes 0-59
  • Appointments can only take consecutive minutes and must be contained within the same period
  • Helper functions of isMinuteFree (to see whether a mintue is used) and reserveBlock (to actually reserve a time slot)

FRQ 1a

  • You have to write a method findFreeBlock that takes in a period and length of time, and looks for the first consecutive block of time that is availiable
  • Examples given by CollegeBoard
  • My solution is below (with comments)
    public int findFreeBlock(int period, int duration) {
    // stores the start of the current block we are on
    int curStart = 0;
    // stores the length of the current block we are on
    int curLength = 0;
      
    // loop through all minutes in the period
    for (int i = 0; i<=59; i++) {
      if (isMinuteFree(period, i)) {
        // increase the length of our block
        curLength++;
      }
      else {
        // clear the current block as minutes must be consecutive
        curLength = 0;
        curStart = i+1;
      }
        
      // check if our block has reached the required length
      if (curLength == duration) {
        return curStart;
      }
    }
      
    // no suitable block has been found
    return -1;
    }
    

FRQ 1b

  • You now have to write the method makeAppointment using findFreeBlock to make an appointment within a period range with a certain duration
  • For this, you would use the helper method reserveBlock
  • Examples given by CollegeBoard
  • My solution is below (with comments)
    public boolean makeAppointment(int startPeriod, int endPeriod, int duration) {
    // loop through all the possible periods we could make an appointment in
    for (int period = startPeriod; period <= endPeriod; period++) {
      // look for a free block in this period
      int block = findFreeBlock(period, duration);
        
      // check if there is a block
      if (block != -1) {
        // reserve this block
        reserveAppointment(period, block, duration);
        return true;
      }
    }
      
    // no suitable block found
    return false;
    }
    

FRQ 2

  • This FRQ is about class definitions, specifically for the Sign class
  • Sign class constructor has 2 params: message and width
  • message is split according to the width to display on a sign
  • numberOfLines method returns int of amount of lines needed to display
  • getLines returns message split with semicolons
public Sign {
  // initialize private variables
  private int width;
  private String message;

  // constructor
  public Sign(String message, int width) {
    this.message = message;
    this.width = width;
  }

  // returns number of lines needed to display message
  public int numberOfLines() {
    // if message length is divisible by width, return message length / width
    int numLines = message.length() / width;

    // if message length is not divisible by width, add 1 to numLines
    // checks edge case for not divisible
    if (message.length() % width != 0) {
      numLines++;
    }

    return numLines;
  }

  // returns string needed to display message
  public String getLines() {
    // initialize string to return
    String lines = "";

    // loop through message
    for (int i = 0; i < message.length(); i++) {
      // if index is divisible by width, add semicolon
      if (i % width == 0 && i != 0) {
        lines += ";";
      }
    
      // add character to lines
      lines += message.charAt(i);
    }

    if (lines.length() == 0) {
      lines = null;
    }

    return lines;
  }
}

FRQ 3

  • This FRQ requires you to analyze weather data from the WeatherData class
  • The ArrayList called temperatures stores the temperatures for the different days and all temperatures are doubles

FRQ 3a

  • You have to write a method cleanData that modifiers the temperatures instance variable and removes all temperatures that are less than the lower parameter OR greater than the upper parameter
  • Examples given by CollegeBoard
    public void cleanData(double lower, double upper) {
      // Iterates through each element in the temperatures
      for (int i = 0; i < temperatures.size(); i++) {
          // Checks if the temperature is outside the boundaries
          if (temperatures.get(i) > upper || temperatures.get(i) < lower) {
              // Remove the element from temperatures
              temperatures.remove(i);
              // Goes back one index to avoid off by one error
              i--;
          }
      }
    }
    

FRQ 3b

  • You now have to write the method longestHeatWave to find the length of the longest heat wave
  • A heat wave is a set of consecutive days that have temperatures which exceed the threshold
  • Examples given by CollegeBoard
    public int longestHeatWave(double threshold) {
      // Creates variables for current heatwave length and maximum heatwave length
      int current = 0;
      int max = 0;
      // Iterates through each element in temperatures
      for (int i = 0; i < temperatures.size(); i++) {
          // If the temperature is greater than the threshold
          if (temperatures.get(i) > threshold) {
              // Add one to the current heatwave length
              current++;
              // If the length of the current heatwave is greater than the maximum heatwave, set the current heatwave to the maximum value
              if (current > max) {
                  max = current;
              }
          }
          // If the temperature is less than the threshold, the heatwave has ended so set the current heatwave length to 0 
          else {
              current = 0;
          }
      }
      // Return the length of the longest heatwave
      return max;
    }
    

FRQ 4

  • This FRQ gives you a 2D array where each object in the 2D array is of Candy type
  • You also have a method getFlavor which returns the flavor of a candy
  • Any element in the 2D array can either have a Candy or be null

FRQ 4a

  • You have to write a method moveCandyToFirstRow which moves a candy to the first row in the given column if a candy doesn’t already exist there
  • If a candy is not present, start from the next row and check for a candy in that column to move to the first row
  • After the program is completed, if a candy is moved to or already in the first row, return true. If not, return false
  • Examples given by CollegeBoard
    public boolean moveCandyToFirstRow(int col) {
      // Checks if the first row already has a candy
      if (box[0][col] != null) {
          return true;
      }
      else {
          // If there is no candy, check each row for a candy
          for (int i = 0; i < box.length; i++) {
              // If there is a candy in the row, move it to the first row and remove it from row i and return true
              if (box[i][col] != null) {
                  box[0][col] = box[i][col];
                  box[i][col] = null;
                  return true;
              }
          }
      }
      // If no candy is found in every row of the given column, return false
      return false;
    }
    

FRQ 4b

  • You now have to write the method removeNextByFlavor which iterates through the 2D array starting from the bottom left. If there is a Candy that has the same flavor as the parameter flavor, remove that Candy and return it.
  • If no Candy in the 2D array has that flavor, return null.
  • Examples given by CollegeBoard
    public Candy removeNextByFlavor(String flavor) {
      // Iterate through each element by starting at the bottom left 
      for (int row = box.length - 1; row >= 0; row--) {
          for (int col = 0; col < box[0].length; col++) {
              // Store the candy in a variable called c
              Candy c = box[row][col];
              // If a candy exists and its flavor equals the given flavor, remove the candy and return it
              if (c != null) {
                  if (c.getFlavor().equals(flavor)) {
                      box[row][col] = null;
                      return c;
                  }
              }  
          }
      }
      // If no candy has a matching flavor, return null
      return null;
    }