알고리즘관련/문제풀이

[programmers][1차]셔틀버스.swift

안토니1 2024. 1. 30. 22:05

코딩테스트 연습 2018 KAKAO BLIND RECRUITMENT [1차] 셔틀버스

https://school.programmers.co.kr/learn/courses/30/lessons/17678

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 이해

문제 이해에 꽤나 애를 먹었다.

설명이 좀 난해하게 작성되어있어 잘못 이해한채로 풀다보니 삽질을 오래했던 문제이다.

결과적으로 구현은 쉬웠지만 실제 시험장에서 마주했더라면 손도 못댔을 것 같다.

 

이 문제를 풀기 위해선 문제의 핵심인 "셔틀을 타고 사무실로 갈 수 있는 도착 시각 중 제일 늦은 시각"을 어떻게 바라보냐에서 시작된다.

 

귀찮으니, 게으르니 같은 소리때문에 좀 헷갈렸는데 여기서의 셔틀을 정의해보면 다음과 같다.

 

1. 셔틀은 09:00에 무조건 최대 m명을 싣고 출발한다.

2. 셔틀을 타기 위해선 출발 시간까지 기다리고 있어야 한다.

3. 셔틀이 2회이상 운영할 경우 다음 셔틀은 T분 이후에 출발한다.

4. 셔틀을 못타는 인원이 발생할 수 있다.

5. "나"는 운행할 수 있는 마지막 셔틀의 가장 마지막으로 탑승해야한다.

 

문제 풀이

위의 사실을 염두해보고 문제를 풀기 위한 조건을 따져보자.

 

1) 시간 계산을 편하게 하기 위해 Timetable을 모두 "분"으로 치환한다.

2) Timetable을 정렬해 시간 순서대로 확인할 수 있도록 한다.

3) 만약 m번째로 오게되는 사람이 존재할 경우, 그 사람보다 1분 먼저 도착해야한다.

4) 그렇지 않다면 가장 마지막으로 출발하게되는 버스의 시간이 정답이다.

 

대기할 수 있는 시간이 00:01분에서 23:59분 까지이고 다음 날짜로 넘어가지 않기에 로직 자체는 단순한편이다.

 

문제 코드

func solution(_ n:Int, _ t:Int, _ m:Int, _ timetable:[String]) -> String {
    let startTime = 9*60
    let sortedTimetable = timetable.map { Int($0.prefix(2))!*60 + Int($0.suffix(2))! }.sorted()
    let crewCount = timetable.count
    
    var crewIndex = 0
    var lastTime = startTime + (n-1) * t
    
    for idx in 0..<n {
        var cnt = 0
        while crewIndex < crewCount, sortedTimetable[crewIndex] <= startTime + (idx * t) {
            cnt += 1
            crewIndex += 1
            if cnt == m {
                if idx == n-1 {
                    lastTime = sortedTimetable[crewIndex-1]-1
                }
                break
            }
        }
    }
    
    return String(format: "%02d:%02d", lastTime/60, lastTime%60)
}