본문 바로가기
알고리즘/문제

[프로그래머스][kotlin] 키패드 누르기

by 코드 이야기 2021. 4. 8.
728x90

 

 

제대로 풀지 못하여 다른 사람의 풀이를 참고했다.

class Solution {
    fun solution(numbers: IntArray, hand: String): String {
        var answer = ""

        val map = mutableMapOf(
            1 to Pair(0, 3),
            2 to Pair(1, 3),
            3 to Pair(2, 3),
            4 to Pair(0, 2),
            5 to Pair(1, 2),
            6 to Pair(2, 2),
            7 to Pair(0, 1),
            8 to Pair(1, 1),
            9 to Pair(2, 1),
            0 to Pair(1, 0),
            "*" to Pair(0, 0),
            "#" to Pair(2, 0)
        ) //키패드의 번호판을 좌표화 시켜준다.

        var currentL: Any = "*"
        var currentR: Any = "#"

        for(n in numbers) {
            when (n) {
                1, 4, 7 -> {  //1, 4, 7이라면 왼손이 누르도록 한다.
                    answer += "L"
                    currentL = n
                }
                3, 6, 9 -> {  //3, 6, 9라면 오른손이 누르도록 한다.
                    answer += "R"
                    currentR = n
                }
                else -> {  //2, 5, 8, 0이라면 눌러야하는 버튼에서 가까운 손을 찾아 누르도록 한다.
                    val position = map[n]!!

                    val leftLength: Int = position.let { map[currentL]!!.distance(it) }  //도착할 지점부터 왼손까지의 거리
                    val rightLength: Int = position.let { map[currentR]!!.distance(it) }  //도착할 지점부터 오른손까지의 거리

                    if(leftLength > rightLength) {
                        answer += "R"
                        currentR = n
                    } else if(leftLength < rightLength) {
                        answer += "L"
                        currentL = n
                    } else {
                        if (hand == "right") {
                            answer += "R"
                            currentR = n
                        } else {
                            answer += "L"
                            currentL = n
                        }
                    }
                }
            }
        }

        return answer
    }

    private fun Pair<Int, Int>.distance(pair: Pair<Int, Int>): Int {  //거리를 계산한다.
        return kotlin.math.abs(this.first - pair.first) + kotlin.math.abs(this.second - pair.second)
        // abs.(현재 열의 좌표 - 도착할 열의 지점 좌표) + abs.(현재 행의 좌표 - 도착할 행의 지점 좌표)
    }
}

 

 

 

문제를 풀며 알게된 것!

좌표를 표현하는 방법도 신기했고, 

가장 신기했던 거리를 구할 때 사용한 범위함수(let)!!

이 블로그를 보고 쉽게 이해할 수 있었다. (감사합니다~)

 

 

 

 

 

 

 

더보기

여담)

처음에는 별로 좋은 방법이 생각나지 않아서 열심히 노가다로 해보았으나 테케 (8, 9, 11~~) 가 틀렸다... 슬펐다..

class Solution {

    var nowLeft = '*'
    var nowRight = '#'
    var bf = StringBuffer()

    fun solution(numbers: IntArray, hand: String): String {
        var answer = ""

        numbers.forEach {
            var charIt: Char = (it+48).toChar()
            when (charIt) {
                '1', '4', '7', '*' -> {
                    nowLeft = charIt
                    bf.append("L")
                }
                '3', '6', '9', '#' -> {
                    nowRight = charIt
                    bf.append("R")
                }
                else -> {
                    //print("$it, ")
                    bf.append(midLine(charIt, hand))
                }
            }
        }

        answer = bf.toString()
        return answer
    }

    private fun midLine(it: Char, hand: String): Char{
        var handInitial: Char = if (hand=="left") 'L' else 'R'

        var leftMove = 0
        var rightMove = 0

        when (it) {
            '2' -> {
                rightMove = if(nowRight=='3' || nowRight=='5') 1
                else if(nowRight=='6' || nowRight=='8') 2
                else if(nowRight=='0' || nowRight=='9') 3
                else 4
                leftMove = if (nowLeft=='1'|| nowLeft=='5') 1
                else if (nowLeft=='4'|| nowLeft=='8') 2
                else if (nowLeft=='7'|| nowLeft=='0') 3
                else 4
            }
            '5' -> {
                rightMove = if(nowRight=='2' || nowRight=='6'|| nowRight=='8') 1
                else if(nowRight=='3' || nowRight=='9'|| nowRight=='0') 2
                else 3
                leftMove = if (nowLeft=='2'|| nowLeft=='4'|| nowLeft=='8') 1
                else if (nowLeft=='1'|| nowLeft=='7'|| nowLeft=='0') 2
                else 3
            }
            '8' -> {
                rightMove = if(nowRight=='5' || nowRight=='9'|| nowRight=='0') 1
                else if(nowRight=='2' || nowRight=='6'|| nowRight=='#') 2
                else 3
                leftMove = if (nowLeft=='5'|| nowLeft=='7'|| nowLeft=='0') 1
                else if (nowLeft=='2'|| nowLeft=='4'|| nowLeft=='*') 2
                else 3
            }
            '0' -> {
                rightMove = if(nowRight=='8' || nowRight=='#') 1
                else if(nowRight=='5' || nowRight=='9') 2
                else if(nowRight=='2' || nowRight=='6') 3
                else 4
                leftMove = if (nowLeft=='8'|| nowLeft=='*') 1
                else if (nowLeft=='5'|| nowLeft=='7') 2
                else if (nowLeft=='2'|| nowLeft=='4') 3
                else 4
            }
        }
        //println("leftMove: $leftMove, rightMove: $rightMove")

        return if(leftMove == rightMove) {
            if(handInitial=='L') nowLeft = it
            else nowRight = it
            handInitial
        } else {
            if (leftMove < rightMove) {
                nowLeft = it
                'L'
            } else {
                nowRight = it
                'R'
            }
        }
    }
}
728x90

댓글