문제출처: 키패드 누르기: 프로그래머스
분류:
function solution(numbers, hand) {
var answer = "";
// 각 키패드에서 가운데 키패드[2,5,8,0]까지의 거리
// [0,1,2,3,4,5,6,7,8,9,*,#]이다.
const move = {
2: [3, 1, 0, 1, 2, 1, 2, 3, 2, 3, 4, 4],
5: [2, 2, 1, 2, 1, 0, 1, 2, 1, 2, 3, 3],
8: [1, 3, 2, 3, 2, 1, 2, 1, 0, 1, 2, 2],
0: [0, 4, 3, 4, 3, 2, 3, 2, 1, 2, 1, 1],
};
let left = 10,
right = 11; // 손가락 포인터
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] === 1 || numbers[i] === 4 || numbers[i] === 7) {
left = numbers[i];
answer += "L";
}
if (numbers[i] === 3 || numbers[i] === 6 || numbers[i] === 9) {
right = numbers[i];
answer += "R";
}
if (
numbers[i] === 2 ||
numbers[i] === 5 ||
numbers[i] === 8 ||
numbers[i] === 0
) {
const leftMove = move[numbers[i]][left];
const rightMove = move[numbers[i]][right];
if (leftMove < rightMove || (leftMove === rightMove && hand === "left")) {
left = numbers[i];
answer += "L";
} else {
right = numbers[i];
answer += "R";
}
}
}
return answer;
}
맨해튼 거리
를 이용하면 move 에 수기로 작성한 거리를 코드적으로 해결할 수 있다.
function solution(numbers, hand) {
var answer = "";
const keypad = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
["*", 0, "#"],
];
let left = "*";
let right = "#";
// 현재지점(x1, y1)에서 목표지점(x2, y2)까지의 거리를 구한다.
const getDistance = function (from, to) {
const [x1, y1] = convertKeypad[from];
const [x2, y2] = convertKeypad[to];
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
};
// keypad를 좌표로 변환한다.
const convertKeypad = keypad.reduce((acc, prev, x) => {
prev.forEach((number, y) => {
acc[number] = [x, y];
});
return acc;
}, {});
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] === 1 || numbers[i] === 4 || numbers[i] === 7) {
left = numbers[i];
answer += "L";
}
if (numbers[i] === 3 || numbers[i] === 6 || numbers[i] === 9) {
right = numbers[i];
answer += "R";
}
if (
numbers[i] === 2 ||
numbers[i] === 5 ||
numbers[i] === 8 ||
numbers[i] === 0
) {
const leftMove = getDistance(left, numbers[i]);
const rightMove = getDistance(right, numbers[i]);
if (leftMove < rightMove || (leftMove === rightMove && hand === "left")) {
left = numbers[i];
answer += "L";
} else {
right = numbers[i];
answer += "R";
}
}
}
return answer;
}
컴퓨터에 더 많은 계산을 맡겼기때문에 실행시간은 더 오래 걸렸다.
본 문제는 내가 직접 거리 계산을 한 순자가 [2,5,8,0] 4개라 금방 끝났지만
표본이 더욱 늘어나면 효율면에서 굉장한 차이가 날 것이다.
또한 거리는 상대적인 것으로 상황이 조금만 변화해도 거리계산을 다시 할 필요가 생길 것이다.
그렇기에 코드의 유지보수 측면에서도 직접 계산한 배열을 활용하는 것은 굉장히 비효율적이다.
좀 더 컴퓨터에 계산을 맡길 수 있도록 코드를 설계하는 부분이 필요하다고 느꼈다.
또한 reduce, forEach 등 배열 고차 함수에 대해 다시 한번 개념을 확인할 필요가 있겠다.