[Kotlin] Korean Coding Test - Programmers - Walking in the park
KotlinQuestion
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)