반응형
문제 제목 : 키패드 누르기 (2020 카카오 인턴십)
문제 유형 : Hash
출제 플랫폼 : Programers
문제 출처 : https://school.programmers.co.kr/learn/courses/30/lessons/67256
PesudoCode and Exception
// PesudoCode
1) 확정값에 대한 object를 만들어 사용할 준비를 한다
- let leftPoint = {'1': 'L', '4': 'L', '7': 'L', '*': "L"}
- let rightPoint = {'3': "R", '6': "R", '9': "R", '#': "R"}
2) 3, 6, 9, 0을 정하는것은 왼손과 오른손의 현재 위치에 따라 다르므로 변수를 만들어 둔다
- leftPoint, rightPoint
3) numbers(array) input => result(string) output : map으로 변경해서 합쳐도됨
4) 2 5 8 을 누를떄는 해당 값에서 leftCur, rightCur를 했을때 거리가 작은값의 손가락을 사용한다.
- 거리를 구해주는 function을 따로 만들고, 핸드폰 배치를 따른 배열을 만들어 거리를 측정한다.
내가 푼 답안
function solution(numbers, hand) {
var answer = '';
let pad = [
[1,2,3],
[4,5,6],
[7,8,9],
['*', 0, '#']
]
// 처음에 변화가 없는 결과값(1,4,7 => 'L', 3,6,9 => 'R')들은 미리 저장하여 바로 return할 수 있게 한다.
let leftPoint = {'1': 'L', '4': 'L', '7': 'L', '*': "L"}
let rightPoint = {'3': "R", '6': "R", '9': "R", '#': "R"}
let leftCur = '*'
let rightCur = '#'
// 현재 양쪽 손가락의 위치와 다음 번호의 위치거리 차를 반환해주는 함수
const findDirection = (current, goal) => {
let curIdx
let goalIdx
for(let i = 0; i< pad.length; i++) {
for(let j = 0; j< pad.length; j++) {
if(pad[i][j] === current) curIdx = [i, j]
if(pad[i][j] === goal) goalIdx = [i, j]
}
}
return Math.abs(curIdx[0] - goalIdx[0]) + Math.abs(curIdx[1] - goalIdx[1])
}
// numbers를 하나하나 확인 하며 해당번호에 대한 결과값을 map으로 바꿔준 결과값(array)을 answer에 저장한다.
answer = numbers.map((el,idx) => {
// 1,4,7은 return 'L', 3,6,9은 return 'R'
// leftPoint와 rightPoint를 나눠 현재 양손가락의 위치를 저장해둔다.
if(leftPoint[el]) {
leftCur = el
return leftPoint[el]
} else if(rightPoint[el]) {
rightCur = el
return rightPoint[el]
} else {
// 2,5,8,0을 누를때는 현재 손가락과의 위치 차이를 계산
// function을 따로 만들어서 결과값만 갖고 온다.
if(findDirection(leftCur, el) < findDirection(rightCur, el)) {
// 왼쪽이 더 가까우면 왼쪽으로 사용
leftCur = el
return 'L'
} else if(findDirection(leftCur, el) > findDirection(rightCur, el)) {
// 오른쪽이 더 가까우면 오른쪽 사용
rightCur = el
return 'R'
} else {
// 왼쪽 오른쪽 같으면 주손잡이로 사용
if(hand[0] === 'r') {
rightCur = el
return 'R'
} else {
leftCur = el
return 'L'
}
}
}
})
// 배열형식의 결과값을 string형식으로 변경
return answer.join('');
}
다른 사람의 풀이
function solution(numbers, hand) {
hand = hand[0] === "r" ? "R" : "L"
let position = [1, 4, 4, 4, 3, 3, 3, 2, 2, 2]
let h = { L: [1, 1], R: [1, 1] }
return numbers.map(x => {
if (/[147]/.test(x)) {
h.L = [position[x], 1]
return "L"
}
if (/[369]/.test(x)) {
h.R = [position[x], 1]
return "R"
}
let distL = Math.abs(position[x] - h.L[0]) + h.L[1]
let distR = Math.abs(position[x] - h.R[0]) + h.R[1]
if (distL === distR) {
h[hand] = [position[x], 0]
return hand
}
if (distL < distR) {
h.L = [position[x], 0]
return "L"
}
h.R = [position[x], 0]
return "R"
}).join("")
}
배운점
1) Hash 문제를 풀때는, 원하는 정보를 어떤 방식의 hash table 형태로 만들것인가 하는것이 중요포인트이다.
- Hash table이 효율적이지 못하면 답을 풀어가는 과정이 매우 길어진다.
2) Javascript는 new Map()이라는 자료구조용 문법을 사용할 수 있지만 해당 문제는 object로 진행하였다.
3) 코드 중간에 중복되는 부분에 대하여 funtion을 나눠서 쓰는 습관이 필요하다.
4) 정규식 문법과 .test() : 범위를 알수있는 특정 문자를 찾고 조건문에 활용할때 사용하기 적합하다.
- let str = '123579'
- /[369]/.test(str[2]) // true
- /[369]/.test(str[4]) // flase
- /[369]/.test(str[5]) // true반응형
'Algorithm' 카테고리의 다른 글
| [Python, 이분탐색] 백준 1072 게임 (1) | 2024.10.28 |
|---|---|
| Programsers JadenCase 문자열 만들기 - JavaScript (0) | 2022.10.14 |
| Programers 비밀지도 (2018 카카오 신입 공채 1차) - JavaScript (1) | 2022.09.23 |
| Programers 체육복 - JavaScript (0) | 2022.09.22 |
| Programers 로또의 최고 순위와 최저 순위 - JavaScript (1) | 2022.09.22 |
