
프로그래머스 - 키패드 누르기
2020 카카오 인턴십
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.

이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.
const keypad = { key(keypad 숫자): value([y, x]) }solution 함수에서 왼쪽 열과 오른쪽 열의 경우에는 무조건 'L', 'R'로 정해져 있으므로 if, else if 조건에 따라 answer 배열에 담는다.
가운데 열의 경우 현재 입력받은 num과 왼쪽, 오른쪽 손가락의 위치인 leftPos, rightPos와의 거리에 따라 'L', 'R' 값이 정해진다.
가운데 열일 때 거리를 계한하는 함수 calcDistance를 작성했다. 가로(x축), 세로(y축)의 거리를 계산해 합산하여 왼손과 오른손의 각각의 거리를 비교하여 'L' 또는 'R'을 리턴했다. 이때 거리계산에서 음수가 나올 수 없으므로 Math.abs() 메서드를 이용했다. 거리가 같은 경우 hand가 기준이 된다.
calcDistance 함수의 리턴값을 answer 배열에 담는다. 'L', 'R'에 따라 leftPos, rightPos 의 상태도 업데이트 해준다.
function calcDistance(num, leftPos, rightPos, hand) {
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],
'*': [3, 0],
0: [3, 1],
'#': [3, 2],
};
// 왼손 거리
const leftDistance =
Math.abs(keypad[num][0] - keypad[leftPos][0]) +
Math.abs(keypad[num][1] - keypad[leftPos][1]);
// 오른손 거리
const rightDistance =
Math.abs(keypad[num][0] - keypad[rightPos][0]) +
Math.abs(keypad[num][1] - keypad[rightPos][1]);
// 거리 비교 후 'L' 또는 'R' 리턴
if (leftDistance > rightDistance) return 'R';
if (leftDistance < rightDistance) return 'L';
return hand[0].toUpperCase();
}
function solution(numbers, hand) {
let leftPos = '*';
let rightPos = '#';
const answer = [];
for (let i = 0; i < numbers.length; i++) {
const num = numbers[i];
if (num % 3 === 1) { // 키패드 왼쪽 열
answer.push('L');
leftPos = num;
} else if (num % 3 === 0 && num !== 0) { // 키패드 오른쪽 열
answer.push('R');
rightPos = num;
} else { // 키패드 가운데 열
answer.push(calcDistance(num, leftPos, rightPos, hand));
calcDistance(num, leftPos, rightPos, hand) === 'R'
? (rightPos = num)
: (leftPos = num);
}
}
return answer.join('');
}
solution([1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5], 'right'); // "LRLLLRLLRRL"