`
regular
  • 浏览: 77604 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

EMC笔试题的初步答案-Scala代码

阅读更多
题目参见:EMC笔试题(最后一道编程题),概要如下:

7*8的一个棋盘,即有56个格子。格子上随机放上小球。小球只可以做水平或者垂直方向运动。
小球相互可以碰撞,碰撞的情况为:
如果两个小球相邻,比如Ball(1, 3)和Ball (1, 4),这时远处的小球Ball(1, 1)移动过来撞到Ball(1, 3),Ball(1, 1)应该停止在(1, 2)位置,同时Ball(1, 3)把碰撞传递给Ball(1, 4)后,Ball(1,3)仍然不动, Ball(1, 4)被撞开,以此类推。

Ball(1, 1) => Ball(1, 3), Ball(1, 4)

如果一个方向上没有其他的小球存在,那么不允许直接将小球沿着这个方向直接移出棋盘。

例如下图中,G表示小球,那么(2,2)位置上的小球只能向右或向下移动,因为(2, 2)位置的小球的上方和左方都没有小球,规则不允许把(2, 2)位置的小球沿上、左方移动从而直接移出棋盘。同理,(4, 2)位置的小球只允许向左移动。
       
     
       
      
       
       
       
       

两个球相邻是不能动的。中间一定要有至少一个的空格。
当碰撞过后,只有一个球在棋盘上为有解。否则无解。
每次选择任意一个球开始运动,碰撞完成后,可以选择任意剩下小球开始运动。
请写出一个程序,任意初始化棋盘上的小球,然后判断是否有解,有解打印出球移动步骤,否则输入无解。


试做的Scala代码如下,由于刚开始使用Scala做实际能用的例子,所以可能还不够函数化,见笑的地方多多包涵。
object Main {
    type Matrix = List[List[Int]]

    def main(args : Array[String]) : Unit = {
        val matrix = List(
                List(0, 0, 0, 0, 0), 
                List(1, 0, 0, 0, 1), 
                List(0, 1, 0, 0, 0), 
                List(0, 0, 0, 1, 0), 
                List(0, 0, 0, 0, 0))
        analyze(matrix, 4) match { // 注意,这里的4是指一共有4颗球,后续可改为自动判断
            case Some(x) => println(x)
            case None =>
        }
    }

    def matrixToString(matrix: Matrix) : String = {
        val f = (l : List[Int]) => ("" /: l)(_ + " " + _).substring(1)
        ("" /: matrix)(_ + f(_) + "\n")
    }

    def analyze(matrix : Matrix, count: Int): Option[String] = {
        if (count == 1) {
            return Some(matrixToString(matrix))
        }
        val top = Array.make(matrix(0).length, -1)
        for (rowIdx <- 0 until matrix.length) {
            val row = matrix(rowIdx)
            var left = -1
            for (colIdx <- 0 until row.length) {
                val point = row(colIdx)
                if (point == 1) {
                    if (left != -1 && colIdx - left > 1) {
                         analyze(click(matrix, rowIdx, colIdx, Direction.West), count - 1) match {
                             case Some(x) => return Some(matrixToString(matrix)+ colIdx + "," + rowIdx + " <\n" + x)
                             case None =>
                         }
                        analyze(click(matrix, rowIdx, left, Direction.East), count - 1) match {
                             case Some(x) => return Some(matrixToString(matrix) + left + "," + rowIdx + " >\n" + x)
                             case None =>
                         }
                    }
                    if (top(colIdx) != -1 && rowIdx - top(colIdx) > 1) {
                        analyze(click(matrix, rowIdx, colIdx, Direction.North), count - 1) match {
                             case Some(x) => return Some(matrixToString(matrix) + colIdx + "," + rowIdx + " ^\n" + x)
                             case None =>
                         }
                        analyze(click(matrix, top(colIdx), colIdx, Direction.South), count - 1) match {
                             case Some(x) => return Some(matrixToString(matrix) + colIdx + "," + top(colIdx) + " v\n" + x)
                             case None =>
                         }
                    }
                    left = colIdx
                    top(colIdx) = rowIdx
                }
            }
        }
        return None
    }
    
    def click(matrix : Matrix, rowIdx : Int, colIdx : Int, dir : Direction.Value) : Matrix = {
        dir match {
            case Direction.West =>
                val row = matrix(rowIdx).toArray
                row(colIdx) = 0
                goLeft(row, colIdx)
                val (top, bottom) = matrix.splitAt(rowIdx)
                top ::: row.toList :: bottom.tail
            case Direction.East =>
                val row = matrix(rowIdx).toArray
                row(colIdx) = 0
                goRight(row, colIdx)
                val (top, bottom) = matrix.splitAt(rowIdx)
                top ::: row.toList :: bottom.tail
            case Direction.North =>
                val col = Array.make(matrix.length, -1)
                for (row <- 0 until col.length) {
                    col(row) = matrix(row)(colIdx)
                }
                col(rowIdx) = 0
                goLeft(col, rowIdx)
                repCol(matrix, col, colIdx)
            case Direction.South =>
                val col = Array.make(matrix.length, -1)
                for (row <- 0 until col.length) {
                    col(row) = matrix(row)(colIdx)
                }
                col(rowIdx) = 0
                goRight(col, rowIdx)
                repCol(matrix, col, colIdx)
        }
    }
    def goLeft(row : Array[Int], idx : Int) {
        for (col <- idx - 1 to (0, -1)) {
            if (row(col) == 1) {
                row(col) = 0
                row(col + 1) = 1
            }
        }
    }
    def goRight(row : Array[Int], idx : Int) {
        for (col <- idx + 1 until row.length) {
            if (row(col) == 1) {
                row(col) = 0
                row(col - 1) = 1
            }
        }
    }
    def repCol(matrix : Matrix, col : Array[Int], colIdx : Int): Matrix = {
        for (pair <- matrix zip col) yield {
            val (row, point) = pair
            val (left, right) = row.splitAt(colIdx)
            left ::: point :: right.tail
        }
    }
}

object Direction extends Enumeration {
    val North, East, South, West = Value
}

输出结果为:
0 0 0 0 0
1 0 0 0 1
0 1 0 0 0
0 0 0 1 0
0 0 0 0 0
0,1 >
0 0 0 0 0
0 0 0 1 0
0 1 0 0 0
0 0 0 1 0
0 0 0 0 0
3,3 ^
0 0 0 0 0
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
0 0 0 0 0
3,2 <
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
0
0
分享到:
评论

相关推荐

    jackson-module-scala_2.11-2.6.7.1-API文档-中英对照版.zip

    赠送源代码:jackson-module-scala_2.11-2.6.7.1-sources.jar; 赠送Maven依赖信息文件:jackson-module-scala_2.11-2.6.7.1.pom; 包含翻译后的API文档:jackson-module-scala_2.11-2.6.7.1-javadoc-API文档-中文...

    flink-scala_2.12-1.14.3-API文档-中文版.zip

    赠送源代码:flink-scala_2.12-1.14.3-sources.jar 包含翻译后的API文档:flink-scala_2.12-1.14.3-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.apache.flink,artifactId:flink-scala_2.12,...

    flink-1.19.0-bin-scala-2.12.tgz flink-1.16.3-bin-scala-2.12.tgz

    标题和描述中提到的"flink-1.19.0-bin-scala-2.12.tgz"和"flink-1.16.3-bin-scala-2.12.tgz"是Apache Flink的两个不同版本的二进制发行版。Flink是一个开源的流处理和批处理框架,它提供了低延迟、高吞吐量的数据...

    mongo-scala-drive的使用demo

    在 Scala 中与 MongoDB 进行交互,通常我们会使用 `mongo-scala-driver`,而不是 `mongo-java-driver`,因为 Scala 驱动提供了更符合 Scala 语言特性的 API 设计。本示例将详细介绍如何使用 `mongo-scala-driver` ...

    flink-1.9.1-bin-scala_2.11.tgz

    flink-1.9.1-bin-scala_2.11.tgz flink-1.9.1-bin-scala_2.11.tgz flink-1.9.1-bin-scala_2.11.tgz flink-1.9.1-bin-scala_2.11.tgz

    flink-1.14.4-scala_2.12 + CDH6.2.1 版 parcel 包

    flink-1.14.4-scala_2.12 + CDH6.2.1 版 parcel 包, 包含 FLINK-1.14.4-BIN-SCALA_2.12-el7.parcel FLINK-1.14.4-BIN-SCALA_2.12-el7.parcel.sha manifest.json (以上三个文件放入 /opt/cloudera/parcel-repo/ 下...

    flink-scala-2.11-1.10.0-API文档-中文版.zip

    赠送源代码:flink-scala_2.11-1.10.0-sources.jar; 赠送Maven依赖信息文件:flink-scala_2.11-1.10.0.pom; 包含翻译后的API文档:flink-scala_2.11-1.10.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org....

    flink-1.17.1-bin-scala-2.12.tgz - Flink 1.17.1 版本

    文件名: flink-1.17.1-bin-scala_2.12.tgz 这是 Apache Flink 1.17.1 版本的二进制文件,专为 Scala 2.12 设计。Flink 是一种开源流处理框架,用于大规模数据处理和分析。这个版本包含了最新的功能和修复,提供了更...

    flink-1.15.1-bin-scala_2.12.tgz

    flink-1.15.1-bin-scala_2.12.tgz

    Flink 资源包 flink-1.15.0-bin-scala_2.12.tgz flink-connector-elasti

    flink-sql-connector-mysql-cdc-2.2.1.jar flink-connector-elasticsearch7-1.15.0.jar flink-1.15.0-bin-scala_2.12.tgz

    flink-1.14.0-bin-scala_2.11.tgz

    标签“flink-1.14.0-bin”则强调了这是 Flink 的二进制发行版,不涉及源代码,适用于那些希望快速启动和运行 Flink 而不关心底层实现的用户。 压缩包内的“flink-1.14.0”目录,是 Flink 安装的核心部分,其中包含...

    m2e-scala.zip

    Eclipse Scala环境的配置 https://yanxml.blog.csdn.net/article/details/89250222 配套的下载资源. http://alchim31.free.fr/m2e-scala/update-site/ 这个地址被墙了.上传,方便大家离线安装`m2e-scala`.

    FLINK-1.14.3-BIN-SCALA_2.12.tar

    适用于CDH5.2 - CDH6.3.2 的 flink版本,FLINK-1.14.3-BIN-SCALA_2.12.tar

    jackson-module-scala_2.11-2.6.7.1-API文档-中文版.zip

    赠送源代码:jackson-module-scala_2.11-2.6.7.1-sources.jar; 赠送Maven依赖信息文件:jackson-module-scala_2.11-2.6.7.1.pom; 包含翻译后的API文档:jackson-module-scala_2.11-2.6.7.1-javadoc-API文档-中文...

    Apache Flink(flink-1.14.4-bin-scala_2.12.tgz)

    Apache Flink(flink-1.14.4-bin-scala_2.12.tgz)是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。Flink以数据并行和流水线方式执行任意流数据程序,Flink的流水线运行...

    jackson-module-scala_2.12-2.6.7.1-API文档-中英对照版.zip

    赠送源代码:jackson-module-scala_2.12-2.6.7.1-sources.jar; 赠送Maven依赖信息文件:jackson-module-scala_2.12-2.6.7.1.pom; 包含翻译后的API文档:jackson-module-scala_2.12-2.6.7.1-javadoc-API文档-中文...

    flink-1.18.1-bin-scala-2.12 免费下载

    flink-1.18.1-bin-scala-2.12 免费下载flink-1.18.1-bin-scala-2.12 免费下载flink-1.18.1-bin-scala-2.12 免费下载flink-1.18.1-bin-scala-2.12 免费下载flink-1.18.1-bin-scala-2.12 免费下载flink-1.18.1-bin-...

    flink-1.12.7-bin-scala_2.12.tgz

    - **API 设计**:Scala 版本的 Flink API 具有强大的类型安全性和函数式编程特性,使得代码更简洁、易读。 - **交互式 Shell**:提供了 `flink-sql-cli`,可以直接在命令行界面运行 SQL 查询,方便测试和调试。 4...

    flink-1.13.1-bin-scala-2.11以及hadoop连接器、kafka连接器

    flink集群搭建 包括: 1.flink-1.13.1-bin-scala-2.11 2.hadoop连接器jar包flink-shaded-hadoop-2-uber-2.7.5-10.0 3.kafka连接器jar包flink-connector-kafka_2.11-1.13.1

    flink-1.13.1-bin-scala_2.12.tgz

    fink安装包 下载地址https://mirrors.tuna.tsinghua.edu.cn/apache/flink/flink-1.13.1/flink-1.13.1-bin-scala_2.12.tgz

Global site tag (gtag.js) - Google Analytics