알고리즘/프로그래머스

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

녕이 2023. 1. 4. 16:47
728x90

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

구현문제인 것 같다.

차근차근해야 할 것을 정리하고 코드를 짜면 풀리는 문제! 대신 조건들을 확인할게 꽤 있어서 시간이 좀 걸렸드아

 

 

문제를 풀면서 정리하면서 한 것인데 꽤... 잘된 거 같아서 올려본다ㅎ

쉽게 정리하자면

 

1. 시각/차량번호/입출 분리하기(split(separator:))

2. IN이라면 dictionary에 intime 업데이트

3. OUT이라면 intime과 outtime를 사용해서 주차시간 계산(calculateParkingTime())

4. records를 모두 순회했다면 이제 누적 주차시간에 맞게 주차비 계산 -> 새로운 dictionary에 [차량번호:주차비]

5. 차량번호가 작은 순서대로 정렬하고 주차비만 출력

 

다행스럽게도,, 누적주차시간이라 구현하기 쉬웠다. 만약 출차할 때마다 계산했어야 했다면~~ 좀 귀찮아졌을지도ㅎㅎ 

Dictionary value에는 내가 따로 만들어준 Car 구조체를 넣어줬다. 차량번호에 따른 값들이 워낙 많아서...

 

추가적으로! 조심해야 할 것들이 있는데

 

- 초과시간이 단위시간으로 나눠지지 않을 경우 올림을 수행한다

  % 연산자를 이용해 나머지가 있다면 + 1을 해줬다. 

- 출차기록이 없으면 23:59에 출차한 것

  예제에서는 0000 차량이 출차기록이 없었다.

  여기서는 isParking이라는 부울 변수를 구조체에 추가해서 아직도 안 나가고 주차되어 있는지 확인해 줬다.

  출차하면 isParking = false, 입차하면 isParking = true

  모든 records를 돌았는데 isParking이 true인 애가 있다면 23:59에 나간 것으로 calculateParkingTime으로 주차 시간을 계산해 줬다.

  

문자열을 분리하는 게 조금 까다로웠는데 하도 자주 해서 이제는 쉽게 진행할 수 있었다. 

subscript로 부분 문자열을 생성해 줬는데, 여기서 index함수를 통해 범위를 지정해 줬다.

(calculateParkingTime함수 내 out/in hour, minute 부분)

 

import Foundation

struct Car {
    var intime: String
    var cumulativeSum: Int
    var isParking: Bool
}

func calculateParkingTime(inTime: String, outTime: String) -> Int {
    var parkingTime = 0
    var outH = Int(outTime[outTime.startIndex..<outTime.index(outTime.startIndex, offsetBy: 2)])!
    let outM = Int(outTime[outTime.index(outTime.startIndex, offsetBy: 3)..<outTime.endIndex])!
    let inH = Int(inTime[inTime.startIndex..<inTime.index(inTime.startIndex, offsetBy: 2)])!
    let inM = Int(inTime[inTime.index(inTime.startIndex, offsetBy: 3)..<inTime.endIndex])!
    
    //minute부터 계산
    if inM > outM {
        parkingTime = outM + 60 - inM
        outH -= 1
    }else {
        parkingTime = outM - inM
    }
    
    parkingTime += (outH - inH) * 60 //hour 계산 (분으로 만들어야 함)
    return parkingTime
}

func solution(_ fees:[Int], _ records:[String]) -> [Int] {
    var carDictionary = [String:Car]()
    var final = [String:Int]()
    let defaultTime = fees[0], defaultFee = fees[1], unitTime = fees[2], unitFee = fees[3]
    for record in records {
        let recordArray = record.split(separator: " ").map{ String($0) }
        if recordArray[2] == "IN" {
            if carDictionary[recordArray[1]] == nil {
                carDictionary[recordArray[1]] = Car(intime: recordArray[0], cumulativeSum: 0, isParking: true)
            } else {
                carDictionary[recordArray[1]]!.intime = recordArray[0]
                carDictionary[recordArray[1]]!.isParking = true
            }
        }else { //OUT
            let inTime = carDictionary[recordArray[1]]!.intime //입차시간
            //출차 - 입차 시간 구하기 (주차시간)
            carDictionary[recordArray[1]]!.cumulativeSum += calculateParkingTime(inTime: inTime, outTime: recordArray[0])
            carDictionary[recordArray[1]]!.isParking = false
        }
    }
    //딕셔너리에 있는 애들의 누적합을 통해 주차요금 계산하기
    for car in carDictionary {
        var sum = car.value.cumulativeSum
        if car.value.isParking == true { //23:59에 출차
            sum += calculateParkingTime(inTime: car.value.intime, outTime: "23:59")
        }
        var parkingFee = 0
        if sum > defaultTime {
            var overTime = (sum - defaultTime) % unitTime != 0 ? (sum - defaultTime) / unitTime + 1 : (sum - defaultTime) / unitTime //나누어 떨어지지 않으면 올린다
            parkingFee = defaultFee + overTime * unitFee
        } else {
            parkingFee = defaultFee
        }
        final[car.key] = parkingFee
    }
    return final.sorted { return $0.key < $1.key }.map{ $0.value }
}

 

 


 

이번엔 다른 사람들의 코드를 확인해 보자.

코드가 길어서 그런가 다른 사람 코드 보기 싫다...

하지만 봐야지...

 

오 어떤 분의 코드에서 분리를 ":", " " 동시에 해줬다!!

나는 " "로만 분리하고, 시각에 관한 것은 index로 subscript를 사용했는데 생각해 보니 ":"로도 쉽게 분리된다...

왜 생각하지 못했을까ㅠㅠ 앞에서는 공백을 split으로 했으면서... ":"는 갑자기 subscript로 해버린..ㅋㅋㅋㅋ

record.components(separatedBy: [":", " "])

이렇게 바꿔서 하기~

 

 

 

728x90