Algorithm/Programmers

[Programmers] 2020 카카오 인턴십 > 키패드 누르기

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

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,5,8,0과 이 숫자를 눌렀을 때 왼손과 오른손의 위치를 구해줘야 하는 부분이었다. 처음엔 키패드가 가진 숫자에서 이동할 숫자를 빼서  위치를 계산했는데 생각해 보니 "키패드 위치"는 위치에 따라 달라지기 때문에 다른 방법이 필요했다.

무슨 방법이 있나 싶었는데 배열의 인덱스를 가지고 이리저리 적어보면서 위치를 구할 방법을 찾았는데 다음고 같은 방법이 떠올랐다.

arr = \
    [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
    ]

# Example, 8과 3의 위치
#   8의 인덱스는 [2][1], 3의 인덱스는 [0][2]
# 계산식
#   abs([2]-[0]) + abs([1] - [2]) = 인덱스 간 거리

그리고 숫자를 입력받으면 2차원 배열의 인덱스를 리턴하는 함수도 따로 작성헀다.

def search_position(number):
    arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9], ['*', 0, '#']]

    for n in range(4):
        for m in range(3):
            if str(arr[n][m]) == str(number):
                return n, m

 

첫 번째 시도

def solution(numbers, hand):
    LEFT_INPUT = [1, 4, 7]
    RIGHT_INPUT = [3, 6, 9]
    MIDDLE_INPUT = [2, 5, 8, 0]

    CURRENT_LEFT = 0
    CURRENT_RIGHT = 0

    answer = []
    for number in numbers:
        if number in LEFT_INPUT:
            CURRENT_LEFT = number
            answer.append('L')
        elif number in RIGHT_INPUT:
            CURRENT_RIGHT = number
            answer.append('R')
        elif number in MIDDLE_INPUT:
            middle_number_x, middle_number_y = search_position(number)
            left_position_x, left_position_y = search_position(CURRENT_LEFT)
            right_position_x, right_position_y = search_position(CURRENT_RIGHT)

            left_gap = abs(left_position_x - middle_number_x) + abs(left_position_y - middle_number_y)
            right_gap = abs(right_position_x - middle_number_x) + abs(right_position_y - middle_number_y)

            if left_gap < right_gap:
                CURRENT_LEFT = number
                answer.append('L')
            elif right_gap < left_gap:
                CURRENT_RIGHT = number
                answer.append('R')
            elif right_gap == left_gap:
                if hand == 'left':
                    CURRENT_LEFT = number
                    answer.append('L')
                if hand == 'right':
                    CURRENT_RIGHT = number
                    answer.append('R')

    return ''.join(answer)

첫 번째 시도로 위와 같은 코드를 작성해서 제출했는데 8번과 15번 테스트 케이스에 실패가 떴다. 모든 조건이 맞았다고 생각했는데 틀리니까 머리가 안 돌았는데 그냥 힌트를 보고 풀었다. 

문제에서 주어진 왼손과 오른손의 시작의 위치는 '*'과 '#' 이다. 그러니 이를 반영해서 두 번째 시도를 했다.

두 번째 시도

def solution(numbers, hand):
    s_numbers = [str(number) for number in numbers]

    LEFT_INPUT = ['1', '4', '7']
    RIGHT_INPUT = ['3', '6', '9']
    MIDDLE_INPUT = ['2', '5', '8', '0']

    CURRENT_LEFT = '*'
    CURRENT_RIGHT = '#'

    answer = []
    for number in s_numbers:
        if number in LEFT_INPUT:
            CURRENT_LEFT = number
            answer.append('L')
        elif number in RIGHT_INPUT:
            CURRENT_RIGHT = number
            answer.append('R')
        elif number in MIDDLE_INPUT:
            middle_number_x, middle_number_y = search_position(number)
            left_position_x, left_position_y = search_position(CURRENT_LEFT)
            right_position_x, right_position_y = search_position(CURRENT_RIGHT)

            left_gap = abs(left_position_x - middle_number_x) + abs(left_position_y - middle_number_y)
            right_gap = abs(right_position_x - middle_number_x) + abs(right_position_y - middle_number_y)

            if left_gap < right_gap:
                CURRENT_LEFT = number
                answer.append('L')
            elif right_gap < left_gap:
                CURRENT_RIGHT = number
                answer.append('R')
            elif right_gap == left_gap:
                if hand == 'left':
                    CURRENT_LEFT = number
                    answer.append('L')
                if hand == 'right':
                    CURRENT_RIGHT = number
                    answer.append('R')

    return ''.join(answer)

시작위치를 '*' 과  '#'으로 바꿔주고 숫자배열을 문자배열로 바꿨다. 그리고 이 코드를 제출하니 통과할 수 있었다.




728x90
반응형