用Scala 解决Gnome Tetravex

Gnome Teltravex 是一个ACM练习题目,完整的描述在这里http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=8

我主要是为了学习scala语言,所以实现可能有问题;我只是简单的测试一下,因为无法提交,所以无法完全确定这个实现是否正确。但这个不是重点。重点是scala。

代码:

 

 

/**
 *
 */

/**
 * @author Blues
 *
 */
class Square(t: Int, r: Int, b: Int, l: Int) {
  val top = t;
  val right = r;
  val bottom = b;
  val left = l;

  override def toString() = "Square [top: " + top + ", right: " + right + ", bottom: " + bottom + ", left: " + left + "]";
  
  override def equals(that: Any):Boolean = that match {
    case that: Square =>  (top == that.top && right == that.right && bottom == that.bottom && left == that.left)
    case _ => false
  }
}

object App {
  def main(args: Array[String]) {
    readAndProcess(readLine, 0);
  }

  def readAndProcess(line: String, counter: Int) {
    val n = line.toInt;
    if (n == 0) {
      return ;
    } else {
      //for 也是表达式,可以使用yield计算
      val squares = for (i <- 0 until n * n) yield {
        val squareLine = readLine();
        val nums = squareLine.split(" ");
        if (nums.length == 4) {
          new Square(nums(0).toInt, nums(1).toInt, nums(2).toInt, nums(3).toInt)
        } else {
          throw new Exception("wrong input");
        }
      }
      val succeeded = process(n, squares.toArray);
      if (succeeded) {
        println("Game " + counter + ": Possible")
      } else {
        println("Game " + counter + ": Impossible")
      }
      //使用递归避免使用while;while没有计算结果,在函数式语言里不被提倡
      readAndProcess(readLine, (counter + 1));
    }
  }

  def process(n: Int, squares: Array[Square]): Boolean = {
    //在函数里定义函数,这个算闭包么?
    def pickSquare(proccededSquares: List[Square]): List[Square] = {
    	squares.filterNot(proccededSquares.contains(_)).toList;
    }

    def dfs(index: Int, proccededSquares: List[Square]): Boolean = {
      //var定义可变变量,不提倡
      var done = false;
      for (pickedSquare <- pickSquare(proccededSquares)
          if !done) {
        val currentRow = index / n;
        val currentCol = index % n;
        //if 也可以计算结果,如此就可以将matched定义为val,不可变类型;
        val matchTop = if (currentRow > 0) {
          val topIndex = (currentRow - 1) * n + currentCol;
          val topSquare = proccededSquares(topIndex);
          topSquare.bottom == pickedSquare.top
        } else {
          true;
        }

        val matchLeft = if (currentCol > 0) {
          val leftIndex = index - 1;
          val leftSquare = proccededSquares(leftIndex);
          leftSquare.right == pickedSquare.left;
        } else {
          true;
        }

        if (matchTop && matchLeft) {
          //list :: 是右操作符,由右边的值调用,并把左边的值作为参数传入
          val addCurrent = (pickedSquare :: (proccededSquares.reverse)).reverse
          println(addCurrent)
          done = dfs(index + 1, addCurrent)
        }
      }
      done;
    }

    dfs(0, Nil);
  }

}

 重点都在注释里面。

 

刚开始学习scala,发现它还是很有趣。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值