HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤎
프론트엔드 데브코스 5기 교육생
/
🙆
박병현팀
/
🔢
키패드 누르기
🔢

키패드 누르기

레벨
LV.1
날짜
Nov 10, 2023
링크
https://school.programmers.co.kr/learn/courses/30/lessons/67256

🔎 문제


school.programmers.co.kr
https://school.programmers.co.kr/learn/courses/30/lessons/67256
 

🧩 구현과정 및 코드

개인 토글 영역에 구현 과정과 코드를 자유롭게 작성해주시면 됩니다.

사용할 데이터 구조와 풀이 방향성
사용할 데이터 구조와 풀이 방향성
적용할 알고리즘 혹은 메서드
적용할 알고리즘 혹은 메서드

수영


구현

 

코드

function solution(numbers, hand) { let answer = ''; const hands = { left: '*', right: '#'} // 키패드 위치 반환하는 함수 function findLocation(searchKey) { const keypad = [[1,2,3], [4,5,6], [7,8,9], ['*', 0, '#']] for (let i = 0; i < keypad.length; i++) { for (let j= 0; j < 3; j++) { if(keypad[i][j] === searchKey) { return [i, j] } } } } numbers.forEach(number => { switch(number) { case 1: case 4: case 7: hands.left = number answer += 'L' break; case 3: case 6: case 9: hands.right = number answer += 'R' break; case 2: case 5: case 8: case 0: // 키패드 위치 찾기 const nl = findLocation(number) const ll = findLocation(hands.left) const rl = findLocation(hands.right) // 거리 계산 const ldist = Math.abs(ll[0] - nl[0]) + Math.abs(ll[1] - nl[1]) const rdist = Math.abs(rl[0] - nl[0]) + Math.abs(rl[1] - nl[1]) if (rdist > ldist) { hands.left = number answer += 'L' } else if(rdist < ldist) { hands.right = number answer += 'R' } else { // 거리가 같은 경우 hand === 'left' ? (hands.left = number, answer += 'L') : (hands.right = number, answer += 'R') } break; } }) return answer; }

정은


구현

  1. 키패드 0을 (0,0)으로 잡고 키패드 번호를 좌표로 치환
      • 1은 (-1,3), 2는 (0,3) ,,,
  1. 번호 2,5,8,0을 눌러야 할 때는 좌표끼리 차이를 비교
      • 그 외는 문제에 주어진대로 구함

코드

def solution(numbers, hand): answer = '' cur_xy_l = [-1,0] #왼손 좌표 cur_xy_r = [1,0] #오른손 좌표 xy = [(0,0)] #키패드 번호들의 좌표들 x = [-1,0,1] for i in range(9): #키패드 좌표 넣기 xy.append((x[i%3], 3-i//3)) for number in numbers: if number == 1 or number == 4 or number == 7: #1,4,7일 때 answer += 'L' cur_xy_l = xy[number] #왼손 좌표 갱신 elif number == 3 or number == 6 or number == 9: #3,6,9일 때 answer += 'R' cur_xy_r = xy[number] #오른손 좌표 갱신 else: #중간 번호들일 때, 왼or오 좌표 거리 계산 target_x, target_y = xy[number] distance_l = abs(target_x - cur_xy_l[0]) + abs(target_y - cur_xy_l[1]) distance_r = abs(target_x - cur_xy_r[0]) + abs(target_y - cur_xy_r[1]) if distance_l > distance_r: #왼쪽거리 > 오른쪽 거리 answer += 'R' cur_xy_r = xy[number] elif distance_l < distance_r: #오른쪽거리 > 왼쪽 거리 answer += 'L' cur_xy_l = xy[number] else: #오른쪽거리 == 왼쪽 거리 if hand == 'left': #왼손잡이 answer += 'L' cur_xy_l = xy[number] else: #오른손 잡이 answer += 'R' cur_xy_r = xy[number] return answer
  • 시행착오: 단순히 숫자끼리 뺄셈을 절대값해서 거리를 구했었음

종혁


구현

  • 각 손가락에서 해당 키패드까지의 거리를 구한 뒤, 가까운 손가락이 이동하면서 손가락의 현재 위치를 바꿔줘야 함
  • [1,4,7,’*’] [2,5,8,0] [3,6,9,’#’]
  • 1에서 5까지의 거리는 왼쪽 키패드에서 1의 인덱스번호인 0 - 중간 키패드에서 5의 인덱스 번호인 1을 뺀 절댓값인 1(실제로는 2지만 오른쪽도 똑같이 할거라 제외)
  • 현재 손가락이 가운데 키패드에 위치해있는 경우 또 가운데를 누르는 경우도 있음
    • 이 경우에도 가운데 키패드에서 인덱스 번호를 구해서 -1

코드

function solution(numbers, hand) { const result = [] const left = [1,4,7,'*'] const middle = [2,5,8,0] const right = [3,6,9,'#'] let [leftHand,rightHand] = ['*','#']//각 손가락의 현재 위치 for(const number of numbers){ if(number % 3 === 1){//왼손만 갈 수 있음 leftHand = number result.push('L') continue } if(number !== 0 && number % 3 === 0 ){//오른손만 rightHand = number result.push('R') continue } const m = middle.indexOf(number)//중간 키패드에서의 위치 const leftD = left.indexOf(leftHand) >= 0 ? //손가락이 왼쪽키패드에 위치한 경우 Math.abs(m - left.indexOf(leftHand)) : Math.abs(m - middle.indexOf(leftHand)) -1 //손가락이 가운데 키패드에 위치해 있음 const rightD = right.indexOf(rightHand) >= 0 ? Math.abs(m - right.indexOf(rightHand)): Math.abs(m - middle.indexOf(rightHand)) - 1 let use = null console.log(number,leftHand,rightHand,leftD,rightD) if(leftD === rightD){ hand === 'right' ? use = 'right' : use = 'left' }else{ leftD > rightD ? use = 'right' : use = 'left' } if(use === 'right'){ result.push('R') rightHand = number }else{ result.push('L') leftHand = number } } return result.join('') }

재웅


구현

  1. 2차원 배열로 키패드를 구성

코드

function solution(numbers, hand) { let answer = ''; let [rowLeft,colLeft] = [3,0] let [rowRight,colRight] = [3,2] const 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], 0:[3,1] } numbers.forEach((number,idx)=>{ const [targetRow,targetCol] = keypad[number] if(number===1 || number===4 || number ===7){ [rowLeft,colLeft]=keypad[number] answer+='L' } else if(number===3 || number===6 || number===9){ [rowRight,colRight]=keypad[number] answer+='R' } else{ // 중간에 있는 키패드일 경우 // 거리 계산하여 가까운 손 변수에 값을 갱신 // 거리 동일할 경우 hand에 맞춰 갱신 const leftDistance = calDistance(rowLeft,colLeft,targetRow,targetCol) const rightDistance = calDistance(rowRight,colRight,targetRow,targetCol) if(leftDistance > rightDistance){ [rowRight,colRight]=keypad[number] answer+='R' } else if (leftDistance < rightDistance){ [rowLeft,colLeft]=keypad[number] answer+='L' } else{ if(hand==='right'){ [rowRight,colRight]=keypad[number] answer+='R' }else if(hand==='left'){ [rowLeft,colLeft]=keypad[number] answer+='L' } } } }) return answer; } function calDistance(originRow,originCol,targetRow,targetCol){ const rowDistance = Math.abs(originRow-targetRow) const colDistance = Math.abs(originCol-targetCol) return rowDistance + colDistance }
 

✏️ 후기

문제를 풀고 느낀 점, 막혔던 부분 혹은 개선 사항 등을 자유롭게 작성해주시면 됩니다.

👧🏻
수영
  • 디버그 돌려보고 안 사실 forEach에서 return이 안된다. 순회 도중에 return하고 싶다면 for문을 사용해야 한다.
👧🏻
정은
나에겐 레벨 1이 아니었다 ㅎ
👦🏻
종혁
 
👦🏻
재웅