-
[프로그래머스] 키패드 누르기 - javascript기타/코딩테스트 2022. 6. 16. 20:55
문제
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며,엄지손가락을 사용하는 규칙은 다음과 같습니다.
1. 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당
2. 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용
3. 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용
4. 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용
4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용나의 풀이
const numbers = [2, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]; const hand = 'left'; // 오른손잡이 , left - 왼손잡이 function solution(_numbers, _hand) { let answer = ''; let right = 12; // 오른손 현재위치 let left = 10; // 왼손 현재위치 _numbers.forEach((value) => { let rightDistance = 0; // 오른손과 다음 위치의 거리 계산 let leftDistance = 0; // 왼손과 다음 위치의 거리 계산 if (value == 1 || value == 4 || value == 7) { // 왼손 left = value; answer += 'L'; } else if (value == 3 || value == 6 || value == 9) { // 오른손 right = value; answer += 'R'; } else { let a = {}, b = {}; switch (value) { case 2: a = { 2: 0, 3: 1, 5: 1, 6: 2, 8: 2, 9: 3, 0: 3, 12: 4 }; b = { 2: 0, 1: 1, 5: 1, 4: 2, 8: 2, 7: 3, 0: 3, 10: 4 }; rightDistance = a[right]; leftDistance = b[left]; break; case 5: a = { 5: 0, 2: 1, 6: 1, 8: 1, 0: 2, 3: 2, 9: 2, 12: 3 }; b = { 5: 0, 2: 1, 4: 1, 8: 1, 0: 2, 1: 2, 7: 2, 10: 3 }; rightDistance = a[right]; leftDistance = b[left]; break; case 8: a = { 8: 0, 0: 1, 5: 1, 9: 1, 2: 2, 6: 2, 12: 2, 3: 3 }; b = { 8: 0, 0: 1, 5: 1, 7: 1, 2: 2, 4: 2, 10: 2, 1: 3 }; rightDistance = a[right]; leftDistance = b[left]; break; case 0: a = { 0: 0, 8: 1, 12: 1, 5: 2, 9: 2, 2: 3, 6: 3, 3: 4 }; b = { 0: 0, 8: 1, 10: 1, 5: 2, 7: 2, 2: 3, 4: 3, 1: 4 }; rightDistance = a[right]; leftDistance = b[left]; break; } if (rightDistance > leftDistance) { answer += 'L'; left = value; } else if (leftDistance > rightDistance) { answer += 'R'; right = value; } else { if (_hand == 'right') { answer += 'R'; right = value; } else { answer += 'L'; left = value; } } } }); return answer; } console.log(solution(numbers, hand));
다른 부분은 대부분 어렵지 않고,
2,5,8,0 을 누르기 위해서 어떻게 계산했는지
위 switch 문에 대한 해석!
a, b는 각 손가락이
현재 올라가 있을 수 있는 숫자(object의 key)들에 따라
누를 키패드 숫자(switch의 value)와의 거리(object의 value)를 계산하여 만든 것
예를 들어 a는 오른손이기 때문에 3,6,9,#(12)와 가운데 겹치는 2,5,8,0 숫자에 손가락이 올라가 있을 수 있다
이 때 value에 따라 거리가 얼마나 되는지 계산한 값을 넣은 것이다 (거리가 가까운 순으로 작성)
그렇게 오른손과 왼손 각각 거리를 알아내어 비교하고 숫자를 입력하는 손가락을 찾을 수 있었다
테스트 결과
const numbers = [2, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]; const hand = 'right'; // 오른손잡이 , left : 왼손잡이 console.log(solution(numbers, hand)); // output => LRLLLRLLRRL
실행결과 실패와 삽질했던 내용 (σ`д′)σ
처음에는 현재 있는 위치와의 거리 예를들어 value = 2 일 때, a = { 2:0 } 이라는 값을 안넣어서 오류가 났었다.
현재 위치해 있는게 가장 가까운건데... 처음에는 생각을 못하고 거리 계산에 안 넣었던 것.
실행 오류가 나고, 오류를 잡기 위해 테스트를 직접 손수 해보면서 알아냈다.ㅎ그래도 꽤 재밌었다.
어느 부분에서 재밌었던건지 생각을 해보면
거리를 어떤 기준으로 계산해야할까. 어떻게 비교해야할까. 를 계속 생각해보면서
규칙을 찾아보려고 했던 그 과정이 재미있었던 것 같다.
결국 규칙을 찾지는 못하고 계산은 내가하고 코드로 풀었지만..ㅋㅋㅋㅋㅋ
컴퓨터에게 계산을 시키는 것도 쉽지 않군..
나랑 조금이라도 비슷하게 풀이한 사람도 찾지 못했다는게 조금 슬프다..ㅎ
많이 엉망인걸까.. 하는 생각.. ㅎ
제출 후 코드 개선
거리를 가져오는 부분을 함수로 분리시키고, forEach문을 for문으로 바꾸어 봄
function solution(_numbers, _hand) { let answer = ''; let right = 12; // 오른손 현재위치 # let left = 10; // 왼손 현재위치 * for (let value of _numbers) { if (value == 1 || value == 4 || value == 7) { // 왼손 left = value; answer += 'L'; continue; } if (value == 3 || value == 6 || value == 9) { // 오른손 right = value; answer += 'R'; continue; } const cal = distanceCal(value, right, left); if (cal > 0 || (cal == 0 && _hand == 'left')) { left = value; answer += 'L'; continue; } right = value; answer += 'R'; } return answer; } function distanceCal(_number, _posR, _posL) { let disR = {}, // 오른손가락이 있는 번호판 위에서 _number까지의 거리 disL = {}; // 왼손가락이 있는 번호판 위에서 _number까지의 거리 switch (_number) { case 2: disR = { 2: 0, 3: 1, 5: 1, 6: 2, 8: 2, 0: 3, 9: 3, 12: 4 }; disL = { 2: 0, 1: 1, 5: 1, 4: 2, 8: 2, 0: 3, 7: 3, 10: 4 }; break; case 5: disR = { 5: 0, 2: 1, 6: 1, 8: 1, 0: 2, 3: 2, 9: 2, 12: 3 }; disL = { 5: 0, 2: 1, 4: 1, 8: 1, 0: 2, 1: 2, 7: 2, 10: 3 }; break; case 8: disR = { 8: 0, 0: 1, 5: 1, 9: 1, 2: 2, 6: 2, 12: 2, 3: 3 }; disL = { 8: 0, 0: 1, 5: 1, 7: 1, 2: 2, 4: 2, 10: 2, 1: 3 }; break; case 0: disR = { 0: 0, 8: 1, 12: 1, 5: 2, 9: 2, 2: 3, 6: 3, 3: 4 }; disL = { 0: 0, 8: 1, 10: 1, 5: 2, 7: 2, 2: 3, 4: 3, 1: 4 }; break; } return disR[_posR] - disL[_posL]; }
'기타 > 코딩테스트' 카테고리의 다른 글
[프로그래머스] [1차] 비밀지도 - javascript (0) 2022.06.21 [프로그래머스] 로또의 최고 순위와 최저 순위 - javascript (0) 2022.06.21 [프로그래머스] 숫자 문자열과 영단어 - javascript (0) 2022.06.14 [프로그래머스] 실패율 - javascript (0) 2022.06.13 [프로그래머스] 폰켓몬 - javascript (0) 2022.06.13