🔎 문제
🧩 구현과정 및 코드
개인 토글 영역에 구현 과정과 코드를 자유롭게 작성해주시면 됩니다.
사용할 데이터 구조와 풀이 방향성
적용할 알고리즘 혹은 메서드
수영
구현
코드
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; }
정은
구현
- 키패드 0을 (0,0)으로 잡고 키패드 번호를 좌표로 치환
- 1은 (-1,3), 2는 (0,3) ,,,
- 번호 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('') }
재웅
구현
- 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이 아니었다 ㅎ
종혁
재웅