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

oznni·2021년 6월 21일
0
post-thumbnail

문제

키패드 누르기


처음에 작성한 코드

keypad = [[1,2,3],[4,5,6],[7,8,9],['*',0,'#']]
def solution(numbers, hand):
    answer = ''
    left_thumb = '*'
    right_thumb = '#'

    for i in range(len(numbers)):
        if numbers[i] in [1,4,7]:
            left_thumb = numbers[i]
            answer += 'L'
        elif numbers[i] in [3,6,9]:
            right_thumb = numbers[i]
            answer += 'R'
        else:
            ldist = abs(get_idx(numbers[i])[0]-get_idx(left_thumb)[0]) + abs(get_idx(numbers[i])[1]-get_idx(left_thumb)[1]) # 왼쪽 엄지손가락과 현재 숫자의 키패드 거리
            rdist = abs(get_idx(numbers[i])[0]-get_idx(right_thumb)[0]) + abs(get_idx(numbers[i])[1]-get_idx(right_thumb)[1]) # 오른쪽 엄지손가락과 현재 숫자의 키패드 거리
            
            if ldist < rdist:
               left_thumb = numbers[i]
               answer += 'L'
            elif ldist > rdist:
                right_thumb = numbers[i]
                answer += 'R'
            else: # 거리가 같은 경우
                if hand == 'left': # 왼손잡이인 경우
                    left_thumb = numbers[i]
                    answer += 'L'
                else: # 오른손잡이인 경우
                    right_thumb = numbers[i]
                    answer += 'R'
    return answer

def get_idx(num):
    for i in range(len(keypad)):
        for j in range(len(keypad[i])):
            if num == keypad[i][j]:
                idx = [i,j]
                return idx

이 문제에서 중요한 부분은 2, 5, 8, 0을 입력할 때이다. 해당 부분은 for문 바로 아래있는 else 부분이다. 처음에는 2차원 keypad 리스트를 사용해서 get_idx(num)함수를 통해 keypad 리스트 내에서 현재 검사할 숫자의 인덱스를 구했다.

인덱스구하는 함수를 따로 만든 이유는 keypad가 2차원리스트라서 반환되는 인덱스가 [0,0]처럼 행,열의 위치를 나타내는 숫자 두개로 구성되어야하는데, 단순히 index()(str 클래스의 내장함수)를 사용할 수 없었기 때문이다.

구한 인덱스는 다음과 같다.

  • 현재 검사할 숫자가 위치한 인덱스 : get_idx(numbers[i])
  • 왼쪽 엄지손가락의 위치한 인덱스 : get_idx(left_thumb)
  • 오른쪽 엄지손가락의 위치한 인덱스 : get_idx(right_thumb)

아래와 같이 현재 검사할 숫자의 인덱스를 왼쪽과 오른쪽 인덱스와의 거리를 각각 구했고, 현재 숫자의 위치에서 왼쪽과 오른쪽 중 더 가까운 쪽을 선택하면 끝이다.

  • 왼쪽 엄지손가락과 현재 숫자의 키패드 거리
ldist = abs(get_idx(numbers[i])[0]-get_idx(left_thumb)[0]) 
+ abs(get_idx(numbers[i])[1]-get_idx(left_thumb)[1])
  • 오른쪽 엄지손가락과 현재 숫자의 키패드 거리
rdist = abs(get_idx(numbers[i])[0]-get_idx(right_thumb)[0]) 
+ abs(get_idx(numbers[i])[1]-get_idx(right_thumb)[1])

수정한 코드

loc = [[3,1],[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]] # 0-9 순서로 키패드 위치를 나타내는 리스트

def solution(numbers, hand):
    answer = ''
    left_loc = [3,0] # '*'의 loc
    right_loc = [3,2] # '#'의 loc

    for n in numbers:
        if n in [1,4,7]:
            left_loc = loc[n]
            answer += 'L'
        elif n in [3,6,9]:
            right_loc = loc[n]
            answer += 'R'
        else:
            ldist = abs(loc[n][0]-left_loc[0]) + abs(loc[n][1]-left_loc[1]) # 왼쪽 엄지손가락과 현재 숫자의 키패드 거리
            rdist = abs(loc[n][0]-right_loc[0]) + abs(loc[n][1]-right_loc[1]) # 오른쪽 엄지손가락과 현재 숫자의 키패드 거리
            if ldist < rdist:
                left_loc = loc[n]
                answer += 'L'
            elif ldist > rdist:
                right_loc = loc[n]
                answer += 'R'
            else: # 거리가 같은 경우
                if hand == 'left': # 왼손잡이인 경우
                    left_loc = loc[n]
                    answer += 'L'
                else: # 오른손잡이인 경우
                    right_loc = loc[n]
                    answer += 'R'

    return answer

항상 문제를 제출한 후에는 다른사람의 풀이를 보곤하는데, get_index 함수를 따로 만들 필요없이 간단하게 답을 구할 수 있는 풀이 방식이 대부분이었는데, 마음에 들었던 풀이는 0-9까지 키패드 위치를 일차원리스트(loc)로 만든 것이었다. 0-9까지의 위치를 순서대로 저장했기 때문에 인덱스 효과도 있어서 아주 신박했다. 그리고 왼쪽과 오른쪽 엄지손가락의 위치를 나타내는 변수를 사용하고, 이 변수는 어차피 초기화를 해야하기때문에 *,#의 위치로 초기화한 점도 인상깊었다.

  • left_loc = [3,0] # '*'의 loc
  • ght_loc = [3,2] # '#'의 loc

발생한 문제점 및 해결 방안

TypeError: 'list' object is not callable

처음 작성한 코드에서 수정하던 도중 발생했던 에러이다.
발생한 원인은 다음과 같다.

 left_thumb = loc(n) # 에러 발생
 left_thumb = loc[n] # 수정한 코드

인덱스로 리스트 접근시 대괄호를 사용해야하는데, 함수처럼 소괄호를 작성해버린 것이다
코드를 한참동안 봤는데 정말 어이없었다ㅎㅎ

profile
Android Developer.

0개의 댓글

관련 채용 정보