[Kotlin] Korean Coding Test - Programmers - Walking in the park

Kotlin

Language :

Question

Link

A robot dog is going to take a walk in a rectangular grid-shaped park with an "O" on the road passing by and an "X" on the obstacle.The walk follows a pre-populated command to the robot dog, which is given in the following format:

  • ["Direction Distance", "Direction Distance"...]

For example, "E5" means that the robot dog has moved five spaces east of its current location.The robot dog checks the following two things before performing the command:

  • Make sure you leave the park when you move in a given direction.
  • Verify that you encounter obstacles while moving in the given direction.

If either of the above applies, the robot dog ignores the command and performs the following command:

If the horizontal length of the park is W and the vertical length is H, the coordinates in the upper left corner of the park are (0, 0), and the coordinates in the lower right corner are (H - 1, W - 1).

Complete the solution function to return the robot dog's position in the order of [vertical coordinates, lateral coordinates] when parameters are given to the park's string array park and the string array routes with commands to be performed.

Restrictions

park

  • park[i] consists of the following characters and only one starting point is given.
  • S : Start Point
  • O : a movable passageway
  • X : Obstacles
  • It's a rectangular shape.

routes

  • Perform the commands in order from the first element.
  • The elements of routes consist of a structure such as "op n", where "op" is the direction to be moved, and "n" is the number of spaces to be moved.
  • op Direction to move
  • N: Move north by the given space.
  • S: Move south by the given space.
  • W : Move west by the given space.
  • E : Move east by the given space.

Input/Output Example

Input/Output Example #1

  • Input
  • park: ["SOO","OOO","OOO"]
  • routes:  ["E 2","S 2","W 1"]
  • Output: [2,1]

Input/Output Example #2

  • Input
  • park: ["SOO","OXX","OOO"]
  • routes: ["E 2","S 2","W 1"]
  • Output: [0,1]

Input/Output Example #3

  • Input
  • park: ["OSO","OOO","OXO","OOO"]
  • routes: ["E 2","S 3","W 1"]
  • Output: [0,0]

Code 1. Draw a Go board

class Solution {
    companion object {
        private const val START = 'S'
        private const val BLOCK = 'X'
        private const val ROAD = 'O'
    }
    
    fun solution(park: Array<String>, routes: Array<String>): IntArray {
        // Robot Position
        var robot = Pair(0, 0)

        // drawing a checkerboard
        val row = park.first().length
        val col = park.count()
        val board = Array(row) { Array(col) { ROAD } }
        park.forEachIndexed { y, str ->
            for (x in str.indices) {
                board[x][y] = str[x]
                if (str[x] == START) robot = Pair(x, y)
            }
        }

        // Robot Puppy Move
        routes.forEach { route ->
            var nextX = robot.first
            var nextY = robot.second
            val (direction, distance) = route.split(" ")
            when (direction) {
                "E" -> nextX += distance.toInt() * 1
                "W" -> nextX += distance.toInt() * -1
                "N" -> nextY += distance.toInt() * -1
                "S" -> nextY += distance.toInt() * 1
            }

            // outside the hall
            if (nextX < 0 || nextY < 0) return@forEach
            if (nextX >= row || nextY >= col) return@forEach
            // a roadblock
            for (i in minOf(robot.first, nextX)..maxOf(robot.first, nextX)) {
                for (j in minOf(robot.second, nextY)..maxOf(robot.second, nextY)) {
                    if (board[i][j] == BLOCK) return@forEach
                }
            }
            // Move
            robot = Pair(nextX, nextY)
        }

        return intArrayOf(robot.second, robot.first)
    }
}
TEST 1 〉	Pass (32.82ms, 63.3MB)
TEST 2 〉	Pass (21.73ms, 63.4MB)
TEST 3 〉	Pass (21.69ms, 63.8MB)
TEST 4 〉	Pass (29.60ms, 64MB)
TEST 5 〉	Pass (26.18ms, 64.4MB)
TEST 6 〉	Pass (32.12ms, 64.8MB)
TEST 7 〉	Pass (22.05ms, 64.1MB)
TEST 8 〉	Pass (22.59ms, 64.2MB)
TEST 9 〉	Pass (32.01ms, 64.2MB)
TEST 10 〉	Pass (21.94ms, 64.3MB)
TEST 11 〉	Pass (25.77ms, 64.6MB)
TEST 12 〉	Pass (32.53ms, 64.3MB)
TEST 13 〉	Pass (22.58ms, 64.2MB)
TEST 14 〉	Pass (24.18ms, 64.1MB)
TEST 15 〉	Pass (21.78ms, 64.6MB)
TEST 16 〉	Pass (23.61ms, 64.3MB)
TEST 17 〉	Pass (21.59ms, 64.1MB)
TEST 18 〉	Pass (27.57ms, 63.9MB)
TEST 19 〉	Pass (22.33ms, 63.9MB)
TEST 20 〉	Pass (22.08ms, 64.1MB)

Code 2. Don't draw a go board

class Solution {
    fun solution(park: Array<String>, routes: Array<String>): IntArray {
        var answer = intArrayOf(0, 0)
        // Location of movement
        val directionMove = hashMapOf(
            "E" to intArrayOf(0, 1),
            "W" to intArrayOf(0, -1),
            "S" to intArrayOf(1, 0),
            "N" to intArrayOf(-1, 0)
        )

        // Initial position
        // ForEach, forEachIndex uses for statements because repeated lambda calls can degrade performance
        for (y in park.indices) {
            for (x in park[y].indices) {
                if (park[y][x] == 'S') answer = intArrayOf(y, x)
            }
        }

        // Move
        routes.forEach { route ->
            val (direction, distance) = route.split(" ")
            val move = directionMove[direction]!!
            val step = distance.toInt()

            var y = answer[0]
            var x = answer[1]
            for (i in 0 until step) {
                y += move[0]
                x += move[1]

                // Park[0] is faster than park.first().
                if (y < 0 || x < 0 || x >= park[0].length || y >= park.size || park[y][x] == 'X') {
                    y = answer[0]
                    x = answer[1]
                    break
                }
            }
            answer = intArrayOf(y, x)
        }
        return answer
    }
}
TEST 1 〉	Pass (12.59ms, 61.6MB)
TEST 2 〉	Pass (9.49ms, 60.9MB)
TEST 3 〉	Pass (10.07ms, 61.7MB)
TEST 4 〉	Pass (10.52ms, 59.9MB)
TEST 5 〉	Pass (9.65ms, 61.7MB)
TEST 6 〉	Pass (10.82ms, 61.3MB)
TEST 7 〉	Pass (14.11ms, 60.4MB)
TEST 8 〉	Pass (10.55ms, 60.7MB)
TEST 9 〉	Pass (12.02ms, 61.4MB)
TEST 10 〉	Pass (14.19ms, 61MB)
TEST 11 〉	Pass (14.31ms, 61.4MB)
TEST 12 〉	Pass (9.11ms, 61.3MB)
TEST 13 〉	Pass (14.19ms, 62.1MB)
TEST 14 〉	Pass (14.02ms, 61.8MB)
TEST 15 〉	Pass (9.50ms, 61.4MB)
TEST 16 〉	Pass (11.62ms, 61.4MB)
TEST 17 〉	Pass (10.33ms, 60.9MB)
TEST 18 〉	Pass (10.75ms, 60.6MB)
TEST 19 〉	Pass (10.01ms, 61.1MB)
TEST 20 〉	Pass (11.82ms, 61.2MB)

민갤

Back-End Developer

백엔드 개발자입니다.