문제
func solution(_ fees:[Int], _ records:[String]) -> [Int] {
let baseTime = fees[0]
let baseCost = fees[1]
let unitTime = fees[2]
let unitCost = fees[3]
var dic: [String:[Int]] = [:]
var answer: [Int] = []
for car in records {
let record = car.split(separator: " ").map { String($0) }
let minute = record[0].split(separator: ":").compactMap { Int($0) }
let time = minute.reduce(0) { ($0 * 60) + $1 }
dic[record[1], default: []].append(time)
}
for record in dic.sorted(by: { $0.key < $1.key }) {
var values = record.value
var currentTime = 0
var times: Int = 0
if values.count % 2 == 0 {
for (i, time) in values.enumerated() {
if (i + 1) % 2 == 0 {
times += (time - currentTime)
currentTime = 0
} else {
currentTime = time
}
}
} else {
let outCost = 1439 - values.removeLast()
for (i, time) in values.enumerated() {
if (i + 1) % 2 == 0 {
times += (time - currentTime)
currentTime = 0
} else {
currentTime = time
}
}
times += outCost
}
if times <= baseTime {
answer.append(baseCost)
} else {
var excess = Int(Double((times - baseTime) / unitTime))
if ((times - baseTime) % unitTime) != 0 {
excess += 1
}
let cost = baseCost + Int(excess * unitCost)
answer.append(cost)
}
}
return answer
}

시간 계산 코드 중복
for (i, time) in values.enumerated() {
if (i + 1) % 2 == 0 {
times += (time - currentTime)
currentTime = 0
} else {
currentTime = time
}
}
이 로직은 values.count % 2 == 0과 else 둘 다에 들어가 있는데, 중복된 코드이기 때문에 개선이 가능하다.
조건 분기 없이 한 번만 순회하면서 IN과 OUT 페어를 처리하고, 짝이 안 맞는 경우 마지막에 23:59를 직접 계산하는 방식이 더 깔끔하다.
올림 계산 방식 복잡
var excess = Int(Double((times - baseTime) / unitTime))
if ((times - baseTime) % unitTime) != 0 {
excess += 1
}
이 부분은 Swift의 ceil을 사용하거나, 정수 연산으로도 올림을 간단하게 구현할 수 있다.
let over = max(0, times - baseTime)
let cost = baseCost + ((over + unitTime - 1) / unitTime) * unitCost
출차되지 않은 차량 처리 방식
출차 안 된 차량 처리 로직도 조건 분기 없이 처리할 수 있을 것이다.
모든 차량의 시간을 짝지어 순회하면서, 마지막에 남은 IN이 있으면 23:59로 간주해 처리하면 된다.
func solution(_ fees: [Int], _ records: [String]) -> [Int] {
let baseTime = fees[0]
let baseCost = fees[1]
let unitTime = fees[2]
let unitCost = fees[3]
var carRecords: [String: [Int]] = [:]
// 1. 기록을 정리 (입차 시간 저장)
for record in records {
let parts = record.split(separator: " ").map { String($0) }
let timeParts = parts[0].split(separator: ":").compactMap { Int($0) }
let totalMinutes = timeParts[0] * 60 + timeParts[1]
let carNumber = parts[1]
carRecords[carNumber, default: []].append(totalMinutes)
}
var result: [(String, Int)] = []
for (carNumber, times) in carRecords {
var totalTime = 0
var stack = times
// 2. IN/OUT 짝 계산
while !stack.isEmpty {
let inTime = stack.removeFirst()
let outTime = stack.isEmpty ? 1439 : stack.removeFirst()
totalTime += outTime - inTime
}
// 3. 요금 계산
let over = max(0, totalTime - baseTime)
let fee = baseCost + ((over + unitTime - 1) / unitTime) * unitCost
result.append((carNumber, fee))
}
// 4. 차량 번호 오름차순 정렬 후 요금만 리턴
return result.sorted { $0.0 < $1.0 }.map { $0.1 }
}
