[Swift - ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] [3μ°¨] 방금그곑

2021. 5. 27. 19:34γ†πŸ§‘πŸ»‍πŸ’» iOS 개발/Swift - Algorithm - Solutions

πŸ•΅πŸ»  λ¬Έμ œ 해석


λ„€μ˜€λŠ” λΌλ””μ˜€μ—μ„œ ν˜λŸ¬λ‚˜μ˜¨ λ…Έλž˜μ˜ λ©œλ‘œλ””μ˜ 일뢀뢄을 κΈ°μ–΅ν•˜κ³  방금 κ·Έ κ³‘μ΄λΌλŠ” μ„œλΉ„μŠ€λ₯Ό μ΄μš©ν•˜μ—¬ ν•΄λ‹Ή λ…Έλž˜μ˜ 제λͺ©μ„ 찾으렀고 ν•©λ‹ˆλ‹€. μ΄λ•Œ λΌλ””μ˜€ μ±„λ„μ˜ μž¬μƒλœ λ…Έλž˜μ˜ 제λͺ©, μž¬μƒ μ‹œκ°, 전체 λ©œλ‘œλ”” 정보λ₯Ό μ΄μš©ν•˜μ—¬ 문제λ₯Ό 해결해보렀 ν•©λ‹ˆλ‹€.

μ£Όμ–΄μ§€λŠ” 정보와 좜λ ₯μ—λŠ” λͺ‡ 가지 κ·œμΉ™μ΄ μ‘΄μž¬ν•©λ‹ˆλ‹€.

  • λ„€μ˜€κ°€ κΈ°μ–΅ν•œ λ©œλ‘œλ””μ™€ 악보에 μ‚¬μš©λ˜λŠ” μŒμ€ C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12κ°œμ΄λ‹€.
  • 각 μŒμ€ 1뢄에 1κ°œμ”© μž¬μƒλœλ‹€. μŒμ•…μ€ λ°˜λ“œμ‹œ μ²˜μŒλΆ€ν„° μž¬μƒλ˜λ©° μŒμ•… 길이보닀 μž¬μƒλœ μ‹œκ°„μ΄ κΈΈ λ•ŒλŠ” μŒμ•…μ΄ λŠκΉ€ 없이 μ²˜μŒλΆ€ν„° λ°˜λ³΅ν•΄μ„œ μž¬μƒλœλ‹€. μŒμ•… 길이보닀 μž¬μƒλœ μ‹œκ°„μ΄ 짧을 λ•ŒλŠ” μ²˜μŒλΆ€ν„° μž¬μƒ μ‹œκ°„λ§ŒνΌλ§Œ μž¬μƒλœλ‹€.
  • μŒμ•…μ΄ 00:00을 λ„˜κ²¨μ„œκΉŒμ§€ μž¬μƒλ˜λŠ” 일은 μ—†λ‹€.
  • 쑰건이 μΌμΉ˜ν•˜λŠ” μŒμ•…μ΄ μ—¬λŸ¬ 개일 λ•Œμ—λŠ” λΌλ””μ˜€μ—μ„œ μž¬μƒλœ μ‹œκ°„μ΄ 제일 κΈ΄ μŒμ•… 제λͺ©μ„ λ°˜ν™˜ν•œλ‹€. μž¬μƒλœ μ‹œκ°„λ„ 같을 경우 λ¨Όμ € μž…λ ₯된 μŒμ•… 제λͺ©μ„ λ°˜ν™˜ν•œλ‹€.
  • 쑰건이 μΌμΉ˜ν•˜λŠ” μŒμ•…μ΄ 없을 λ•Œμ—λŠ” “(None)”을 λ°˜ν™˜ν•œλ‹€.
  • m은 음 1개 이상 1439개 μ΄ν•˜λ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.
  • musicinfosλŠ” 100개 μ΄ν•˜μ˜ 곑 정보λ₯Ό λ‹΄κ³  μžˆλŠ” λ°°μ—΄λ‘œ, 각각의 곑 μ •λ³΄λŠ” μŒμ•…μ΄ μ‹œμž‘ν•œ μ‹œκ°, λλ‚œ μ‹œκ°, μŒμ•… 제λͺ©, 악보 정보가 ', '둜 κ΅¬λΆ„λœ λ¬Έμžμ—΄μ΄λ‹€.
  • μŒμ•…μ˜ μ‹œμž‘ μ‹œκ°κ³Ό λλ‚œ μ‹œκ°μ€ 24μ‹œκ°„ HH:MM ν˜•μ‹μ΄λ‹€.
  • μŒμ•… 제λͺ©μ€ ', ' μ΄μ™Έμ˜ 좜λ ₯ κ°€λŠ₯ν•œ 문자둜 ν‘œν˜„λœ 길이 1 μ΄μƒ 64 μ΄ν•˜μ˜ λ¬Έμžμ—΄μ΄λ‹€.
  • 악보 μ •λ³΄λŠ” 음 1개 이상 1439개 μ΄ν•˜λ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

 

μ €λŠ” λ¨Όμ € 주어진 μŒμ•…μ˜ λ©œλ‘œλ””λ₯Ό μž¬μƒμ‹œκ°„μ— 맞게 끔 반볡 μž¬μƒν•œ λ¬Έμžμ—΄μ„ κ΅¬ν•˜κ³  κ·Έ λ¬Έμžμ—΄μ΄ λ„€μ˜€κ°€ κΈ°μ–΅ν•œ λ©œλ‘œλ”” λ¬Έμžμ—΄μ„ ν¬ν•¨ν•˜κ³  있으면 정닡을 λ¦¬ν„΄ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ ‘κ·Όν–ˆμŠ΅λ‹ˆλ‹€.

