알고리즘 문제 풀이

[Swift] 프로그래머스 LV2. 주차 요금 계산

lgvv 2022. 4. 16. 02:10

프로그래머스 LV2. 주차 요금 계산

 

접근 방식

 

2022 KAKAO BLIND RECRUITMENT 문제. 레벨은 2지만 점수는 1점이라, 알고리즘보다 입출차 기록을 순서대로 처리하는 구현에 가까움.

 

딕셔너리 세 개로 상태를 나눔. dict는 차량번호별 입차 시각, totalTimeArray는 차량번호별 누적 주차 시간(분), priceDict는 차량번호별 요금.

 

records를 순회하며 입차면 입차 시각을 저장하고, 같은 차의 출차를 만나면 그 구간 시간을 계산해 누적한 뒤 입차 기록을 지움. 끝까지 출차하지 않은 차량은 23:59에 나간 것으로 처리함.

 

요금은 누적 시간에서 기본 시간을 뺀 초과분을 단위 시간으로 나눠 올림하고(나머지가 있으면 +1) 단위 요금을 곱해 기본요금에 더함.

 

코드

 

    import Foundation

    func solution(_ fees:[Int], _ records:[String]) -> [Int] {
        
        
        var dict: [String: String] = [:] // 차량번호 : 시간
        var totalTimeArray: [String: Int] = [:] // 차량번호 : 누적시간
        var priceDict: [String: Int] = [:] // 차량번호 : 금액
        
        // records 내에서의 인덱스와 차랑번호를 저장
        records.forEach { record in
            let info = record.components(separatedBy: " ")
            let carNumber = info[1]
            
            if dict[carNumber] == nil { // 아직 IN하지 않았다면
                dict[carNumber] = info[0]
                 if totalTimeArray[carNumber] == nil {
                    totalTimeArray[carNumber] = 0
                }
            } else { // 이미 차가 들어왔다면
                // 계산하는 로직 수행해야 합니다.
                let inTime = dict[carNumber]! // 이전에 들어왔던 시간
                let time = calueteTime(fees: fees, inTime: inTime, outTime: info[0]) // 이번 구간에서 주차한 시간 계산
                
                dict[carNumber] = nil // 출차 처리
                
                if totalTimeArray[carNumber] == nil {
                    totalTimeArray[carNumber] = time
                } else {
                    totalTimeArray[carNumber]! += time
                }
            }
        }
        
        dict.forEach { carNumber, value in
            let inTime = dict[carNumber]!
            let time = calueteTime(fees: fees, inTime: inTime, outTime: "23:59")
            
            totalTimeArray[carNumber]! += time
            dict[carNumber] = nil // 굳이 이 코드는 없어도 된다.
        }
        
        totalTimeArray.forEach { carNumber, time in
            let time = time - fees[0] // 기본시간 빼주기
            var price = fees[1] // 기본금액
            
            if time <= 0 {
                // 기본 금액만 내면 된다.
            } else {
                var count = time / fees[2]
                if time % fees[2] != 0 {
                    count += 1
                }
                
                price += count * fees[3]
            }
            
            priceDict[carNumber] = price
        }
        var answer = priceDict.sorted { $0.key < $1.key }.map { $0.value }
        
        return answer
    }

   func calueteTime(fees: [Int], inTime: String, outTime: String) -> Int{
        let inTimeArray = inTime.components(separatedBy: ":").map { Int($0)! }
        let outTimeArray = outTime.components(separatedBy: ":").map { Int($0)! }
        
        let hour = outTimeArray[0] - inTimeArray[0]
        let minute = outTimeArray[1] - inTimeArray[1]
        
        return hour * 60 + minute
    }