[Swift] [26일차] 마법의 엘리베이터

·2025년 1월 2일
0

SwiftAlgorithm

목록 보기
29/105
post-thumbnail

programmers-마법의 엘리베이터

문제설명

  1. -1, +1, -10, +10, -100, +100과 같이 절댓값이 10c인 엘베버튼 -> 누르면 현재 층 에서 그값을 더한 층으로 이동
  2. 0이하로 되면 이동안함
  3. 현재 층에서 0층 도달하기 위한 최소 버튼 클릭 수
  4. 그냥 단순하기보다 예를들어 16이면 +4해서 20을 만들어주고 -10 -10 해서 6번누르는 등 좀 더 디테일하게 생각해야함

이전에 조이스틱? 문제가 이런식이었던 것 같은데, 그것보다는 쉽게 느껴졌다.

문제 접근

바로 생각난거는 일단 그 자리에서 5보다 크냐? 작냐? 였던 것 같다. 5보다 작으면 그냥 빼주는게 맞고, 5보다 크면 위로 올려서 크게 빼주는게 맞고, 그게 아니면 그냥 바로 빼주는게 이득이라는 점이다.

그래서 결국 이렇게 해주려면은 어떻게 이게 10000이면 이걸 어떻게 10^4 와 10^5 사이인지 어떻게 판단하지? 싶다가 각 자리수를 써보다보니 이걸 배열로해서 원소끼리 판단해주면 되지 않을까? 싶었다.


문제풀이

var storey_arr = Array(String(storey)).compactMap { Int(String($0)) }

이렇게해서 16이 들어오면 짤라서 [1,6] 이렇게 저장될 수 있게 했다. 그리고 이게 숫자 자리 올림이 있어야해서 이걸 reversed상태로 반복문을 돌려줄 것이다.

1차 제출 코드

import Foundation

func solution(_ storey: Int) -> Int {
    var answer = 0

    var storey_arr = Array(String(storey)).compactMap { Int(String($0)) }

    var upNumber = false // 10넘으면 올림해주기
    for num in storey_arr.reversed() {
        var counting = num
        if upNumber {
            counting += 1
        }
        if counting <= 9 {
            upNumber = false
        }
        if counting <= 5 {
            answer += counting
        }
        else {
            answer += (10 - num)
            upNumber = true
        }
    }
    return answer
}

예제도 잘 맞길래 한 번에 잘 풀린지 알았으나..

채점 결과

정확성: 23.1
합계: 23.1 / 100.0
3개빼고 다틀렸다. 근데 조금만 조정해주면 될 것 같기도..?


반례를 찾아보니 555가 있었다 이게 14가 나와야한다는데..

나는 이게 15가 나와서 왜인지알아보니 5일때를 잘 알아냈어야했다.
5일때는 올리는 것 내리는 것 전부 5번을 소요하는데, 올린다음에 내리는게 한번 추가되니까 <=5 로 묶어줘서 풀었었는데, 이게 다음 숫자가 5이상이면 5일때 올려주는게 이득임을 알아냈다.

그래서 isFive라는 친구를 만들어서 처음에 num을 조절하도록했다.

최종 제출코드

import Foundation

func solution(_ storey: Int) -> Int {
    var answer = 0
    var storey_arr = [0] + Array(String(storey)).compactMap { Int(String($0)) }

    var upNumber = false // 10넘으면 올림해주기
    var isFive = false
    for num in storey_arr.reversed() {
        var counting = num
        if isFive {
            if counting >= 5 {
                counting += 1 // 올림 적용
            }
            isFive = false
        }
        if upNumber {
            counting += 1
        }
        upNumber = false
        if counting < 5 {
            answer += counting
        }
        else if counting > 5 {
            answer += (10 - counting)
            upNumber = true
        }
        else if counting == 5 {
            answer += 5
            isFive = true
        }
    }
    return answer
}

Q: `var storey_arr = [0] + Array(String(storey)).compactMap { Int(String($0)) } 이건 뭔데?

A: 이거는 맨마지막 숫자에서 이걸 올림해주면 그 자리가 없더라구요. 그래서 맨끝(실제 숫자에서는 맨앞)자리가 올라갔을 때 그 앞자리 공백도 계산해주려고 처음에 [0]을 추가했습니다.


채점 결과

정확성: 100.0
합계: 100.0 / 100.0
처음 문제 보고 막막했었는데, 잠깐 고민하니까 이걸 배열로 해줘야겠다라는 생각이 들어서 좀 만족스러운 문제였다.


타인의 코드

import Foundation

func solution(_ storey:Int) -> Int {
    var storey = storey
    var result = 0

    while storey != 0 {
        if storey % 10 > 5 || (storey % 10 == 5 && (storey / 10) % 10 >= 5) {
            result += 10 - (storey % 10)
            storey = (storey / 10) + 1
        } else {
            result += storey % 10
            storey = storey / 10
        }
    }

    return result
}
  1. 문제에서 요구하는대로 앞자리부터 계산하는 방식
  2. 나는 isFive로 넘겨줬는데 여기서는 storey에 당장10을 나눠보고 그게 5보다 크면 이제 올림시켜주는 방식으로 했다. 더 직관적인 것 같기도 ?
  3. 중간에 재귀방식을 생각해봤어쓴ㄴ데, 이런방식이면 이제 원본 숫자를 계속 변경시켜주면서 재귀로 해도 될 것 같았다. (찾아보니 다른 정답코드에 재귀가 존재)
profile
기억보단 기록을

0개의 댓글