[PG67256] 키패드 누르기
✏️ 𝗔𝗹𝗴𝗼𝗿𝗶𝘁𝗵𝗺/프로그래머스

[PG67256] 키패드 누르기

프로그래머스

🚩 문제 설명

키패드 이미지
프로그래머스 #67256

◾ 키패드를 누를 때 어떤 손의 엄지손가락을 쓰는지 구하는 문제이다.

◾ 키패드가 1, 4, 7에 해당하면 왼쪽 손을 쓴다.

◾ 키패드가 3, 6, 9에 해당하면 오른쪽 손을 쓴다.

◾ 키패드가 그 외의 수 2, 5, 8, 0에 해당하면 현재 키패드에서 더 가까운 엄지손가락을 쓴다.

  • 만약 그 거리가 같다면 사용자의 주 손잡이 방향을 쓴다. 이는 hand 배열로 주어진다.
  • 왼손, 오른손의 위치를 표시를 해야하구나 생각을 한다.

◾ 여기서 주의할 점은 (문제 안풀려서 필자가 개고생한 점 😅)

  • 거리가 나온다면 키패드간의 피타고라스 증명을 써서 거리를 구하려는 사람이 많은데
  • 문제를 보면 단순 위치에서의 거리를 이른다.
  • 즉 무슨 말이냐면,

  • 위처럼 1, 2, 5의 키패드가 있다고 하자.
  • 만약 5를 눌러야하고 왼손은 1에 오른손은 2에 있다고 가정하자.
    • 1에서 5를 가려고 하면 (1 - 0)^2 + (1 - 0)^2 = sqrt(2) 이고
    • 2에서 5를 가려고 하면 (1 - 0)^2 + (1 - 1)^2 = sqrt(1) 이다.
    • 따라서 거리가 1이 더 크므로 왼손으로 눌러야할 것 같지만
  • 문제의 로직을 보면 둘다 그냥 한칸으로 친다.
    • 그래서 만약에 사용자가 오른손잡이라면 오른손으로 눌러야한다.

 

 


 

 

✅ 입출력

numbers: 누를 번호가 순서대로 담긴 배열
hand: 사용자의 주요 손잡이
return ➡️ 번호를 누를때마다 어떤 손을 쓰는지 기록한 문자열을 리턴한다.
numbers hand return
[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL"
[7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR"
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

✔️ 예시

만약 numbers = [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] 이고, hand = "right" 라면
number l r ans
처음 시작 시 * # ""
1 1 # L
3 1 3 LR
4 4 3 LRL
5 5 3 LRLL
8 8 3 LRLLL
2 8 2 LRLLLR
1 1 2 LRLLLRL
4 4 2 LRLLLRLL
5 4 5 (오른손잡이니까) LRLLLRLLR
9 4 9 LRLLLRLLRR
5 5 9 LRLLLRLLRRL

◾ 이로써 마지막 LRLLLRLLRRL을 리턴한다.

 

 


 

 

📑 문제 풀이

with 파이썬 (Python)
# 키패드
keypad = [[1, 2, 3],
          [4, 5, 6],
          [7, 8, 9],
          ['*', 0, '#']]


def distance(n_idx, l_idx, r_idx, hand):
    l_dis = abs((n_idx[0][0] - l_idx[0][0])) + abs((n_idx[0][1] - l_idx[0][1]))
    r_dis = abs((n_idx[0][0] - r_idx[0][0])) + abs((n_idx[0][1] - r_idx[0][1]))

    if l_dis > r_dis:
        return 'right'
    elif l_dis == r_dis:
        return hand
    else:
        return 'left'


def solution(numbers, hand):
    ans = ""
    l, r = '*', '#'

    for n in numbers:
        if n == 1 or n == 4 or n == 7:
            ans += 'L'
            l = n
        elif n == 3 or n == 6 or n == 9:
            ans += 'R'
            r = n
        else:  # 2 5 8 0
            n_idx = [(y, x) for y in range(len(keypad)) for x in range(len(keypad[0])) if keypad[y][x] == n]
            l_idx = [(y, x) for y in range(len(keypad)) for x in range(len(keypad[0])) if keypad[y][x] == l]
            r_idx = [(y, x) for y in range(len(keypad)) for x in range(len(keypad[0])) if keypad[y][x] == r]

            res = distance(n_idx, l_idx, r_idx, hand)

            if res == 'left':
                ans += 'L'
                l = n
            else:
                ans += 'R'
                r = n
    return ans

💬 Point

➡️  단순 이동량을 이용해서 거리를 구할 것
➡️  abs(x` - x) + abs(y` - y)
➡️  n_idx = [(y, x) for y in range(len(keypad)) for x in range(len(keypad[0])) if keypad[y][x] == n]

◾ 단순 이동량으로 거리를 구해야한다. 👈 주의할 것

◾ 나는 키패드를 그냥 2차원 배열로 저장했다.

◾ 그렇기 때문에 해당 값을 가진 인덱스를 반환하기 위해서 위와 같이 반복문 두개를 써서

◾ 만약 keypad[y][x]의 값이 내가 찾는 값과 같다면 y, x 를 반환하도록 했다.

◾ 이차원 배열에서 인덱스를 찾고자 한다면 위를 사용해보자.

◾ 아니면 그냥 아예 키패드를 딕셔너리로 선언해도 나쁘지 않을 것 같다.

  • { 1: [0, 0], 2: [0, 2], ...} 이런식으로

 

 

 

 

 

 

 

 

 

 

 


 

728x90