10. 프로그래머스(1단계) - 키패드 누르기

성훈·2021년 8월 1일
0

Algorithm

목록 보기
10/61
post-thumbnail

📌 문제의 조건

  1. 숫자를 요소로 가지고 있는 배열을 어느 손으로 눌렀는지 문자열로 반환한다.
  2. 각 손가락은 다른 숫자를 누르기 전까지 가장 최근에 누른 숫자의 위치에 있다.
  3. 1,4,7은 왼손 3,6,9는 오른손으로 누르고, 2,5,8,0은 왼손과 오른손 중 가까운 위치에 있는 손으로 누른다.
  4. 만약 거리가 같으면 오른손 잡이라면 오른손, 왼손잡이라면 왼손으로 누른다.

제한사항 🤔

  • numbers 배열의 크기는 1 이상 1,000 이하입니다.
  • numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
  • hand는 "left" 또는 "right" 입니다.
    • "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
  • 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.

📌 풀이

의사 코드 👨‍💻

  1. 손의 위치를 배열로 설정한다.
  2. 반환할 결과를 빈 문자열로 선언한다.
  3. numbers를 반복문을 돌린다.
  4. 항상 왼손과 오른손으로 누르는 숫자들과 거리에 따라 번갈아 가며 누르는 숫자를 배열로 할당한다.

풀이 👨‍💻

function solution(numbers, hand) {
    let result = '';
    let left = [4,1],
    right = [4,3];
    
    const positions = [
        [4,2], [1,1], [1,2], [1,3],
        [2,1], [2,2], [2,3],
        [3,1], [3,2], [3,3]
    ];
    
    for(let nums of numbers){
        if(nums % 3 === 1){
            result = result + 'L';
            left = positions[nums];
        } else if(nums % 3 === 0 && nums){
            result = result + 'R';
            right = positions[nums];
        } else {
            if(Math.abs(left[0]-positions[nums][0]) + Math.abs(left[1]-positions[nums][1]) <
               Math.abs(right[0]-positions[nums][0]) + Math.abs(right[1]-positions[nums][1])){
                result = result + 'L';
                left = positions[nums];
            } else if(Math.abs(left[0]-positions[nums][0]) + Math.abs(left[1]-positions[nums][1]) >
               Math.abs(right[0]-positions[nums][0]) + Math.abs(right[1]-positions[nums][1])) {
                result = result + 'R';
                right = positions[nums];
            } else {
                if(hand === 'left'){
                    result = result + 'L';
                    left = positions[nums];
                } else {
                    result = result + 'R';
                    right = positions[nums];
                }
            }    
        }   
    }
    return result;
}

리듀스 사용 👨‍💻

function solution(numbers, hand) {
    let left = [4,1],
    right = [4,3];
    
    const positions = [
        [4,2], [1,1], [1,2], [1,3],
        [2,1], [2,2], [2,3],
        [3,1], [3,2], [3,3]
    ];
    
    return numbers.reduce((acc, cur)=>{
        if(cur % 3 === 1){
            left = positions[cur];
            return acc + 'L'
        } else if(cur % 3 === 0 && cur){
            right = positions[cur];
            return acc + 'R'
        } else {
            if(Math.abs(left[0]-positions[cur][0]) + Math.abs(left[1]-positions[cur][1]) <
               Math.abs(right[0]-positions[cur][0]) + Math.abs(right[1]-positions[cur][1])){
                left = positions[cur];
                return acc + 'L';
            } else if(Math.abs(left[0]-positions[cur][0]) + Math.abs(left[1]-positions[cur][1]) >
               Math.abs(right[0]-positions[cur][0]) + Math.abs(right[1]-positions[cur][1])) {
                right = positions[cur];
                return acc + 'R';
            } else {
                if(hand === 'left'){
                    left = positions[cur];
                    return acc + 'L';
                } else {
                    right = positions[cur];
                    return acc + 'R';
                }
            }    
        }   
    }, '')
}

📌 리뷰

리듀스로 바꾸면 더 깔끔해질 것 같았는데 생각보다 깔끔해지진 않았다.
그래도 변수 하나 덜 선언하고 코드 조금 더 짧아졌다는데 의의를 두자 😇

📌 문제 출처

출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges#

profile
어떻게 이걸 풀어낼 수 있을까

0개의 댓글