κ·Έ κ³Όμ •μ—μ„œ λͺ‡ 가지 λ¬Έμ œκ°€ μžˆμ—ˆλŠ”λ°, 그쀑에 ν•˜λ‚˜κ°€ C와 C#λ₯Ό ꡬ뢄해주어야 ν•œλ‹€λŠ” μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€. λ‹¨μˆœνžˆ contains λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ κΈ°μ–΅ν–ˆλ˜ λ©œλ‘œλ””κ°€ "ABC"이고 μž¬μƒλœ λ…Έλž˜λ“€μ΄ "ABC", "ABC#" 일 λ•Œ 두 λ…Έλž˜ λͺ¨λ‘ 맀칭이 λ˜μ–΄ μ •ν™•ν•œ 닡을 ꡬ할 수 μ—†κΈ° λ•Œλ¬Έμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

이λ₯Ό ν•΄κ²°ν•΄μ£ΌκΈ° μœ„ν•΄ C#을 μ†Œλ¬Έμž c둜 λ³€ν™˜ν•΄μ£Όμ–΄ ꡬ뢄이 λ˜λ„λ‘ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€. κ·Έ ν›„ 맀칭이 λ˜λŠ” λ…Έλž˜λ“€μ„ 배열에 λ‹΄μ•„μ„œ μž¬μƒμ‹œκ°„, μž…λ ₯ μˆœμ„œμ— 따라 정렬을 ν•΄μ€€ λ’€ 정닡을 κ΅¬ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

πŸ“¦  λ¬Έμ œ 풀이 & μ½”λ“œ


import Foundation

struct MusicInfo {
    let title: String
    let playtime: Int
    let score: String
    var playedMelody: String {
        let start = score.startIndex
        
        // μž¬μƒμ‹œκ°„μ΄ ν•΄λ‹Ήκ³‘μ˜ λ©œλ‘œλ”” 보닀 짧은 경우
        if playtime < score.count {
            return String(score[start...score.index(start, offsetBy: playtime)])
        }
        
        // 그렇지 μ•Šμ„ 경우 λ‚˜λ¨Έμ§€ 연산을 톡해 μž¬μƒμ‹œκ°„μ— 맞좰 μž¬μƒλœ λ©œλ‘œλ”” λ¬Έμžμ—΄μ„ λ°˜ν™˜
        return [String](repeating: score, count: playtime / score.count).joined()
        + String(score[start...score.index(start, offsetBy: playtime % score.count)])
    }
    
    init(_ title: String, _ playtime: Int, _ score: String) {
        self.title = title
        self.playtime = playtime
        self.score = score
    }
}

func solution(_ m:String, _ musicinfos:[String]) -> String {
    
    // 맀칭된 μŒμ•… 리슀트λ₯Ό μ €μž₯ν•  λ°°μ—΄
    var matchedMusicList: [(title: String, playtime: Int)] = []
    let formatter =  DateFormatter()
    formatter.dateFormat = "HH:mm"
    
    // DateFormatterλ₯Ό μ΄μš©ν•˜μ—¬ μž¬μƒμ‹œκ°„μ„ λΆ„ λ‹¨μœ„λ‘œ κ΅¬ν•˜λŠ” ν•¨μˆ˜
    
    func calculatePlaytime(_ start: String, _ end: String) -> Int {
        let startDate = formatter.date(from: start)!
        let endDate = formatter.date(from: end)!
        
        return Int(endDate.timeIntervalSince(startDate) / 60)
    }
    
    // μž…λ ₯된 λ©œλ‘œλ”” λ¬Έμžμ—΄μ˜ #λ…ΈνŠΈλ“€μ„ μ†Œλ¬Έμžλ‘œ λ³€ν™˜ν•˜λŠ” ν•¨μˆ˜
    
    func convertSharpToLowcase(_ score: String) -> String {
        var convertedScore = score
        let notes = [("C#","c"), ("A#","a"), ("D#","d"), ("F#","f"), ("G#","g")]
        
        for note in notes {
            convertedScore = convertedScore.replacingOccurrences(of: note.0, with: note.1)
        }
        
        return convertedScore
    }
    
    for musicinfo in musicinfos {
        let components = musicinfo.components(separatedBy: ",")
        let convertedScore =  convertSharpToLowcase(components[3])
        let music = MusicInfo(components[2], calculatePlaytime(components[0], components[1]), convertedScore)
        
        // 맀칭된 μŒμ•…μ„ λ¦¬μŠ€νŠΈμ— μ €μž₯
        if music.playedMelody.contains(convertSharpToLowcase(m)) {
            matchedMusicList.append((music.title, music.playtime))
        }
    }
    
    // 맀칭된 μŒμ•…μ΄ 없을 경우 "(None)" 리턴
    
    if matchedMusicList.isEmpty {
        return "(None)"
    }
    
    // μž¬μƒ μ‹œκ°„, μž…λ ₯μˆœμ„œμ— 맞좰 배열을 μ •λ ¬, μž¬μƒμ‹œκ°„μ΄ κΈ΄ μŒμ•…μ΄ μ•žμ— μ˜€λ„λ‘ μ •λ ¬
    
    let sorted = matchedMusicList.enumerated().sorted {
        if $0.element.playtime == $1.element.playtime {
            return $0.offset < $1.offset
        }
        return $0.element.playtime > $1.element.playtime
    }
    
    // λ°°μ—΄μ˜ 첫 번째 μ›μ†Œκ°€ μ •λ‹΅
    
    return sorted.first!.element.title
}