Advertisement
Guest User

Untitled

a guest
Nov 15th, 2018
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 5.00 KB | None | 0 0
  1. import GraphBFS.bfs
  2. object Maze extends App {
  3.   def solveMaze(maze: List[String]):Option[String] = {
  4.     type node = Int
  5.     val width = maze.head.length()
  6.     val height = maze.length
  7. //    val start =
  8. //    maze.map()
  9.     def findStart(maze: List[String], r: Int, start: (Int, Int), end: (Int, Int)): ((Int, Int), (Int,Int)) = {
  10.       def inner(row: String, c: Int, start: (Int, Int), end: (Int, Int)): ((Int, Int), (Int,Int)) = {
  11.         if (c == width) (start, end)
  12.         else {
  13.           val start_ = if (row.head.equals('s')) (r, c) else start
  14.           val end_ = if (row.head.equals('e')) (r, c) else end
  15.           inner(row.tail, c+1, start_, end_)
  16.         }
  17.       }
  18.       if (r == height) (start, end)
  19.       else {
  20.         val se = inner(maze.head, 0, start, end)
  21.         findStart(maze.tail, r + 1, se._1, se._2)
  22.       }
  23.     }
  24.  
  25.     def cre(Maze: List[String], r: Int, Maze_ : List[Int]): List[Int] = {
  26.       def inner(row: String, r: Int, c: Int, row_ : List[Int]): List[Int] = {
  27.         if (c == width)
  28.           row_
  29.         else
  30.         if (row.head.equals(' ')) inner(row.tail, r, c+1, (r*1000 + c)::row_) else inner(row.tail, r, c+1, row_)
  31.       }
  32.       if (r == height) Maze_
  33.       else
  34.         cre(Maze.tail, r + 1, inner(Maze.head, r, 0, Maze_))
  35.       }
  36.  
  37.     val (start, end) = findStart(maze, 0, (0, 0), (0, 0))
  38.     val maze_ = (end._1*1000+end._2 :: start._1*1000+start._2 :: cre(maze, 0, Nil)).toSet//.flatMap(_.toList)).toSet
  39. //    println(time((end :: start :: cre(maze, 0, Nil)).toSet))
  40. //    print(maze_)
  41.  
  42.  
  43.     def nbrs(node: Int): Set[Int] = {
  44.         Set((node/1000)*1000 + node%1000-1, (node/1000)*1000 + node%1000 + 1, (node/1000 -1)*1000 + node%1000, (node/1000 + 1)*1000 + node%1000).filter(maze_.contains(_))
  45. //      case (a,b) => Set((a, b - 1), (a, b + 1), (a - 1, b), (a + 1, b)).filter(maze_.contains(_))
  46.     }
  47.  
  48.     val myGraph = time {maze_.map(x => (x, nbrs(x))).toMap}
  49.  
  50.     val myNbrs = (n: Int) => myGraph.getOrElse(n, Set())
  51.  
  52.     def getDir(c: Int, p: Int):String = {
  53.         val c1 = c/1000
  54.         val c2 = c%1000
  55.         val p1 = p/1000
  56.         val p2 = p%1000
  57. //        println(c1,c2, p1,p2)
  58.         if (c1 > p1) "d"
  59.         else if (c1 < p1) "u"
  60.         else if (c2 > p2) "r"
  61.         else if (c2 < p2) "l"
  62.         else ""
  63.     }
  64.  
  65.  
  66.     val (parent: Map[Int, Int], distance) = time{bfs(myGraph, start._1*1000+start._2)}
  67. //    println(parent)
  68.  
  69.     def traverse(crr: Int, dleft: Int, path: List[String]): List[String] = dleft match{
  70.       case 0 => path
  71.       case _ =>
  72. //        println(getDir(crr, parent(crr)))
  73.         traverse(parent(crr), dleft - 1, getDir(crr, parent(crr)) :: (path))
  74.     }
  75.     if (parent isDefinedAt end._1*1000+end._2){
  76.       Some(traverse(end._1*1000+end._2, distance(end._1*1000+end._2), Nil).mkString)
  77.     }
  78.     else None
  79.  
  80.     }
  81.   val maze = List("xxxxxxxxxxxxxxxxxx",
  82.     "x    x      x   ex",
  83.     "x    x   x  x xxxx",
  84.     "x        x  x    x",
  85.     "xs   x   x       x",
  86.     "xxxxxxxxxxxxxxxxxx")
  87. //  println(solveMaze(maze))
  88.  
  89.   def time[R](block: => R): R = {
  90.     val t0 = System.currentTimeMillis()
  91.     val result = block    // call-by-name
  92.     val t1 = System.currentTimeMillis()
  93.     println("Elapsed time: " + (t1 - t0) + "ms")
  94.     result
  95.   }
  96.   val maze250 = List("x" * 250):::List("xs" + " " * 247 + "x"):::List.fill(246)("x"+" " * 248+"x"):::List("x" + " " * 247 + "ex"):::List("x" * 250)
  97.   println(time(solveMaze(maze250)))
  98.  
  99. }
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107. import scala.collection.immutable
  108.  
  109. object GraphBFS {
  110.  
  111.   def bfs[V](nbrs: V => Set[V], src: V) = {
  112.  
  113.     def expand(frontier: Set[V], parent: Map[V, V]): (Set[V], Map[V, V]) = {
  114.  
  115.       val parent_ = frontier
  116.         .flatMap(x => nbrs(x).filter(j => !parent.contains(j)).flatMap(g => Map(g -> x)))
  117. //      val frontier_ = frontier.flatMap(nbrs).filter(!parent.keySet.contains(_))
  118.       val frontier_ = frontier.flatMap(nbrs).filter(!parent.contains(_))
  119. //        .diff(parent.keySet)
  120.  
  121.         //.flatMap(_.toSet)
  122. //      def map(f1: Set[V], f2: Set[V], map: Map[V, V]):Null = (f1, f2) match{
  123. //        case (h1::t1, h2::t2) =>
  124. //      }
  125. //      val parent_ = (frontier zip frontier_).toMap
  126.  
  127.  
  128. //      val parent_ = frontier.flatMap(x => nbrs(x).filter(!parent.keySet.contains(_)).map((_, x))).toMap ++ parent
  129.  
  130. //  map{x =>
  131. //        try{
  132. //          nbrs(x).diff(parent.keySet).map((_, x))
  133. //        } catch {
  134. //          case e: Exception =>
  135. //            Nil
  136. //        }
  137. //      }.flatMap(_.toSet).toMap ++ parent
  138.  
  139.       (frontier_, parent ++ parent_)
  140.     }
  141.  
  142.     def iterate(frontier: Set[V], parent: Map[V, V], distance: Map[V, Int], d: Int):(Map[V, V], Map[V, Int]) =
  143.       if (frontier.isEmpty)
  144.         (parent, distance)
  145.       else {
  146.         val (frontier_, parent_) = expand(frontier, parent)
  147.         val distance_ = distance ++ frontier.map(_ -> d)
  148. //        val distance_ = distance ++ frontier.flatMap(a => Map(a -> d))
  149.  
  150.         iterate(frontier_, parent_, distance_, d + 1)
  151.       }
  152.  
  153.     iterate(Set(src), Map(src -> src), Map(), 0)
  154.   }
  155.  
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement