-
프로그래머스 - [카카오 인턴] 키패드 누르기Algorithm 2023. 5. 6. 00:21
문제
풀이
카카오 인턴쉽 문제답게 상당히 어려운 문제였다. 풀고자 했던 의도는 키패드를 먼저 2차원 평면 좌표로 구현하기 위해 2차원 배열로 좌표들을 지정해 주었고, 현재 왼손 시작 좌표, 오른손 시작 좌표를 지정해 준 다음 numbers 배열들을 좌표에 매칭시켰다.
먼저 1번, 4번, 7번에 해당되는 (1, 0), (2, 0), (3, 0)일 때 "L"을 추가하고
3번, 6번, 9번에 해당되는 (1, 2), (2, 2), (3, 2)일 때 "R"을 추가시킨다.
남은 0번, 2번, 5번, 8번을 처리할 때가 관건인데 이는 예시를 통해 이해해보자
왼손 위치가 키패드4번, 오른손 위치가 키패드9번에 있을 때 다음으로 5번 키를 눌러야 하는 상황
9번에서 5번을 가기위해 걸리는 거리는 (1,2)와 (2,1)사이의 거리를 구하기 위해서 유클리드 거리를 계산하기 위해
Math.sqrt(Math.pow(1-2, 2) + Math.pow(2-1, 2)) 의 연산을 했더니 계속 풀리지 않아 의문을 가졌다.
그리고 문제의 예제 설명을 자세히 보니 9번에서 5번으로 가는 거리가 루트2가 아닌 2라고 표기된 것을 발견했다
그제서야 문제 조건에서 손의 위치는 상하좌우로만 이동할 수 있다는 것을 발견했다.... (문제 조건을 확실하게 읽자ㅠ)
즉, 피타고라스 공식을 사용하는 유클리드 거리가 아닌 맨하탄 거리를 이용해서 구해야 한다는 것이었다.
따라서, x좌표간의 차이 + y좌표간의 차이를 구하면 되기에 Math.abs((1-2) + (2-1)) 로 구현해 주니 해결되었다.
그리고 왼손위치에서 계산한 맨하탄 거리와 오른손위치에서 계산한 맨하탄 거리가 같을 때 왼손잡이이면 "L", 오른손잡이이면 "R"을 추가한다.
function solution(numbers, hand) { answer = ''; leftHandPosition = [0, 0]; // 왼손 시작 좌표 rightHandPosition = [0, 2]; // 오른손 시작 좌표 // numbers 배열을 좌표에 매칭하기 위한 인덱스화 numbers.map((num, idx) => { if(num === 0) return numbers[idx] = 10 else return numbers[idx]-- }); // 키패드를 좌표를 그린다 생각하고 2차원 배열로 표현 let keyCoordinate = [ [3, 0], [3, 1], [3, 2], // 1 2 3 [2, 0], [2, 1], [2, 2], // 4 5 6 [1, 0], [1, 1], [1, 2], // 7 8 9 [0, 0], [0, 1], [0, 2] // * 0 # ]; numbers.map((_, idx) => numbers[idx] = keyCoordinate[numbers[idx]]); for(let i = 0; i < numbers.length; i++) { // numbers[i]가 1, 4, 7 일때, 왼손위치 numbers[i]로 변경, answer에 L 글자 추가 if(JSON.stringify(numbers[i]) === JSON.stringify([3, 0]) || JSON.stringify(numbers[i]) === JSON.stringify([2, 0]) || JSON.stringify(numbers[i]) === JSON.stringify([1, 0]) ) { leftHandPosition = numbers[i]; answer += 'L'; } // numbers[i]가 3, 6, 9 일때, 오른손위치 numbers[i]로 변경, answer에 R 글자 추가 else if(JSON.stringify(numbers[i]) === JSON.stringify([3, 2]) || JSON.stringify(numbers[i]) === JSON.stringify([2, 2]) || JSON.stringify(numbers[i]) === JSON.stringify([1, 2]) ) { rightHandPosition = numbers[i]; answer += 'R'; } // numbers[i]가 0, 2, 5, 8 일때 else { // 왼손위치와 numbers[i]의 거리가 오른손위치와 numbers[i]의 거리보다 짧을 때 if(Math.abs(leftHandPosition[0] - numbers[i][0]) + Math.abs(leftHandPosition[1] - numbers[i][1]) < Math.abs(rightHandPosition[0] - numbers[i][0]) + Math.abs(rightHandPosition[1] - numbers[i][1]) ) { leftHandPosition = numbers[i]; answer += 'L'; } // 오른손위치와 numbers[i]의 거리가 왼손위치와 numbers[i]의 거리보다 짧을 때 else if(Math.abs(leftHandPosition[0] - numbers[i][0]) + Math.abs(leftHandPosition[1] - numbers[i][1]) > Math.abs(rightHandPosition[0] - numbers[i][0]) + Math.abs(rightHandPosition[1] - numbers[i][1]) ) { rightHandPosition = numbers[i]; answer += 'R'; } // 왼손위치와 numbers[i]의 거리와 오른손위치와 numbers[i]의 거리가 같을 때 else { if(hand === 'left') { leftHandPosition = numbers[i]; answer += 'L' } else { rightHandPosition = numbers[i]; answer += 'R'; } } } } return answer; }
'Algorithm' 카테고리의 다른 글
프로그래머스 - 신고 결과 받기 (1) 2023.05.12 프로그래머스 - 체육복 (0) 2023.05.06 프로그래머스 - 두 개 뽑아서 더하기 (0) 2023.05.04 프로그래머스 - 덧칠하기 (0) 2023.05.03 프로그래머스 - 다음 큰 숫자 (0) 2023.05.02