본문 바로가기

Problem Solving/Programmers

[프로그래머스] Level 1 키패드 누르기 | 파이썬

문제 설명

스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

 

이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.

 

맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.

  1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
  2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
  3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
  4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
    4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.

순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.

 

제한 조건

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

 

문제 풀이

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]}
    L = keypad['*']
    R = keypad['#']
    res = ''
    for num in numbers:
        key = keypad[num]
        if num in [1,4,7]:
            res += 'L'
            L = key
        elif num in [3,6,9]:
            res += 'R'
            R = key
        else:
            L_dis = 0
            R_dis = 0
            #L_dis = abs(L[0]-key[0])+abs(L[1]-key[1])
            #R_dis = abs(R[0]-key[0])+abs(R[1]-key[1])
            for l,r,k in zip(L, R, key):
                L_dis += abs(l-k)
                R_dis += abs(r-k)
            if L_dis < R_dis:
                res += 'L'
                L = key
            elif L_dis > R_dis:
                res += 'R'
                R = key
            else:
                if hand == 'left':
                    res += 'L'
                    L = key
                else:
                    res += 'R'
                    R = key
    return res

키패드를 좌표처럼 사용하기 위해 딕셔너리 형태로 keypad를 정의했다.

 

keypad의 value값을 얻기 위해 key를 사용해서 L과 R을 정의했다.

 

출력 결과를 담기 위해 빈 문자열 res를 정의했다.

 

입력받은 숫자 리스트 numbers로 for문을 만들었다.

 

num에 해당하는 keypad의 value값을 key로 정의했다.

규칙에 의해 왼쪽 열과 오른쪽 열은 누르는 손가락이 정해져 있기 때문에, 이 경우 'L'(또는 'R')을 res에 더하고 L(또는 R) 변수를 key 값으로 바꿨다. 

가운데 열은 거리에 따라 정해지기 때문에 L_dis, R_dis 변수를 새로 정의했다.

 - 좌표 간의 거리를 zip 함수를 사용해서 구하고 값을 비교해 res와 L(또는 R) 값을 바꿨다.

 - 거리가 같게 나온 경우 hand값에 따라 정하도록 조건문을 추가했다.

 

거리를 구할 때는 리스트의 인덱스로 접근할 수도 있고(주석처리) 순회 가능한 객체(iterable objects)를 인자로 받는 zip함수를 사용할 수도 있다.

 


프로그래머스 키패드 누르기

 

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

[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

점프 투 파이썬 딕셔너리 자료형

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

파이썬 내장 함수 zip 사용법

 

[파이썬] 내장 함수 zip 사용법

Engineering Blog by Dale Seo

www.daleseo.com

 

회사 실습의 반이 지나갔다. 한동안 피곤하다는 이유로 퇴근 후에 책상에 앉질 못했다. 배운 게 많으면 뭐하나 머릿속이 엉망진창인데🤦‍♂️ 이번 주는 차근차근 정리해봐야겠다,,,😇😇