[프로그래머스] 키패드 누르기 Python 풀이
# 해당 포스팅은 이제 막 알고리즘 공부를 시작한 초보 수준에서 작성했음을 이해해주시고, 비난보다는 따뜻한 조언을 부탁드립니다.
안녕하십니까, 간토끼입니다.
오늘은 프로그래머스(Programmers) 키패드 누르기 문제에 대해 다뤄보겠습니다.
2020 카카오 인턴십 문제(Lv.1 수준)입니다.
1. 문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/67256
알고리즘 공부를 시작한지 약 2주 남짓한 시간밖에 되지 않아서 아직은 잘 모르겠지만,
카카오 Lv.1 수준의 문제들은 웬만하면 2차원 배열을 활용하는 구현 문제를 출제하는군요.
문제의 생김새는 서로 다른 것 같지만 2차원 배열을 잘 만질 줄 안다면 풀 수 있는 문제들입니다.
이 문제도 2차원 배열을 활용합니다. 전화 키패드에서 왼손과 오른손을 이용해 숫자를 입력하는 상황을 생각해봅시다.
초기 세팅은 왼손은 별* 표시(좌측 하단), 오른손은 샵# 표시에서 시작하는 걸로 하고,
각각의 숫자 입력이 주어질 때 왼손과 오른손을 활용해 문제에서 요구하는 조건을 만족한 상태로 적절히 클릭하여
최종적으로 어떤 손가락들을 이용해 숫자를 입력했는지 출력하면 되는 문제입니다.
즉 주어진 전화 키패드를 2차원 배열로 가정한다면 4x3 사이즈의 배열이 되겠죠.
이때 배열의 1열(1,4,7)은 왼손만 쓸 수 있고, 3열(3,6,9)은 오른손만 쓸 수 있으며,
배열의 2열(2,5,8,0)은 입력하기 직전의 위치에서 입력해야 하는 번호와 가까운 위치에 있는 손가락이 클릭하게 됩니다.
즉 단계마다 왼손이든 오른손이든 숫자를 클릭하고 나면 좌표를 최신화해줘야 합니다.
2. 접근 방법
다음과 같이 접근하였습니다.
먼저 숫자 키패드를 2차원 배열로 생각합시다.
이때 1열의 숫자가 나온다면 왼손만 쓰고, 3열의 숫자가 나온다면 오른손을 쓰면 되겠죠.
단 고려할 사항이 2열(2,5,8,0)이 나올 때인데요.
이를 위해 현재 위치에서 2열의 숫자까지 얼마나 떨어져있는지 거리를 계산하는 함수 distance를 정의해줬습니다.
거리 함수는 각 행끼리, 열끼리 뺀 값에 절대값을 취해서 더해주는 값입니다. 즉 맨하탄 거리라고 할 수 있겠네요.
위 예시를 보면 왼손의 위치가 4이고(2,1), 오른손의 위치가 3인 (1,3) 상황에서 5로 이동해야 한다고 가정합니다.
왼손의 거리는 1이고, 오른손의 거리는 2임을 알 수 있죠? 그러면 오른손보다 왼손이 가까우므로 왼손으로 클릭해주고, 왼손의 좌표를 (2,1) -> (2,2)로 최신화해주면 됩니다. (파이썬의 인덱스는 각각 1씩 빼줘야함은 너무 자명하니... 넘어가겠습니다.)
그리고 만약 두 거리가 같다면 최초 입력받은 왼손잡이, 오른손잡이 여부를 알려주는 변수인 hand를 통해 결정해주면 됩니다.
재밌는 문제네요~
3. 코드
def distance(number, center, hand_row, hand_col):
# center 영역에 위치할 때, 왼손과 오른손의 거리 차이를 구함
# center는 항상 col = 1임.
cent_row = center.index(number) # center의 row number
cent_col = 1 # 항상 1
# 거리 계산
dist = (abs(hand_row - cent_row) + abs(hand_col - cent_col))
return dist
def solution(numbers, hand):
left = [1,4,7] # 왼손으로만 타이핑하는 번호
right = [3,6,9] # 오른손으로만 타이핑하는 번호
center = [2,5,8,0]
click = [] # 왼손 오른손 클릭 여부 기록
# 시작 지점
left_hand_row = 3 ; left_hand_col = 0 # (3,0)
right_hand_row = 3 ; right_hand_col = 2 # (3,2)
for number in numbers:
# (1) 왼손 영역인지 판단
if number in left:
click.append("L")
left_hand_row = left.index(number)
left_hand_col = 0 # 왼손 영역은 항상 col = 0
# (2) 오른손 영역인지 판단
elif number in right:
click.append("R")
right_hand_row = right.index(number)
right_hand_col = 2 # 오른손 영역은 항상 col = 2
# (3) 중간(center) 영역이라면?
elif number in center:
# 1. 거리 계산
left_dist = distance(number, center, left_hand_row, left_hand_col)
right_dist = distance(number, center, right_hand_row, right_hand_col)
# 1-(1) 왼손이 더 멀다면? 오른손 사용
if left_dist > right_dist:
right_hand_row = center.index(number) # 오른손 위치 최신화
right_hand_col = 1
click.append("R")
# 1-(2) 오른손이 더 멀다면? 왼손 사용
if left_dist < right_dist:
left_hand_row = center.index(number) # 왼손 위치 최신화
left_hand_col = 1
click.append("L")
# 1-(3) 둘다 같다면? hand를 활용!
if left_dist == right_dist:
if hand == "right": # 오른손 잡이면 오른손 사용
right_hand_row = center.index(number) # 오른손 위치 최신화
right_hand_col = 1
click.append("R")
else: # 왼손잡이면 왼손 사용
left_hand_row = center.index(number) # 왼손 위치 최신화
left_hand_col = 1
click.append("L")
answer = str()
for i in click:
answer = answer + i
return answer
감사합니다.
잘 읽으셨다면 게시글 하단에 ♡(좋아요) 눌러주시면 감사하겠습니다 :)
(구독이면 더욱 좋습니다 ^_^)
* 본 블로그는 학부생이 운영하는 블로그입니다.
따라서 포스팅에 학문적 오류가 있을 수 있으며, 이를 감안해서 봐주시면 감사하겠습니다.
- 간토끼(DataLabbit)
- B.A. in Economics, Data Science at University of Seoul