Scala 解决 Enigma problem Part 2

解密部分代码:

 

/**
 *
 */
package com.me.acm.problem1009

/**
 * @author Blues
 *
 */

object App {
  val CharSeq = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray
  val CharSeqLowerCae = CharSeq.map(c => c.toLower)
  def main(args: Array[String]): Unit = {
    readAndProcess(readLine, 1)
  }

  def readAndProcess(line: String, counter: Int) {
    val num = line.toInt
    if (num > 0) {

      val input = new Input(CharSeqLowerCae.take(num))
      var preDevice: Device = input;
      for (i <- 0 until 3) {
        val rotorLine = readLine
        val rotor = new Rotor(rotorLine.toCharArray, new Some(preDevice))
        preDevice = rotor
      }

      val output = new Output(CharSeq.take(num), new Some(preDevice))

//      encrpt(readLine, input, counter)
      decrpt(readLine, output, counter)
      readAndProcess(readLine, counter + 1)
    }
  }

  def encrpt(line: String, input: Input, counter: Int) {
    val num = line.toInt
    if (num > 0) {
      val text = readLine.toCharArray()
      val encrptedArray = for (c <- text) yield {
        input.encrpt(c)
      }

      println("Enigma " + counter + ":")
      println(encrptedArray.mkString(""))
    }
  }
  
  def decrpt(line: String, output: Output, counter: Int) {
    val num = line.toInt
    if (num > 0) {
      val text = readLine.toCharArray()
      val decrptedArray = for (c <- text) yield {
        output.decrpt(c)
      }

      println("Enigma " + counter + ":")
      println(decrptedArray.mkString(""))
    }
  }
}

abstract class Device(val codes: Array[Char]) {
  var nextDevice: Option[Device] = None
  val preDevice: Option[Device] = None
  def encrpt(inputIndex: Int): Char
  def decrpt(inputIndex: Int): Char
  def readyForNextToMove: Boolean
}

class Input(codes: Array[Char]) extends Device(codes) {
  def encrpt(inputIndex: Int): Char = {
    nextDevice match {
      case Some(next) => next.encrpt(inputIndex)
      case None => if (inputIndex < codes.length) codes(inputIndex) else '0'
    }
  }

  def encrpt(c: Char): Char = {
    encrpt(App.CharSeqLowerCae.indexOf(c))
  }

  def readyForNextToMove: Boolean = true

  def decrpt(inputIndex: Int): Char = {
    if (inputIndex < codes.length) codes(inputIndex) else '0'
  }
}

class Rotor(codes: Array[Char], override val preDevice: Some[Device]) extends Device(codes) {
  preDevice match {
    case Some(pre) => pre.nextDevice = new Some(this)
  }
  var stepCounter = 0

  var tunnels = for {
    i <- 0 until codes.length
  } yield {
    val code = codes(i)
    (i, App.CharSeq.indexOf(code))
  }

  def encrpt(inputIndex: Int): Char = {
    val tunnel = tunnels.find(_._1 == inputIndex)
    val outputIndex = tunnel match {
      case Some(x) => x._2
      case None => -1
    }

    //    println("found: " + inputIndex + ", " + outputIndex)  

    val encrpted = if (outputIndex >= 0) {
      this.nextDevice match {
        case Some(next) => next.encrpt(outputIndex)
        case None => '0'
      }
    } else {
      '0'
    }

    preDevice match {
      case Some(pre) => {
        if (pre.readyForNextToMove) {
          move
        }
      }
    }

    encrpted
  }

  private def move() {
    tunnels = for {
      tunnel <- tunnels
    } yield {
      ((tunnel._1 + 1) % codes.length, (tunnel._2 + 1) % codes.length)
    }
    stepCounter += 1
  }

  def readyForNextToMove: Boolean = if (stepCounter > 0) stepCounter % codes.length == 0 else false

  def decrpt(inputIndex: Int): Char = {
    val tunnel = tunnels.find(_._2 == inputIndex)
    val outputIndex = tunnel match {
      case Some(x) => x._1
      case None => -1
    }

    val decrpted = if (outputIndex >= 0) {
      this.preDevice match {
        case Some(pre) => pre.decrpt(outputIndex)
      }
    } else {
      '0'
    }

    preDevice match {
      case Some(pre) => {
        if (pre.readyForNextToMove) {
          move
        }
      }
    }
    
    decrpted
  }
}

class Output(codes: Array[Char], override val preDevice: Some[Device]) extends Device(codes) {
  preDevice match {
    case Some(pre) => pre.nextDevice = new Some(this)
  }
  override def encrpt(inputIndex: Int): Char = {
    if (inputIndex < codes.length) codes(inputIndex) else '0'
  }

  def decrpt(inputIndex: Int): Char = {
    preDevice match {
      case Some(pre) => pre.decrpt(inputIndex)
    }
  }
  
  def decrpt(code: Char): Char = {
    decrpt(codes.indexOf(code))
  }
  
  def readyForNextToMove = false
}   
 

你可能感兴趣的:(scala)