Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- TCA
- UI
- network
- xcode
- navigationsplitview
- regex
- SWIFT
- Navigation
- IOS
- 모바일
- Git
- SWIFTUI
- tuist #xcodecloud #ios #ci/cd #swiftlint #firebase
- test
- iOS 13.0+
- Tuist
- concurrency
- github
- Firebase
- xcodecloud
- combine
- swiftdata
- 정규표현식
- 개발
- composablearchitecture
- ObjC
- iOS 개발자
- uikit
- Alamofire
- ios18
Archives
- Today
- Total
iOS 개발 기록
Swift - 셔틀버스(프로그래머스, Lv3) 본문
728x90
문제 설명
알고리즘
풀이에 사용한 알고리즘의 의사코드.
n의 범위가 1 이상, 10 이하이기 때문에 차량 시간대 별로 인원을 정리해두면 반복문을 10번만 돌려도 값을 구할 수 있었다.
첫번째 코드
import Foundation
func solution(_ n:Int, _ t:Int, _ m:Int, _ timetable:[String]) -> String {
// 1. 차량 구하기
var busTime = [Date]()
for i in 1...n {
busTime.append(busTimeTable(i, t))
}
// -> 막차보다 늦는 인원 자르고 계산
var times = [Date]()
timetable.forEach { if busTime.last! >= convertDate($0) {
times.append(convertDate($0))
}}
times.sort()
// 2. 차량 탑승 인원에 따라 경우 나눔.
var peopleCount = pCount(busTime, times, m)
var personCount = 0
// print(peopleCount)
for i in 0..<peopleCount.count {
// 현재 탑승인원 초과하면 다음 차로 넘김
if peopleCount[i] >= m {
// 막차가 꽉 찬 경우 막차의 마지막 인원보다 1분 빠른 값 반환
if i == peopleCount.count-1 {
let index = personCount + m - 1
return printDate(Date(timeInterval: -60, since: times[index]))
} else {
// 막차가 아닌 경우, 다음 차 탑승 인원 계산
peopleCount[i+1] += (peopleCount[i] - m)
personCount += m
}
} else {
// 막차가 비어있으면 막차 탄다.
if i == peopleCount.count-1 {
return printDate(busTime[i])
} else {
// 앞에서부터 사람 수 체크
personCount += peopleCount[i]
}
}
}
return ""
}
// 막차시간
func busTimeTable(_ n: Int, _ t: Int) -> Date {
let intervalTime = (n-1) * t * 60
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let start = dateFormatter.date(from: "09:00")!
let last = Date(timeInterval: TimeInterval(intervalTime), since: start)
return last
}
// 시간대별 탑승 인원 구하기
func pCount(_ busTime: [Date], _ peopleTime: [Date], _ m: Int) -> [Int] {
var array = Array(repeating: 0, count: busTime.count)
for time in peopleTime {
for i in 0..<busTime.count {
if time <= busTime[i] {
array[i] += 1
break
}
}
}
return array
}
// String -> Date 포맷으로 변환
func convertDate(_ str: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.date(from: str)!
return date
}
// Date -> String 포맷으로 변환
func printDate(_ date: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
return dateFormatter.string(from: date)
}
통과 하기는 했는데 dateFormatter를 이용해 Date형으로 변환하여 계산했더니 계산 속도가 느렸다. 코딩테스트에서 Date는 사용하지 않는게 좋겠다.
두번째 코드
import Foundation
func solution(_ n:Int, _ t:Int, _ m:Int, _ timetable:[String]) -> String {
// 1. 차량 구하기
let busTime = busTimeTable(n, t)
let peopleTimeTable = people(timetable)
// 2. 시간대별 탑승 인원 구하기
var peopleCount = pCount(busTime, peopleTimeTable, m)
var personCount = 0 // 막차 마지막 탑승 인원 index 파악하기 위한 변수
for i in 0..<peopleCount.count {
// 현재 탑승인원 초과하면 다음 차로 넘김
if peopleCount[i] >= m {
// 막차가 꽉 찬 경우 막차의 마지막 인원보다 1분 빠른 값 반환
if i == peopleCount.count-1 {
let index = personCount + m - 1
return printTime(peopleTimeTable[index]-1)
} else {
// 막차가 아닌 경우, 다음 차 탑승 인원 계산
peopleCount[i+1] += (peopleCount[i] - m)
personCount += m
}
} else {
// 막차가 비어있으면 막차 탄다.
if i == peopleCount.count-1 {
return printTime(busTime[i])
} else {
// 앞에서부터 사람 수 체크
personCount += peopleCount[i]
}
}
}
return ""
}
// 버스시간표
func busTimeTable(_ n: Int, _ t: Int) -> [Int] {
var time = [Int]()
// 540은 첫 버스 시간 09:00를 분으로 계산한 것.
for i in 0..<n {
time.append(540 + (t * i))
}
return time
}
// 대기 시간 변환
func people(_ peopleTime: [String]) -> [Int] {
var people = [Int]()
peopleTime.forEach{ people.append(Int($0.prefix(2))! * 60 + Int($0.suffix(2))!) }
people.sort()
return people
}
// 시간대별 탑승 인원 구하기
func pCount(_ busTime: [Int], _ peopleTime: [Int], _ m: Int) -> [Int] {
var array = Array(repeating: 0, count: busTime.count)
for time in peopleTime {
for i in 0..<busTime.count {
if time <= busTime[i] {
array[i] += 1
break
}
}
}
return array
}
// 분을 시로 바꾸어 출력
func printTime(_ time: Int) -> String {
let hour = String(time / 60).count == 1 ? "0\(String(time / 60))" : String(time / 60)
let min = String(time % 60).count == 1 ? "0\(String(time % 60))" : String(time % 60)
return "\(hour):\(min)"
}
똑같은 방법인데 시간만 Date가 아니라 Int형으로 계산했는데 속도의 향상이 엄청났다.
배운점
코테에 Date 쓰지마라 ...
'코딩테스트' 카테고리의 다른 글
Swift - 오픈채팅방(프로그래머스, Lv2) (0) | 2022.04.12 |
---|---|
Swift - 추석 트래픽 (프로그래머스, Lv.3) (0) | 2022.04.12 |
Swift - 2178번 미로 [BaekJoon] (0) | 2022.04.05 |
Swift - 큰 수 만들기(프로그래머스, 그리디 Lv2) (0) | 2022.03.31 |