[프로그래머스/Swift] 주차 요금 계산
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: [":", " "])
이렇게 바꿔서 하기~