안녕하세요. 오늘은 키패드 누르기라는 문제를 정리해 보도록 하겠습니다.

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

크게 어려운 문제는 아니나, 카카오 스러운(?) 문제라서 정리해보고자 합니다.

 

 

전체 풀이:

def distance(start, end):
    mat = [["1", "2", "3"],
          ["4", "5", "6"],
          ["7", "8", "9"],
          ["*", "0", "#"]]
    start_loc = []
    end_loc = []
    dist = 0
    for idx, r in enumerate(mat):
        if str(start) in r:
            start_loc.append(idx)
            start_loc.append(r.index(str(start)))
        
        if str(end) in r:
            end_loc.append(idx)
            end_loc.append(r.index(str(end)))

    dist = abs(end_loc[0]-start_loc[0]) + abs(end_loc[1]-start_loc[1])
    return dist
    
    

def solution(numbers, hand):
    answer = ''
    left_list = ["1", "4", "7"]
    right_list = ["3", "6", "9"]
    center_list = ["2", "5", "8", "0"]
    r_loc = "#"
    l_loc = "*"
    
    for idx, num in enumerate(numbers):
        if str(num) in left_list:
            answer += "L"
            l_loc = str(num)
        elif str(num) in right_list:
            answer += "R"
            r_loc = str(num)
        else: # center에 해당하는 경우
            dist_l = distance(l_loc, num)
            dist_r = distance(r_loc, num)
            if dist_l < dist_r:
                answer += "L"
                l_loc = str(num)
            elif dist_l > dist_r:
                answer += "R"
                r_loc = str(num)
            else:
                if hand == 'left':
                    answer += "L"
                    l_loc = str(num)
                else:
                    answer += "R"
                    r_loc = str(num)
    
    
    
    return answer

 

문제에서 정의하기로는 좌측에 위치한 1, 4, 7인 경우는 무조건 왼손으로, 3 6 9인 경우는 무조건 오른손으로 타이핑하면 된다고 했기 때문에, 이런 경우는 단순히 if문을 통해서 해결하면 됩니다.

 

이때, answer만 갱신하는 것이 아니라, 왼손과 오른손의 위치 또한 갱신해주어야 합니다.

 

2, 5, 8, 0의 경우는 오른손과 왼손 중 가까운 손을 사용해야 하기 때문입니다.

 

 

만약 왼손이나 오른손으로 확정되지 않는, 2, 5, 8, 0의 경우는 거리를 계산해야 하는데요.

 

이 부분은 별도로 distance라는 함수로 빼서 정의하였습니다.

 

def distance(start, end):
    mat = [["1", "2", "3"],
          ["4", "5", "6"],
          ["7", "8", "9"],
          ["*", "0", "#"]]
    start_loc = []
    end_loc = []
    dist = 0
    for idx, r in enumerate(mat):
        if str(start) in r:
            start_loc.append(idx)
            start_loc.append(r.index(str(start)))
        
        if str(end) in r:
            end_loc.append(idx)
            end_loc.append(r.index(str(end)))

    dist = abs(end_loc[0]-start_loc[0]) + abs(end_loc[1]-start_loc[1])
    return dist

해당 함수는 start 지점부터 end 지점까지의 거리를 계산해 주는 함수입니다.

 

먼저 키패드에 해당하는 matrix를 문자열로 정의하였습니다. *와 #이 존재하므로, 일괄적으로 문자열로 정의하는 게 낫다고 판단했습니다.

 

그리고 matrix를 row 단위로 돌면서, 해당 row에 start나 end가 있으면 해당 위치를 (x, y)의 형태로 저장하도록 했습니다.

 

마지막으로는 |x1-x0| + |y1-y0|을 계산해서 return 하도록 했습니다. 

 

어차피 한 칸을 이동하는게 1로 계산되고, 별도의 제약이 없기 때문에 이렇게 계산해도 충분하다고 판단했습니다. 

 

일반적인 distance를 계산하는 방식처럼 루트를 사용하거나 하지 않기 때문에, 1칸씩 격자로 이동하기 때문이죠.

 

 

이 distance라는 함수를 활용해서 start를 왼손 위치로 잡고, end는 우리가 쳐야 하는 숫자로 입력하면 왼손 기준의 거리를 계산할 수 있고, start를 오른손 위치로 잡고, end를 우리가 쳐야 하는 숫자로 입력하면 오른손 기준의 거리를 계산할 수 있습니다.

 

이 둘 간의 거리를 바탕으로 왼손과 오른손을 결정하면 됩니다.

 

문제에 나와 있듯이, 만약 두 거리가 같을 경우는 왼손잡이인지 오른손잡이인지만 판단해서 결정해 주면 되겠죠.

 

 

사실상 문제 자체가 어려운 케이스는 아닌데, 2, 5, 8, 0인 경우에 각각 왼손, 오른손으로 부터 해당 키패드까지의 거리를 구하는 코드만 잘 짜면 되는 문제라고 보입니다.

 

이번 문제는 여기까지 정리하도록 하겠습니다.

 

감사합니다.

 

 

 

 

 

+ Recent posts