Today
Total
«   2025/05   »
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
관리 메뉴

기억은 짧고 기록은 길다

[프로그래머스/Programmers] 키패드 누르기 - Python 본문

CodingTest/programmers

[프로그래머스/Programmers] 키패드 누르기 - Python

ukunV 2021. 9. 4. 18:11

Link

 

코딩테스트 연습 - 키패드 누르기

[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"

programmers.co.kr

 

Solution

해당 문제는 다양한 방법으로 풀 수 있지만 Other Solution의 첫번째 풀이인 좌표를 지정해서 푸는 방법이 가장 바람직한 풀이라고 생각한다.

필자의 풀이는 *, 0, #을 각각 10, 11, 12로 두었고 위아래 방향은 3, 좌우 방향은 1씩 값이 증가 혹은 감소 하므로 번호의 차를 3으로 나눈 몫과 나머지의 합이 두 번호의 거리인 공식을 활용하였다.

def solution(numbers, hand):
    answer = ''

    recent_left = 10
    recent_right = 12

    for i in range(len(numbers)):
        if numbers[i] in [1, 4, 7]:
            recent_left = numbers[i]
            answer += 'L'
        elif numbers[i] in [3, 6, 9]:
            recent_right = numbers[i]
            answer += 'R'
        elif numbers[i] in [2, 5, 8, 0]:
            t = numbers[i] if numbers[i] != 0 else 11

            if sum(divmod(abs(t - recent_left), 3)) > sum(divmod(abs(t - recent_right), 3)):
                recent_right = t
                answer += 'R'
            elif sum(divmod(abs(t - recent_left), 3)) < sum(divmod(abs(t - recent_right), 3)):
                recent_left = t
                answer += 'L'
            else:
                if hand == 'right':
                    recent_right = t
                    answer += 'R'
                else:
                    recent_left = t
                    answer += 'L'

    return answer
🔑 key point: (U: -3, D: +3, L: -1, R: +1), ('*': 10, 0: 11, '#': 12)
📌 Tip: divmod(), abs()

 

Other Solution

def solution(numbers, hand):
    answer = ''
    key_dict = {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 = [1,4,7]
    right = [3,6,9]

    lhand = '*'
    rhand = '#'
    for i in numbers:
        if i in left:
            answer += 'L'
            lhand = i
        elif i in right:
            answer += 'R'
            rhand = i
        else:
            curPos = key_dict[i]

            lPos = key_dict[lhand]
            rPos = key_dict[rhand]

            ldist = abs(curPos[0]-lPos[0]) + abs(curPos[1]-lPos[1])
            rdist = abs(curPos[0]-rPos[0]) + abs(curPos[1]-rPos[1])

            if ldist < rdist:
                answer += 'L'
                lhand = i
            elif ldist > rdist:
                answer += 'R'
                rhand = i
            else:
                if hand == 'left':
                    answer += 'L'
                    lhand = i
                else:
                    answer += 'R'
                    rhand = i

    return answer
🔑 key point: 각 번호를 좌표로 지정
def solution(numbers, hand):
    l = 10
    r = 11

    answer = ""

    p = [[0, 4, 3, 4, 3, 2, 3, 2, 1, 2],
         [4, 0, 1, 2, 0, 2, 3, 0, 3, 4],
         [3, 1, 0, 1, 2, 1, 2, 3, 2, 3],
         [4, 2, 1, 0, 3, 2, 1, 4, 3, 2],
         [3, 0, 2, 3, 0, 1, 2, 0, 2, 3],
         [2, 2, 1, 2, 1, 0, 1, 2, 1, 2],
         [3, 3, 2, 1, 2, 1, 0, 3, 2, 1],
         [2, 0, 3, 4, 0, 2, 3, 0, 1, 2],
         [1, 3, 2, 3, 2, 1, 2, 1, 0, 1],
         [2, 4, 3, 2, 3, 2, 1, 2, 1, 0],
         [1, 0, 4, 5, 0, 3, 4, 0, 2, 3],
         [1, 5, 4, 0, 4, 3, 0, 3, 2, 0]]

    for i in numbers:
        if i in [1, 4, 7]:
            l = i
            answer += "L"
        elif i in [3, 6, 9]:
            r = i
            answer += "R"
        else:
            if p[l][i] < p[r][i]:
                l = i
                answer += "L"
            elif p[l][i] > p[r][i]:
                r = i
                answer += "R"
            elif hand == "left":
                l = i
                answer += "L"
            else:
                r = i
                answer += "R"

    return answer
🔑 key point: 좌표간의 거리를 미리 구함
Comments