티스토리 뷰
320x100
2021년 1월 13일에 Velog에 작성한 글을 옮겨온 글입니다.
프로그래머스 - [카카오 인턴] 키패드 누르기
풀이
우선 각 번호 사이의 거리를 구해둔 후(dist 객체), 번호에 따라 적절한 손가락을 사용하도록 분기처리했다. 현재 손가락 위치(left, right 변수)를 저장하여 가운데 줄 번호를 누를 때 번호 사이의 거리를 측정할 수 있게 했다.
if else 분기처리가 많다보니 깔끔한 느낌이 없어 아쉬웠지만, 이 이상 줄이면 오히려 지저분해질거 같고, 문제에서 제시한 스탭과 맞아 아래 코드로 제출했다.
function solution(numbers, hand) {
const dist = { // 가운데 줄 번호와 각 번호 사이의 거리. ex) dist[2][0] - 2번과 0번 사이의 거리: 3
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; // 현재 손가락 위치(왼손 *: 10, 오른손 #: 11로 초기화)
return numbers.reduce((answer, num) => {
if(num === 1 || num === 4 || num === 7) { // 1, 4, 7번 => 왼손
left = num;
answer += 'L';
} else if(num === 3 || num === 6 || num === 9) { // 3, 6, 9번 => 오른손
right = num;
answer += 'R';
} else { // 0, 2, 5, 8번 => 가까우면서 주사용손
const l = dist[num][left];
const r = dist[num][right];
if(l < r || (l === r && hand === 'left')) {
left = num;
answer += 'L';
} else if(l > r || (l === r && hand === 'right')) {
right = num;
answer += 'R';
}
}
return answer;
}, '');
}
제출 후, 다른 사람의 풀이를 보니 각 번호 사이의 맨해튼 거리 구하는 것이 키 포인트였던 것 같다...경우의 수가 적어서 그냥 dist 객체로 만들고 시작했는데, 코드에 분기처리 외에 특별한 게 없는 느낌이 그냥 든게 아니었다..
어느 정도 의미가 있을지 모르겠지만, 조금 더 나의 관여를 줄이고 컴퓨터가 일을 하도록 수정해보았다.
키패드 모양의 이차원 배열(realKeypad)에서 좌표를 추출하고(keypad), 시작점(from)에서 도착점(to)까지의 맨해튼 거리를 구하는 calcDistance 함수를 추가해주었다.
실행시간은 아래 풀이가 2~3배 정도 더 든다.
function solution(numbers, hand) {
const calcDistance = (from, to) => {
const [fromX, fromY] = keypad[from];
const [toX, toY] = keypad[to];
return Math.abs(fromX - toX) + Math.abs(fromY - toY);
};
const realKeypad = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
['*', 0, '#']];
const keypad = realKeypad.reduce((acc, row, x) => { // 2차원 키패드 배열을 좌표로 변환
row.forEach((number, y) => (acc[number] = [x, y]));
return acc;
}, {});
let left = '*', right = '#'; // 현재 손가락 위치
return numbers.reduce((answer, num) => {
if(num === 1 || num === 4 || num === 7) { // 1, 4, 7번 => 왼손
left = num;
answer += 'L';
} else if(num === 3 || num === 6 || num === 9) { // 3, 6, 9번 => 오른손
right = num;
answer += 'R';
} else { // 0, 2, 5, 8번 => 가까우면서 주사용손
const lDist = calcDistance(num, left);
const rDist = calcDistance(num, right);
if(lDist < rDist || (lDist === rDist && hand === 'left')) {
left = num;
answer += 'L';
} else if(lDist > rDist || (lDist === rDist && hand === 'right')) {
right = num;
answer += 'R';
}
}
return answer;
}, '');
}
320x100
'개발 > Algorithm' 카테고리의 다른 글
프로그래머스 | [3차] 압축(JavaScript) (0) | 2021.06.23 |
---|---|
프로그래머스 | 신규 아이디 추천(JavaScript) (0) | 2021.06.21 |
프로그래머스 | 124 나라의 숫자(JavaScript) (0) | 2021.06.16 |
프로그래머스 | 파일명 정렬(JavaScript) (0) | 2021.06.14 |
프로그래머스 | k번째 수(JavaScript) (0) | 2021.06.11 |
댓글
최근에 올라온 글
TAG
- 스토리북 에러
- file opener preference
- mkdirp
- fs-extra
- createAction
- 자바스크립트
- ModuleParseError: Module parse failed: Unexpected token
- 스터디
- 프로그래머스
- 인증
- jest
- sass
- node fs
- ELIFECYCLE
- node file package
- external editor
- 웹팩 에러
- node mkdir -p
- javascript event
- 인가
- Webpack Error
- Storybook Error
- JavaScript
- errno 253
- make-dir
- rimraf
- node cp -r
- 페이지 특정 위치 link
- ECONNRESET
- node rm -rf