알고리즘 문제풀이

프로그래머스 level 2 - 마법의 엘리베이터(Javascript)

승큐니 2023. 11. 6. 18:48

마법의 엘리베이터

배운 것, 유의할 것

배열로만 풀 필요 없다 ㅠㅠ

왜 그런지 모르겠는데 알고르즘 문제는 배열로 푸는게 편하다. 정답만 구하면된다? 라는 생각도 많이 하긴 하는데, 다른 메소드들에 익숙해지지 못하는 경우도 많고 생각의 틀도 닫힌다는 느낌이 들 때도 있다. 그리고 문제에서 주어지는 자료를 가공해서 푸는 경우가 많은데, 현업에서 raw 데이터를 내 입맛대로 가공하면 협업이나 데이터 관리에도 문제가 될 수 있겠다는 생각이 든다…
별도의 공부를 하든 다른 분들의 코드를 참고해서 나의 방식과 비교해서 더 나은 방법을 고민해야겠다.

재귀로 푼 코드

function solution(storey) {
    if (storey < 5) return storey;
    const r = storey % 10;
    const m = Math.floor(storey / 10);
    return Math.min(r + solution(m), 10 - r + solution(m + 1));
}

프로그래머스에서 좋아요를 제일 많이 받은 정답코드… 프로그래머스는 특히나 간결하게 작성된 코드에 좋아요가 후한 것 같다.
아무튼 코드를 보면 함수는 Math.min(r + solution(m), 10 - r + solution(m + 1));를 리턴하고 있는데, 각 자리수를 0으로 만드는 수 r과 해당 자리수를 10으로 만들어 윗자리에 1을 올림해주는 수 10-r중 어떤 상황이 유리할지 Math.min을 통해 저절로 계산되게끔 재귀로 구현해놨다…
여러 값들에 동작이 반복되고, 동작마다의 리턴 값들이 정답을 구성하는 요소가 된다면 재귀를 항상 생각해보도록 해야겠다.

나의 정답코드

function solution(storey) {
    var answer = 0;
    // 층수를 배열의 형태로 바꿈
    storey = String(storey).split('').map(v=>Number(v));
    // 가장 높은 자리에서 한자리 높아질 수 있으므로 첫번째 자리에 0을 임의로 만들어 줌
    storey.unshift(0);
    // 각 자리수의 층에서 몇번 이동이 필요한지
    for(let i = storey.length - 1; i >= 0; i--){
        // 밑에 자리에서 하나가 올림이 되어 혹시 10이 된 경우에
        if(storey[i] === 10){
            // 우선 그 자리수에서는 10을 빼주고
            storey[i] -= 10;
            // 그 윗자리수에 +1 해줌
            storey[i-1] += 1;
            // 이번 자리수에서는 계산할 것 없으므로 continue;
            continue;
        }
        // 자리수가 5보다 큰 경우와 작은 경우, 5인 경우 구분 구분
        if(storey[i] > 5) {
            answer += 10 - storey[i];
            storey[i-1] += 1;
        } else if(storey[i] < 5){
            answer += storey[i];
        } 
        // 현재 자리수가 5인 경우 윗자리수에 올리는게 이득, 손해일 수 있음
        else {
            if(storey[i-1] >= 5){
                answer += 10 - storey[i];
                storey[i-1] += 1;
            } else {
                answer += storey[i];
            }
        }
    }
    return answer;
}