/**
 * Exercise 2.1 Suppose we have a crypto-system based on the following
 * substitution cipher, where each plain letter is encrypted according to the
 * following table.
 *
 *    |   Plain   | Encrypted |
 *    |     A     |     C     |
 *    |     B     |     A     |
 *    |     C     |     D     |
 *    |     D     |     B     |
 *
 * For example, the string BAD would be encrypted as ACB.
 * Write a function check that, given a plaintext string s1 and a ciphertext
 * string s2, returns true if, and only if, s2 is the ciphertext for s1. 
 * Your function should raise an exception if s1 is not a plaintext string.
 * How does your code scale as the alphabet gets larger?
 *
 */

def encryptSingleChar(c: Char) = c match {
  case 'A' => 'C'
  case 'B' => 'A'
  case 'C' => 'D'
  case 'D' => 'B'
  case _   =>
    throw new Exception("Invalid Argument " + c + " in encryptSingleChar")
}

def encryptString(s: String) = {
  def iter(i: Int, acc: String): String = 
    if (i == 0) encryptSingleChar(s(i)) + acc
    else iter(i - 1, encryptSingleChar(s(i)) + acc)
  iter(s.length - 1, "")
}

def compare(s1: String, s2: String) = 
  encryptString(s1) == s2


println("The 'BAD' string encrypted is " + encryptString("BAD"))