Advertisement
Guest User

Untitled

a guest
May 10th, 2020
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.29 KB | None | 0 0
  1. class Graph(val grid: List<String>) {
  2.     private val rows = grid.size
  3.     private val cols = grid[0].length
  4.     private val overlapX = cols - 1
  5.     private val overlapY = rows - 1
  6.     private val up = Pair(0, -1)
  7.     private val down = Pair(0, 1)
  8.     private val left = Pair(-1, 0)
  9.     private val right = Pair(1, 0)
  10.     val floors = mutableSetOf<Pair<Int, Int>>()
  11.     val neighbors = mutableMapOf<Pair<Int,Int>, MutableList<Pair<Int, Int>>>()
  12.  
  13.     init {
  14.         fillGraph()
  15.     }
  16.  
  17.     private fun constrainX(x: Int) =
  18.             when {
  19.                 x < 0 -> overlapX
  20.                 x > overlapX -> 0
  21.                 else -> x
  22.             }
  23.     private fun constrainY(y: Int) =
  24.             when {
  25.                 y < 0 -> overlapY
  26.                 y > overlapY -> 0
  27.                 else -> y
  28.             }
  29.  
  30.     private fun addToTheGraph(floorPoint: Pair<Int, Int>, dir: Pair<Int, Int>) {
  31.         val x = floorPoint.first
  32.         val y = floorPoint.second
  33.         val newPair = Pair(constrainX(x + dir.first), constrainY(y + dir.second))
  34.         if (grid[newPair.second][newPair.first] != ' ')
  35.             return
  36.         neighbors[floorPoint]!!.add(newPair)
  37.     }
  38.  
  39.     private fun fillGraph() {
  40.         grid.forEachIndexed { y, row ->
  41.             row.forEachIndexed x@{ x, value ->
  42.                 if (value == '#')
  43.                     return@x
  44.                 val floorPoint = Pair(x, y)
  45.                 floors.add(floorPoint)
  46.                 neighbors[floorPoint] = mutableListOf()
  47.                 addToTheGraph(floorPoint, up)
  48.                 addToTheGraph(floorPoint, down)
  49.                 addToTheGraph(floorPoint, left)
  50.                 addToTheGraph(floorPoint, right)
  51.             }
  52.         }
  53.     }
  54.  
  55.     fun bfs(start: Pair<Int, Int>, end: Pair<Int, Int>) : Int {
  56.         val queue = mutableListOf<Pair<Int, Int>>()
  57.         val visited = mutableListOf<Pair<Int, Int>>()
  58.         queue.add(start)
  59.         visited.add(start)
  60.         val parents = mutableMapOf<Pair<Int, Int>, Pair<Int, Int>>()
  61.         while (queue.isNotEmpty()) {
  62.             val current = queue.removeAt(0)
  63.             if (current == end)
  64.                 return countParents(current, parents)
  65.             neighbors[current]?.forEach {
  66.                 if (!visited.contains(it)) {
  67.                     queue.add(it)
  68.                     visited.add(it)
  69.                     parents[it] = current
  70.                 }
  71.             }
  72.         }
  73.         return 0
  74.     }
  75.  
  76.  
  77.     fun distanceMatrix() : Map<Pair<Int, Int>, Map<Pair<Int, Int>, Int>> {
  78.         val map = mutableMapOf<Pair<Int, Int>, MutableMap<Pair<Int, Int>, Int>>()
  79.         var skipped = 0
  80.         var calculated = 0
  81.         var precalculated = 0
  82.         floors.forEach { start ->
  83.             map[start] = mutableMapOf()
  84.             floors.forEach { end ->
  85.                 if (start != end) {
  86.                     if (map[end] != null) {
  87.                         map[start]!![end] = map[end]!![start]!!
  88.                         skipped++
  89.                     } else {
  90.                         val myNeighbors = neighbors[end]!!
  91.                         val neighborsToStart = myNeighbors.mapNotNull { n -> map[start]!![n] }
  92.                         if (neighborsToStart.isEmpty() || neighborsToStart.size < myNeighbors.size) {
  93.                             map[start]!![end] = bfs(start, end)
  94.                         } else {
  95.                             val shortest = neighborsToStart.min()!!
  96.                             map[start]!![end] = shortest + 1
  97.                             precalculated += 1
  98.                         }
  99.                         calculated++
  100.                     }
  101.                 }
  102.             }
  103.         }
  104.         println("Skipped: $skipped")
  105.         println("Calculated: $calculated")
  106.         println("Pre-calculated: $precalculated")
  107.         /**
  108.         map.forEach { e ->
  109.             e.value.forEach {
  110.                 println("Distance between ${e.key} to ${it.key}: ${it.value}")
  111.             }
  112.         }**/
  113.         return map
  114.     }
  115.  
  116.     private fun countParents(start: Pair<Int, Int>, parents: Map<Pair<Int, Int>, Pair<Int, Int>>) : Int {
  117.         var count = 0
  118.         var parent = parents[start]
  119.         while (parent != null) {
  120.             count++
  121.             parent = parents[parent]
  122.         }
  123.         return count
  124.     }
  125.  
  126.  
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement