본문 바로가기

알고리즘 & 문제풀이

프로그래머스 - L1 키패드 누르기

설계

위치를 나타내고 거리 계산이 되는 객체 필요

왼쪽, 오른쪽 현 위치를 나타내는 변수 및 업데이트 필요

키패드들의 위치를 담고 있는 변수 필요

numbers 순회하여 진행

git : 키패드 누르기

문제 : https://school.programmers.co.kr/learn/courses/30/lessons/67256


문제 풀이

미리 정의 된 값들의 값 정의

문제의 제시 된 키패드대로 keypadPositions 딕셔너리에 값 할당

오른쪽 손, 왼쪽 손의 위치 초기화

numbers를 순회하여, 기본적으로 오른손으로 수행 위치이면 수행, 왼쪽 수행 위치이면 수행하며, 거리 계산이 필요한 경우 거리 계산 후 규칙대로 수행

결과 반환

import Foundation

func solution(_ numbers:[Int], _ hand:String) -> String {
    var keypadPositions: [String: Posistion] = [:]
    var keypad: [String] = ["1","2","3","4","5","6","7","8","9","*","0","#"].reversed()
    var rightHandNumber = ["3", "6", "9", "#"]
    var leftHandNumber = ["1", "4", "7", "*"]
    
    var result = ""
    
    for row in 0...3{
        for column in 0...2 {
            if let key = keypad.popLast() {
                keypadPositions.updateValue(Posistion(x: column, y: row), forKey: key)
            }
        }
    }
    
    guard var rightHand = keypadPositions["#"], var leftHand = keypadPositions["*"] else {
        return result
    }
    
    
    for number in numbers {
        let numberString = String(number)
        if let targetNumberPosistion = keypadPositions[numberString] {
            
            if(rightHandNumber.contains(numberString)){
                result += "R"
                rightHand = targetNumberPosistion
            } else if (leftHandNumber.contains(numberString)) {
                result += "L"
                leftHand = targetNumberPosistion
            } else {
                let rightDistance = rightHand.getDistance(targetNumberPosistion)
                let leftDistance = leftHand.getDistance(targetNumberPosistion)
                
                if(rightDistance == leftDistance) {
                    if(hand == "right") {
                        result += "R"
                        rightHand = targetNumberPosistion
                    }
                    else {
                        result += "L"
                        leftHand = targetNumberPosistion
                    }
                } else {
                    if(rightDistance > leftDistance) {
                        result += "L"
                        leftHand = targetNumberPosistion
                    } else {
                        result += "R"
                        rightHand = targetNumberPosistion
                    }
                }
            }
        }
    }
    
    return result
}

struct Posistion {
    let x: Int
    let y: Int
    
    func getDistance(_ other: Posistion) -> Int {
        return abs(self.x - other.x) + abs(self.y - other.y)
    }
    
}

key = keypad.popLast() 부분에서 최초에는 .popFist()를 사용했는데 계속 컴파일 에러가 발생해서 이유를 찾아봤습니다..

popFist는 popLast와 다르게 처음 요소를 pop 하고 index 정의가 이뤄져야해서 그런지 ArraySlice와 Collection에서만 기본적으로 제공..

일반 Array에서 사용을 하려면 extension 또는 [0…array.count] slice 처리 후 진행해야합니다!

다른 사람 풀이 분석

프로그래머스 -

https://school.programmers.co.kr/learn/courses/30/lessons/67256/solution_groups?language=swift

해당 풀이는 알고리즘 활용보다는 구현방식에 차이를 보여 한번씩 확인해보시면 괜찮을거 같습니다!

정리

설계부분에서 주어진 값들을 어떻게 정의하고 활용할지 생각해 볼 필요가 있다.