[프로그래머스] 마법의 엘리베이터

silverCastle·2023년 1월 23일
0

https://school.programmers.co.kr/learn/courses/30/lessons/148653

✍️ 첫번째 접근

현재 층에서 0층으로 가기 위해 필요한 마법의 돌의 최소값을 찾는 문제이다. 엘리베이터가 움직일 때마다 항상 최적의 결정을 하면서 접근해야겠다고 생각했다.
필자는 아래와 같은 논리로 접근하였다.

현재 층이 2554층이고, 목표는 0층이라고 생각하자.
현재 층에서 맨 오른쪽 자릿수 즉, 일의 자리부터 0으로 바꿀 것이다.
각 자릿수를 모두 0으로 만들면 목표 층으로 갈 수 있기 때문이다.
하지만 이렇게 할 경우 예외를 생각하지 못해 틀린 결과를 받았다.

import Foundation

func solution(_ storey:Int) -> Int {
    var result = 0
    var storey = "\(storey)".map{Int(String($0))!}
    
    for i in (0..<storey.count).reversed() {
        if storey[i] > 5 {  // 6, 7, 8, 9
            while storey[i] != 10 {
                storey[i] += 1
                result += 1
            }
            storey[i] = 0
            if i-1 >= 0 {
                storey[i-1] += 1
            }
        }
        else if storey[i] < 5 { // 0, 1, 2, 3, 4
            while storey[i] != 0 {
                storey[i] -= 1
                result += 1
            }
        }
        else {  // 5
            if i-1 >= 0 {
                if storey[i-1] >= 5 {
                    while storey[i] != 10 {
                        storey[i] += 1
                        result += 1
                    }
                }
                else {
                    while storey[i] != 0 {
                        storey[i] -= 1
                        result += 1
                    }
                }
            }
            else {
                result += 5
            }
        }
    }
    
    return result
}

✍️ 두번째 접근

만약 현재 자릿수에 있는 수가 5보다 커서 앞 자릿수의 수가 1 증가되어야하는데 그 수가 10이 되어버리면? 말이 어려우니 아래 그림을 보면 쉽게 이해될 것이다.

현재 층은 999층으로 3자리인데 계산하다보니 4자리로 계산되었다. 따라서, 필자는 다시 논리를 세웠다.

  • 현재 층의 모든 자릿수에 있는 수가 0이 될 때까지 탐색한다. ex) 0000이 될 때까지
  • 일의 자리에서부터 0이 아닌 위치를 찾는다. ex) 1230일 때 3의 index
  • 찾은 위치에 있는 값이 5보다 큰 경우, 작은 경우, 같은 경우를 따져서 계산한다.
  • 주의해야 할 점은 자릿수가 넘어갈 때 해당 위치의 앞에 있는 값을 +1 해줘야한다. 이때 해당 위치가 제일 앞에 있는 경우라면 자릿수를 늘려준다. ex) 800 -> 1000 즉, 3자리에서 4자리로 증가

import Foundation

func solution(_ storey:Int) -> Int {
    var result = 0
    var storey = "\(storey)".map{Int(String($0))!}
    
    while storey.filter{$0 == 0}.count != storey.count {    // storey가 모두 0일 떄까지
        // storey 맨 오른쪽부터 0이 아닌 위치를 찾는다
        var idx = storey.count - 1
        while storey[idx] == 0 && idx > 0 {
            idx -= 1
        }
        if storey[idx] > 5 {    // 찾은 수가 5보다 크다면
            result += 10-storey[idx]    // (10-찾은 수)를 result에 추가
            storey[idx] = 0 // 해당 위치를 계산하였으므로 0으로 설정
            if idx > 0 {    // 맨 왼쪽 자리가 아닐 경우
                storey[idx-1] += 1  // 찾은 수에서 자릿수가 넘어가서 0이 되었으니 찾은 수의 앞 자리 수 증가 
            }
            else {
                storey.insert(1, at: 0) // 맨 왼쪽 자리인 경우에서 자릿수가 넘어갔으니 1 추가
            }
        }
        else if storey[idx] < 5 {   // 찾은 수가 5보다 작다면
            result += storey[idx]   // result에 추가
            storey[idx] = 0 // 해당 위치를 계산하였으므로 0으로 설정
        }
        else {  // 찾은 수가 5라면 찾은 수의 앞 자리 수를 조건에 따라 비교해야한다
            if idx-1 > 0 {
                if storey[idx-1] >= 5 {
                    result += 10-storey[idx]
                    storey[idx] = 0
                    storey[idx-1] += 1                
                }
                else {
                    result += storey[idx]
                    storey[idx] = 0
                }
            }
            else {
                result += 5
                storey[idx] = 0
            }
        }
    }
    return result
}

0개의 댓글