문제 보기 · Level 1 · 2020 카카오 인턴십 · 정답률 54% · 푼 사람 40,129명 (2026-09-30 기준)1

문제

전화 키패드를 두 엄지로 누른다. 왼손은 *, 오른손은 # 위치에서 시작한다. 1·4·7은 왼손, 3·6·9는 오른손이 누른다. 2·5·8·0은 상하좌우 이동 거리로 더 가까운 손이 누르고, 거리가 같으면 주로 쓰는 손(hand)이 누른다. 누른 손을 L·R로 이은 문자열을 돌려준다.

  • numbers 길이 1~1,000
  • hand는 "left" 또는 "right"

풀이

막히면 한 단계씩 펼친다.

필요한 개념

구현과 시뮬레이션: 키를 격자 좌표로 바꾸고, 맨해튼 거리로 가까운 손을 고르고, 손 위치를 한 번씩 갱신한다.

1단계 · 작은 예로 손으로 풀기

키패드를 4줄 3칸 격자로 보고 (행, 열) 좌표를 붙인다.

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)

numbers = [1, 5], 오른손잡이

  • 1 → 왼손. 왼손이 (0, 0)으로 간다.
  • 5 (1, 1): 왼손 (0, 0)에서 거리 |0−1| + |0−1| = 2, 오른손 # (3, 2)에서 |3−1| + |2−1| = 3 → 왼손

답은 “LL”이다.

2단계 · 가장 단순한 방법과 그 속도

번호마다 규칙을 그대로 따르면 된다. 번호가 최대 1,000개라 금방 끝난다. 이 문제는 좌표와 규칙을 정확히 옮기는 구현 문제다.

3단계 · 핵심 아이디어
  • 키를 좌표로: 딕셔너리로 적어 두거나 식으로 구한다. 1~9는 ((d-1)//3, (d-1)%3), 0은 (3, 1)이다. d − 1 = 3 × 행 + 열(열은 0~2)을 만족하는 (행, 열)은 나눗셈 정리에 따라 한 쌍뿐이라, 몫과 나머지가 곧 좌표다.
  • 거리: 상하좌우로만 움직이니 맨해튼 거리 |r1 - r2| + |c1 - c2|다.
  • 상태: 두 손의 현재 좌표만 기억하면 된다. 누른 손의 좌표만 바꾼다.
4단계 · 코드 흐름
  1. 키 → 좌표 표를 만든다. 왼손은 *, 오른손은 # 좌표에서 시작한다.
  2. 번호마다:
    • 1·4·7이면 L, 3·6·9면 R.
    • 아니면 두 손의 거리를 구해 가까운 손, 같으면 hand 쪽 손.
  3. 고른 손의 위치를 그 키로 옮기고 글자를 붙인다.
5단계 · 파이썬 코드
def solution(numbers, hand):
    pos = {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, right = pos["*"], pos["#"]
    answer = ""
    for d in numbers:
        if d in (1, 4, 7):
            use = "L"
        elif d in (3, 6, 9):
            use = "R"
        else:
            r, c = pos[d]
            dl = abs(left[0] - r) + abs(left[1] - c)
            dr = abs(right[0] - r) + abs(right[1] - c)
            if dl < dr:
                use = "L"
            elif dr < dl:
                use = "R"
            else:
                use = "L" if hand == "left" else "R"
        if use == "L":
            left = pos[d]
        else:
            right = pos[d]
        answer += use
    return answer
  • pos: 키(숫자나 기호)를 좌표 튜플로 바꾸는 딕셔너리다.
  • left[0], left[1]: 튜플의 행과 열이다.
  • abs(x): 절댓값이다.
6단계 · 실행 추적

문제의 예시 1(오른손잡이)의 앞부분이다.

번호 왼손 거리 오른손 거리 누른 손 왼손 위치 오른손 위치
(시작)       * #
1     L 1 #
3     R 1 3
4     L 4 3
5 1 2 L 5 3
8 1 3 L 8 3
2 2 1 R 8 2

끝까지 가면 “LRLLLRLLRRL”이다.

7단계 · 복잡도와 흔한 실수

번호마다 계산 몇 번이라 \(O(n)\)이다.

  • 시작 위치를 *와 #로 두지 않는다.
  • 가운데 열을 누를 때만 위치가 바뀌는 게 아니다. 1·4·7, 3·6·9를 눌러도 그 손의 위치가 바뀐다.
  • 0의 좌표를 (0, 1)처럼 잘못 둔다. 0은 맨 아래 가운데 (3, 1)이다.
검증: 문제의 예시 3개를 통과했고, 무작위 번호열 2,000개에서 “키패드 칸을 BFS로 건너가며 거리를 구하는” 다른 풀이와 결과가 같았다 — 08_pg67256_p1.py
  1. 프로그래머스 스쿨, “키패드 누르기” (https://school.programmers.co.kr/learn/courses/30/lessons/67256), 2026-09-30 조회. ↩