RouteCipher free response answer 7

The RouteCipher problem from the 2011 AP Computer Science Exam is typical of free response problems that test 2 dimensional arrays. The problem requires you to traverse the array in row major order, which is most easily accomplished with a nested for loop.

Review the RouteCipher free response problem with AP CS Tutor Brandon Horn.

RouteCipher Part (a): fillBlock

 private void fillBlock(String str)
 {
  int strIndex = 0;

  for (int r = 0; r < numRows; r++)
  {
   for (int c = 0; c < numCols; c++)
   {
    if (strIndex >= str.length())
     letterBlock[r][c] = "A";
    else
     letterBlock[r][c] = str.substring(strIndex, strIndex + 1);

    strIndex++;
   }
  }
 }

RouteCipher Part (a): fillBlock – alternate solution

  private void fillBlock(String str)
  {
    for (int i = 0; i < numRows * numCols; i++)
    {
      if (i >= str.length())
        letterBlock[i / numCols][i % numCols] = "A";
      else
        letterBlock[i / numCols][i % numCols] = str.substring(i, i + 1);
    }
  }

RouteCipher Part (b): encryptMessage

public String encryptMessage(String message)
{
  String cipherText = "";
  int mIndex = 0;
  
  while(mIndex < message.length())
  {
    fillBlock(message.substring(mIndex);  // ignores extra characters
    cipherText += encryptBlock();
    mIndex += numRows * numCols;
  }
  
  return cipherText;
}

RouteCipher Part (b): encryptMessage – alternate solution 1

 public String encryptMessage(String message)
 {
  String cipherText = "";

  while (message.length() > 0)
  {
   fillBlock(message); // ignores extra characters
   cipherText += encryptBlock();
   if(message.length() > numRows * numCols)
    message = message.substring(numRows * numCols);
   else
    message = "";
  }

  return cipherText;
 }

RouteCipher Part (b): encryptMessage – alternate solution 2

  public String encryptMessage(String message)
  {
    String cipherText = "";
    
    for(int i = 0; i < message.length(); i += numRows * numCols)
    {
      fillBlock(message.substring(i));
      cipherText += encryptBlock();
    }

    return cipherText;
  }

This is the same as the first solution except with a for loop.

Get AP CS Help

2011 AP CS Exam Free Response Solutions

Recommended Practice Problems

7 thoughts on “RouteCipher free response answer

  1. Reply Zac May 5,2011 9:46 pm

    for part a, would this work?
    int k=0;
    int size=string.length(); string temp=””;
    while(k<numRows*numCols){
    if(k<size)
    temp=string.substring(k,k+1);
    else temp="A";
    int row=k/numCols;
    int col=k%numCols;
    letterBlock[row][col]=temp;
    k++;
    }

    • Reply Brandon Horn May 6,2011 12:11 pm

      Your logic is correct; however, you have some minor syntax errors. Here is a working version using your logic.

       public void fillBlock(String str)
       {
        int k=0;
        int size=str.length();
        String temp= "";
      
        while(k < numRows * numCols)
        {
         if(k<size)
          temp=str.substring(k,k+1);
         else
          temp="A";
         int row=k/numCols;
         int col=k%numCols;
         letterBlock[row][col]=temp;
         k++;
        }
       }
      
  2. Reply Jess Dec 21,2011 2:30 am

    for part b, I am not sure if I understood this correctly, but

    fillBlock(message); doesn’t this line fill the array with the message?? not concatenate it??

    Thank You

    • Reply Brandon Horn Dec 21,2011 6:34 am

      fillBlock(message) starts at the beginning of the message and copies as much of the message as possible into the array. If there are more characters in the message than there are spaces in the array, fillBlock ignores the remaining characters in the message. If there are fewer characters in the message than there are spaces in the array, fillBlock fills each remaining space in the array with "A". Each time fillBlock is run everything previously in the array is removed.

      In part (b), encryptMessage repeatedly:
      – fills the array using fillBlock (regardless of the number of characters that remain in the message)
      – encrypts the array by calling encryptBlock
      – concatenates the existing ciphertext with the encrypted result
      – removes the number of characters encrypted from the front of the message

  3. Reply Helen Apr 18,2012 1:29 am

    Is there a way to do it using a for loop?
    This is what I was trying to do:

    int size = numRows * numCols;
    String encrypted = “”;
    if(message.length()==0)
    return encrypted; //to return an empty string right away without filling block entirely of “A”s (is this needed?)

    else //problem starts here..:(
    {
    for(int k=0; k<message.length(); k+=size)
    {
    fillBlock(message.substring(k, k+size); //Q: How do you do this without causing indexOutOfBoundsException at the last loop?
    encrypted += encryptBlock();
    }
    }
    return encrypted;

    Also, please let me know if there are any other mistakes.
    Thank you!

    • Reply Brandon Horn Apr 18,2012 2:39 pm

      Both parts can be done with simple for loops. I added an alternate solution for each part that demonstrates the technique. The problem with your code is the second parameter to substring. fillBlock already ignores excess characters. It is unnecessary to obtain a substring of the exact length and results in an exception on the last run.

Leave a Reply