Posts 키패드 누르기 [Python]
Post
Cancel

키패드 누르기 [Python]

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

문제 설명

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

  • 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  • 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  • 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  • 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    • 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
  • 순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

제한사항

  • numbers 배열의 크기는 1 이상 1,000 이하입니다.
  • numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
  • hand는 “left” 또는 “right” 입니다.
    • “left”는 왼손잡이, “right”는 오른손잡이를 의미합니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

문제풀이

  • 1, 4, 7, *, 3, 6, 9, #은 여지없이 L과 R이 바로 나온다.
  • 하지만 2, 5, 8, 0 일때의 R,L을 결정하는 로직을 만들어야 한다.
  • 일단 주어진 number를 for문을 돌면서 answer에 L과 R을 넣으며 현재 왼손과 오른손의 위치를 정한다.
  • 이후 2,5,8,0 중에 하나가 주어지면 현재 손의 위치에서 target값의 위치를 계산한 뒤 가까운 손을 사용하게 한다.
  • 거리는 keypad를 만들어 np.where를 사용하여 row와 col의 거리를 조합하여 만들었다.
  • 왼손 : 4, 오른손 : 2, 타겟넘버 : 5일때,
    • 왼손은 row는 2번째줄로 동일하니 이동거리 0, col은 4에서 5로 한칸 이동하니 이동거리 1 두개 합쳐서 총 이동거리 1이 나온다.
    • 오른손은 row는 1번째 줄과 2번째줄로 이동해야하니 이동거리 1, 2와 5는 둘다 2번째 col에 있으니 이동거리 0으로 총 이동거리 1이 나온다
    • 둘의 이동거리가 같으니 이때는 왼손잡이인지 오른손 잡이인지 확인 후 L,R을 붙인다.
  • row와 col으로 이동거리를 target값과 비교하니 둘의 차이를 np.abs로 절대값을 씌워줘야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import numpy as np

def solution(numbers, hand):
    
    keypad = np.array([[1,2,3], [4,5,6], [7,8,9], ['*',0,'#']])
    answer = ''
    letf_hand = '*'
    right_hand = '#'
    hand = hand
    
    for i in numbers:

        if i == 1 or i == 4 or i == 7 or i == '*':
            answer += 'L'
            letf_hand = i

        elif i == 3 or i == 6 or i == 9 or i == '#':
            answer += 'R'
            right_hand = i

        else:
            
            letf_row, letf_col = int(np.where(keypad == str(letf_hand))[0]), int(np.where(keypad == str(letf_hand))[1]) # 왼쪽의 row, col의 위치 저장
            right_row, right_col = int(np.where(keypad == str(right_hand))[0]), int(np.where(keypad == str(right_hand))[1]) # 오른쪽의 row, col 위치 저장
            target_row, target_col = int(np.where(keypad == str(i))[0]), int(np.where(keypad == str(i))[1]) # target의 row, col 위치 저장

            letf_distance = (np.abs(target_row - letf_row)) + (np.abs(target_col - letf_col)) # 왼쪽과 타겟의 거리 구함
            right_dictance = (np.abs(target_row - right_row)) + (np.abs(target_col - right_col)) # 오른쪽과 타겟의 거리를 구함.


            if letf_distance < right_dictance:
                answer += 'L'
                letf_hand = i
                
            elif letf_distance > right_dictance:
                answer += 'R'
                right_hand = i

            elif letf_distance == right_dictance:
                
                if hand == 'left':
                    answer += 'L'
                    letf_hand = i
                    
                else :
                    answer += 'R'
                    right_hand = i
                    
    return answer
1
2
3
numbers = [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5]
hand = 'right'
solution(numbers, hand)
1
'LRLLLRLLRRL'
1
2
3
numbers = [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]
hand = 'left'
solution(numbers, hand)
1
'LRLLRRLLLRR'
1
2
3
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
hand = 'right'
solution(numbers, hand)
1
'LLRLLRLLRL'
1
keypad
1
2
3
4
array([['1', '2', '3'],
       ['4', '5', '6'],
       ['7', '8', '9'],
       ['*', '0', '#']], dtype='<U21')
This post is licensed under CC BY 4.0 by the author.