iyOmSd/Title: Algorithm풀이

[Swift Algorithm] 프로그래머스 17683 방금 그곡 (2018 카카오 블라인드)

냄수 2020. 10. 29. 14:22
반응형

programmers.co.kr/learn/courses/30/lessons/17683

 

코딩테스트 연습 - [3차] 방금그곡

방금그곡 라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 '방금그곡' 서비스를 이용하곤 한다. 방금그곡에서는 TV,

programmers.co.kr

 

풀이과정

 

처음에 접근하기위한 생각은

문제에 시간만큼 문자열의 길이가 결정되는 것 같았어요

그래서 시간을 분리해서 계산해서 분단위로 맞추고

분만큼 문자열을 재생성하고 비교를 하면 될것 같았어요

 

비교할 때

C#, D#, F#, G#, A# 같이 #붙은 경우가있기때문에 contains을이용하게되면

 

원하는문자열: ABC

생성된문자열: ABC#

이런경우 원하는문자열이 포함되기때문에 예외가 생겨버리죠

그래서 생각한게

문자열 마지막 부분에 #만 검사하려고 했어요

 

원하는문자열: A#BC

생성된문자열: A#BC#

이런경우에

A#BC이 포함된 문자열의 index를 찾고(Bold처리) 그 다음 index에 #이 있는지없는지를 판별해서 처리하려 했어요

#이 있다면 정답이아니기때문에 제외해야겠죠?

 

논리는 맞는것 같지만 많은 테스트케이스를 통과를 못하더라구요

 

생각치 못했던게 있었어요

문자열을 파싱할 때

분만큼 재생성하는데 만약 #이 포함되어있다면 C#과 C는 모두 1분을 소모하는데 지금 작성한코드는 C#이 2분을 소모하게되서 절대 맞을리가 없겟네요 ㅎㅎ...

예를 들면 이런경우죠

 

분: 3, 입력문자열: A#BC#D 일때

A#BC#이 만들어져야 정상인데

지금같은경우는 A#B만 만들어지겠어요..

 

 

다시 생각해보면!

처음에 생각한 논리는 맞는것 같았구요

다른점이라면

#붙은 문자를 다른 문자로 치환하면 될 것 같네요

A# -> a

C# -> c 이런식으로 구분될 수 있게 다시 변환 시켜줬구요

분만큼 재생성해주고

그 재생성된 문자열에 원하는 문자열이 있는지 검사해서 풀면 되더라구요

 

 

func solutionP17683(_ m:String, _ musicinfos:[String]) -> String {
    var result: [(title: String, time: Int)] = []
    let m = m.replacingOccurrences(of: "C#", with: "c")
        .replacingOccurrences(of: "D#", with: "d")
        .replacingOccurrences(of: "F#", with: "f")
        .replacingOccurrences(of: "G#", with: "g")
        .replacingOccurrences(of: "A#", with: "a")
    
    for infoString in musicinfos {
        let music = infoString.components(separatedBy: ",")
        let start = music[0]
        let end = music[1]
        let title = music[2]
        let info = music[3].replacingOccurrences(of: "C#", with: "c")
            .replacingOccurrences(of: "D#", with: "d")
            .replacingOccurrences(of: "F#", with: "f")
            .replacingOccurrences(of: "G#", with: "g")
            .replacingOccurrences(of: "A#", with: "a")
            .map{String($0)}
        
        // 시간 계산
        let startTime = start.components(separatedBy: ":").map{Int($0)!}
        let startHour = startTime[0]
        let startMinute = startTime[1]
        let endTime = end.components(separatedBy: ":").map{Int($0)!}
        let endHour = endTime[0]
        let endMinute = endTime[1]
        let minute = (endHour - startHour) * 60 + endMinute - startMinute
        
        var fullInfo = ""
        for i in 0..<minute {
            let index = i % info.count
            fullInfo += info[index]
        }
        
        if fullInfo.contains(m) {
            result.append((title, minute))
        }
    }

    return result.max{$0.time < $1.time}?.title ?? "(None)"
}

 

 

점수가 엄청높더라구요,,, +10..!

반응형