[Swift] 프로그래머스 주차 요금 계산(lv. 2)
1. 문제
https://school.programmers.co.kr/learn/courses/30/lessons/92341
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
2. 접근
크게는 두 가지로 나눌 수 있었다. 하나는 어떤 차량이 들어왔다가 나갈 때까지 '들어온 시간'을 저장하는 부분, 또 하나는 차량이 하루에 두 번 이상 왔다 갈 수도 있으니 전체 누적 시간을 저장하는 부분이 필요했다.
그 다음 누적 시간을 파악한 다음에 차량의 번호가 작은 순 대로 하루의 요금을 제시를 해야 하는 부분이 필요했다.
나머지 자잘한 조건은 조건문 분기를 통해서 해결하면 될 것 같았고 그렇게 구현하였다.
아래 코드의 stackTimeDict은 차량별로 누적 주차시간을 저장해 둔 것이고, 차량번호와 시간을 매칭하여 Dictionary로 데이터를 저장하였다. 그리고 timeDict은 차량별로 IN, OUT 간의 시간을 측정하기 위해 만든 Dictionary다.
Dictionary를 쓴 이유는 '차량번호와 시간 또는 누적시간'과의 매칭이 필요했기 때문이다.
그 다음 반복문에서는 records를 차례로 읽는데, temp라는 임시 배열 저장소를 두어 문자열을 다시 배열로 분할하여 저장하였다. 공백을 기준으로 필요한 데이터가 나누어지기 때문에 공백을 기준으로 나누어 배열을 저장하였다.
그 다음 temp 배열의 2번 인덱스에 있는 원소는 항상 IN or OUT이기에 switch문을 가지고 각 상황을 분리하여 처리하였다. IN인 경우는 들어온 시간을 '분' 단위로 변환하여 저장하였는데, 00시 00분을 기준으로 23시 59분까지 하루의 주차요금으로 정산하기 때문에 분 단위로 변환하여 저장해도 상관은 없었다. 나중에 나간 시간 - x 로 하면 '들어와 있는' 시간은 측정할 수 있기 때문이다.
그 다음 OUT인 경우, 나간 시간도 00시 00분을 기준으로 분 단위로 변환하여 outTime이라는 변수로 둔다. 그런 다음 주차한 시간을 parkTime이라고 하고 (나간 시간 - 들어온 시간)으로 하여 저장한다.
만약 기존에 들어왔던 차량이라면, stackTimeDict에 차량번호와 총 주차시간이 들어가 있을 것이다. 그러면 그 key의 짝인 value를 그 시간만큼 증가시켜주고, 만약 stackTimeDict에 없다면, 처음 들어왔다 나간 차기 때문에 새롭게 stackTimeDict에 추가를 해준다. 그런 다음 기존의 timeDict에서는 그 차량의 번호와 들어와 있던 시간을 모두 삭제해준다.
그 다음으로 반복문을 돌고나면 records는 모두 확인한 것인데, 아직 처리하지 못한 것이 있다. 만약 timeDict에 남아있는 원소가 있다면, 그 날 들어온 기록은 있지만 나간 기록이 없는 차량이 남아 있는 것이다. 그런 차량은 23시 59분에 출차한 것으로 간주하여 계산하라는 조건이 있었기 때문에 처리를 해주어야 한다. 1439분을 기준으로 들어온 시간을 빼주고 윗 문단과 같은 처리를 해준다.
sortDict는 차량번호가 낮은 순으로 배열을 정렬한 다음 value만 남겨놓은 배열이다. 그 배열에 각각 요금을 곱해주면 최종적으로 요금을 계산하여 리턴할 수 있다.
3. 코드
import Foundation
func solution(_ fees:[Int], _ records:[String]) -> [Int] {
var stackTimeDict: Dictionary = [Int : Int]()
var timeDict: Dictionary = [Int : Int]()
for i in records {
let temp = i.split(separator: " ")
switch temp[2] {
case "IN":
let timeSet = temp[0].split(separator: ":").compactMap({ Int($0) })
timeDict[Int(temp[1])!] = timeSet[0] * 60 + timeSet[1]
case "OUT":
let timeSet = temp[0].split(separator: ":").compactMap({ Int($0) })
let outTime = timeSet[0] * 60 + timeSet[1]
let parkTime = outTime - timeDict[Int(temp[1])!]!
if stackTimeDict.contains(where: { $0.key == Int(temp[1])!}) {
stackTimeDict[Int(temp[1])!]! += parkTime
timeDict.remove(at: timeDict.firstIndex(where: { $0.key == Int(temp[1])!})!)
} else {
stackTimeDict[Int(temp[1])!] = parkTime
timeDict.remove(at: timeDict.firstIndex(where: { $0.key == Int(temp[1])!})!)
}
default:
return []
}
}
if timeDict.count > 0 {
for i in timeDict {
if stackTimeDict.contains(where: { $0.key == i.key }) {
stackTimeDict[i.key]! += 1439 - i.value
} else {
stackTimeDict[i.key] = 1439 - i.value
}
}
}
var sortDict = stackTimeDict.sorted(by: { $0.key < $1.key }).compactMap({ $0.value })
for (index, i) in sortDict.enumerated() {
var fee = fees[1]
if i > fees[0] {
fee += Int(ceil(Double(i - fees[0]) / Double(fees[2]))) * fees[3]
sortDict[index] = fee
} else {
sortDict[index] = fee
}
}
return sortDict
}
'Problem Solving' 카테고리의 다른 글
[Swift] 프로그래머스 [1차] 뉴스 클러스터링(lv. 2) (0) | 2023.03.28 |
---|---|
[Swift] 프로그래머스 프린터(lv. 2) (0) | 2023.03.27 |
[Swift] 프로그래머스 기능개발(lv. 2) (0) | 2023.03.24 |
[Swift] 프로그래머스 튜플(lv. 2) (0) | 2023.03.23 |
[Swift] 프로그래머스 위장(lv. 2) (0) | 2023.03.22 |
댓글