Post

(프로그래머스 Lv.1) 키패드 누르기 / with.맨하탄 거리

문제링크: https://school.programmers.co.kr/learn/courses/30/lessons/67256

코드

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
def solution(numbers, hand):

    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_pos = (3, 0)
    right_pos = (3, 2)
    
    res = []

    for num in numbers:
        if num in [1, 4, 7]:
            res.append("L")
            left_pos = keypad[num]
        elif num in [3, 6, 9]:
            res.append("R")
            right_pos = keypad[num]
        else:  # 2, 5, 8, 0인 경우
            left_distance = abs(left_pos[0] - keypad[num][0]) + abs(left_pos[1] - keypad[num][1])
            right_distance = abs(right_pos[0] - keypad[num][0]) + abs(right_pos[1] - keypad[num][1])

            if left_distance < right_distance:
                res.append("L")
                left_pos = keypad[num]
            elif right_distance < left_distance:
                res.append("R")
                right_pos = keypad[num]
            else:  # 거리가 같을 때
                if hand == "right":
                    res.append("R")
                    right_pos = keypad[num]
                else:
                    res.append("L")
                    left_pos = keypad[num]

    return ''.join(res)

풀이

  1. 키패드의 배열을 딕셔너리에 담는다.
    • 왜? 맨하탄 거리를 계산하기 위해서다. 키패드에서 숫자를 누를 때 손가락은 수평, 수직으로만 이동할 수 있다.
    • 맨하탄 거리가 뭔데?
      • 격자 위에서 두 점 간의 거리를 계산하는 방법으로, |수평의 차| + |수직의 차| 를 한 값.
  2. 따라서 현재 손가락의 위치와 다음으로 움직일 위치간의 맨하탄 거리를 left, right 각각 구하고 left와 right를 비교하면 된다.

참고

나는 그냥 잼민이처럼 1D로 풀었는데 답이 도저히 안 나와서 뭐지? 했더니만…….잼민이도 이렇게 안 푸나? ㅎ 아아. 수학의 중요성. 아아. . . . . 수평 또는 수직으로만 이동할 수 있는 상황에서는 맨하탄 거리 공식을 이용합시다….

또한, left_pos와 right_pos에 새 값을 할당해주기 때문에 tuple을 사용해도 문제가 없다. 안에 들어있는 원소값 자체를 바꾸는게 아니니까…

This post is licensed under CC BY 4.0 by the author.