[프로그래머스] 키패드 누르기 [2020 카카오 인턴십] [python] Level1

 

문제 설명

 

스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

  1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

 


입출력 예 #2

왼손잡이가 [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]를 순서대로 누르면 사용한 손은 "LRLLRRLLLRR"이 됩니다.

입출력 예 #3

오른손잡이가 [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]를 순서대로 누르면 사용한 손은 "LLRLLRLLRL"이 됩니다.

 

설계 및 구현

 

my_solution

def distance(A,B):
    return abs(A[0]-B[0])+abs(A[1]-B[1])

def solution(numbers, hand):
	# 1. 변수의 선언과 초기화
    answer = ''
    keypad = {1:(0, 0), 2:(0, 1), 3:(0, 2),
                4:(1, 0), 5:(1, 1), 6:(1, 2),
                7:(2, 0), 8:(2, 1), 9:(2, 2),
                '*':(3, 0), 0:(3, 1), '#':(3, 2)}
    left,right = '*','#'
    
    # 2.
    for num in numbers:
        if num in [1,4,7]:
            answer+='L'
            left = num
        elif num in [3,6,9]:
            answer+='R'
            right = num
        elif num in [2,5,8,0]:
            if distance(keypad[left],keypad[num]) < distance(keypad[right],keypad[num]):
                answer+='L'
                left = num
            elif distance(keypad[right],keypad[num]) < distance(keypad[left],keypad[num]):
                answer+='R'
                right = num
            else:
                if hand == "right":
                    answer+='R'
                    right = num
                else:
                    answer+='L'
                    left = num
    return answer

지문에서 제시된 조건에 따라 구현을 하는 문제 이다.

키패드의 왼쪽부분은 왼손으로 오른부분은 오른손으로 가운데 부분은 거리가 가까운 손으로 거리가 같다면 주손잡이에 따라서 손을 사용하고 answer배열에 차례로 쌓고 반환하면 해결 할 수 있다.

위의 4가지 조건으로 분기하여 코드를 작성하였다.

 

1. 먼저 answer리스트, keypad 딕셔너리, 왼손,오른손의 최초위치인 left,right를 선언,초기화 하였다.

2. numbers를 순회하면서 조건을 확인한다.     

    . num이 [1,4,7] or [2,4,7] 중 하나라면 answer리스트에 사용한 손을 쌓고 사용한 손의 위치를 변경해준다.

    ②. [2,5,8,0]중 하나라면 num과 left(왼손의 위치), right(오른손위치)를 비교한후 가까운 손을 사용한다.

         distance(A,B) = 두 번호의 거리를 반환하는 함수

        ⓐ만약 둘의 거리가 같다면 hand를 확인하여 주로 사용하는 손을 사용한다.

3. numbers를 모두 순회하면 answer를 반환하여 해결 할 수 있다.

 

 

모범 solution

def solution(numbers, hand):
    answer = ''
    key_dict = {1:(0,0),2:(0,1),3:(0,2),
                4:(1,0),5:(1,1),6:(1,2),
                7:(2,0),8:(2,1),9:(2,2),
                '*':(3,0),0:(3,1),'#':(3,2)}

    left = [1,4,7]
    right = [3,6,9]
    lhand = '*'
    rhand = '#'
    for i in numbers:
        if i in left:
            answer += 'L'
            lhand = i
        elif i in right:
            answer += 'R'
            rhand = i
        else:
            curPos = key_dict[i]
            lPos = key_dict[lhand]
            rPos = key_dict[rhand]
            ldist = abs(curPos[0]-lPos[0]) + abs(curPos[1]-lPos[1])
            rdist = abs(curPos[0]-rPos[0]) + abs(curPos[1]-rPos[1])

            if ldist < rdist:
                answer += 'L'
                lhand = i
            elif ldist > rdist:
                answer += 'R'
                rhand = i
            else:
                if hand == 'left':
                    answer += 'L'
                    lhand = i
                else:
                    answer += 'R'
                    rhand = i

    return answer

문제가 지문에서 주어진 조건에 따라 단순 구현하는 문제이다보니 코드의 길이가 길수밖에없나보다 모범 solution 역시 numbers를 순회하며 사용한 손을 쌓는 방식으로 [0,2,5,8]이 들어오면 거리를 비교하여 쌓는 방식으로 내가 해결한 방식과 같은 풀이 였다.

반응형

+ Recent posts