HIT해
[Swift/프로그래머스] 과제 진행하기 (?) 본문
728x90
https://school.programmers.co.kr/learn/courses/30/lessons/176962
시간을 계산할때 : 을 기준으로 split을 해준뒤 시간에는 60을 곱해서 계산하는 방식을 사용했었는데
DateFormatter()를 사용해서 날짜를 계산하고 싶었다.
처음 풀이
import Foundation
func solution(_ plans:[[String]]) -> [String] {
// 가장 최근에 멈춰둔 과제니까 stack
// Swift는 사실 상관없음
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
var wait = [(String,Int)]()
var answer = [String]()
let sortedPlans = plans.sorted {
dateFormatter.date(from: $0[1])! < dateFormatter.date(from: $1[1])!
}
var cutLine : Date?
for (index,plan) in sortedPlans.enumerated() {
// 시작하는 시간
let currentPlanTime = dateFormatter.date(from:plan[1])!
// 끝나는 시간
let currentTimeAfter = Calendar.current.date(byAdding: .minute, value : Int(plan[2]) ?? 0, to : currentPlanTime)!
// 다음 일정
if index+1 < sortedPlans.count {
cutLine = dateFormatter.date(from:sortedPlans[index+1][1])
// 수행 가능한 경우
if let cutLine = cutLine, cutLine >= currentTimeAfter{
answer.append(plan[0])
// 다음 시작 시간까지 남은 시간
var remainTime = Int(cutLine.timeIntervalSince(currentTimeAfter) / 60)
while !wait.isEmpty && remainTime > 0 {
let last = wait.removeLast()
if remainTime >= last.1 {
remainTime -= last.1
answer.append(last.0)
}else{
wait.append((last.0,last.1 - remainTime))
remainTime = 0
}
}
}
// 수행 불가능한 경우
else{
let remainTime = Int(plan[2])! - Int(cutLine!.timeIntervalSince(currentPlanTime) / 60)
wait.append((plan[0], remainTime))
}
}
// 마지막 일정이라면 계산없이 바로 추가.
else{
answer.append(plan[0])
}
}
while !wait.isEmpty {
let plan = wait.popLast()!
answer.append(plan.0)
}
return answer
}
Date를 연산하는 과정에서 시간초과가 발생했다
개선한 코드
import Foundation
func solution(_ plans:[[String]]) -> [String] {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
var wait = [(String,Int)]()
var answer = [String]()
let sortedPlans = plans.sorted {
dateFormatter.date(from: $0[1])! < dateFormatter.date(from: $1[1])!
}
for (index,plan) in sortedPlans.enumerated() {
// 시작하는 시간
let currentPlanTime = dateFormatter.date(from:plan[1])!
let duration = Int(plan[2])!
// 다음 일정
if index+1 < sortedPlans.count {
let nextStartTime = dateFormatter.date(from:sortedPlans[index+1][1])!
let timeUntilNext = Int(nextStartTime.timeIntervalSince(currentPlanTime) / 60)
// 수행 가능한 경우
if timeUntilNext >= duration {
answer.append(plan[0])
// 다음 시작 시간까지 남은 시간
var remainTime = timeUntilNext - duration
while !wait.isEmpty && remainTime > 0 {
let last = wait.removeLast()
if remainTime >= last.1 {
remainTime -= last.1
answer.append(last.0)
} else {
wait.append((last.0, last.1 - remainTime))
break
}
}
}
// 수행 불가능한 경우
else {
wait.append((plan[0], duration - timeUntilNext))
}
}
// 마지막 일정이라면 계산없이 바로 추가
else {
answer.append(plan[0])
}
}
while !wait.isEmpty {
let plan = wait.popLast()!
answer.append(plan.0)
}
return answer
}
Date 객체 생성 부분
// 변경 전
let currentTimeAfter = Calendar.current.date(byAdding: .minute, value : Int(plan[2]) ?? 0, to : currentPlanTime)!
cutLine = dateFormatter.date(from:sortedPlans[index+1][1])
// 변경 후
let duration = Int(plan[2])!
let nextStartTime = dateFormatter.date(from:sortedPlans[index+1][1])!
let timeUntilNext = Int(nextStartTime.timeIntervalSince(currentPlanTime) / 60)
// 변경 후
if timeUntilNext >= duration {
// 변경 후
var remainTime = timeUntilNext - duration
시간과 시간을 비교하는게 아닌 남은 시간과 남은 시간을 비교해 Date Date 비교가 아닌 Int끼리의 비교로 시간을 단축시켰다.
'Swift > Swift 알고리즘' 카테고리의 다른 글
[Swift/프로그래머스] 리코쳇 로봇 (BFS) (0) | 2024.11.01 |
---|---|
[Swift] DateFormatter (0) | 2024.11.01 |
[Swift/프로그래머스] 연속된 부분 수열의 합 (그리디) (0) | 2024.10.31 |
[Swift/프로그래머스] 요격 시스템 (그리디) (0) | 2024.10.31 |
[Swift] Dictionary (0) | 2024.10.31 |