Skip to content

[Algorithm] [3차] 방금그곡 #118

@hwangJi-dev

Description

@hwangJi-dev

💬 문제

[3차] 방금그곡


💬 Idea

  1. 재생 시간을 분 단위로 계산하기
  2. 분 단위 기반으로 총 재생된 모든 음계 계산하기
    1. 이 때 #이 들어간 음계의 string을 변환하여 저장하기 위해 Array 형태를 사용했다
    2. CC#DEF → [C, C#, D, E, F] 로 변환하여 저장
  3. m과 비교하여 일치할 시 dict에 저장
    1. [재생시간: [음악제목]]

💬 풀이

func solution(m:String, musicinfos:[String]) -> String {
			var answerDict: [Int: [String]] = [:]  
  
			for musicinfo in musicinfos {
        let musicInfo = musicinfo.components(separatedBy: ",").map({ String($0) })
				// 시간 분 단위로 계산
        let playedMinute = calMinute(musicInfo[0], musicInfo[1])
				// 분 단위 기반으로 음계 계산
        let playedSyllable = calSyllable(playedMinute, convertSyllabletoArr(musicInfo[3]))
        
				// m과 비교하여 dict에 저장
        if playedSyllable.contains(convertSyllabletoArr(m)) {
            if answerDict[playedMinute] == nil {
                answerDict[playedMinute] = [musicInfo[2]]
            } else {
                answerDict[playedMinute]?.append(musicInfo[2])
            }
        }
    }
    
    if answerDict.isEmpty {
        return "(None)"
    } else {
        return answerDict.sorted(by: { $0.key > $1.key })[0].value[0]
    }
}

// 재생시간 계산 메서드
func calMinute(_ start: String, _ end: String) -> Int {
    let start = Int(start.replacingOccurrences(of: ":", with: "")) ?? 0
    let end = Int(end.replacingOccurrences(of: ":", with: "")) ?? 0
    
    if start / 100 < end / 100 {
        return (60 - (start % 100)) + ((end / 100 - start / 100 - 1) * 60) + (end % 100)
    } else {
        return (((end - start) / 100) * 60) + ((end - start) % 100)
    }
}

// C, C#을 정확하게 구분하여 표현하기 위해 음계를 Array로 변환하는 메서드
func convertSyllabletoArr(_ syllable: String) -> [String] {
    var syllableArr = Array(syllable).map({ String($0) })
    for (idx, s) in syllableArr.enumerated() {
        if s == "#" {
            syllableArr[idx - 1] += "#"
        }
    }
    return syllableArr.filter({ $0 != "#" })
}

// 총 재생된 음계 계산 메서드
func calSyllable(_ minute: Int, _ syllable: [String]) -> [String] {
    return Array(repeatElement(syllable, count: minute / syllable.count)).flatMap{ $0 } + syllable[0..<minute % syllable.count]
}

하 .. Programmers.. 배열간 contains가 안먹힌다… 그래서 재풀이… ^^..

  1. 재생 시간을 분 단위로 계산하기
  2. 분 단위 기반으로 총 재생된 모든 음계 계산하기
    1. 이 때 #이 들어간 음계의 string을 소문자로 변환하여 저장해주었다. 계산의 편의성을 위해 Array 형태 사용은 동일.
    2. CC#DEF → [C, c, D, E, F] 로 변환하여 저장
  3. m과 비교하여 일치할 시 dict에 저장
    1. 이 때 배열, 배열간 contains가 안먹히므로 배열을 모두 joined()해주어 하나의 string으로 변환한 뒤 문자열 비교를 해주었다.
func solution(m:String, musicinfos:[String]) -> String {
    var answerDict: [Int: [String]] = [:]
    
    for musicinfo in musicinfos {
        let musicInfo = musicinfo.components(separatedBy: ",").map({ String($0) })
        let playedMinute = calMinute(musicInfo[0], musicInfo[1])
        let playedSyllable = calSyllable(playedMinute, convertSyllabletoArr(musicInfo[3]))
        
        if playedSyllable.joined().contains(convertSyllabletoArr(m).joined()) {
            if answerDict[playedMinute] == nil {
                answerDict[playedMinute] = [musicInfo[2]]
            } else {
                answerDict[playedMinute]?.append(musicInfo[2])
            }
        }
    }
    
    if answerDict.isEmpty {
        return "(None)"
    } else {
        return answerDict.sorted(by: { $0.key > $1.key })[0].value[0]
    }
}

// 재생시간 계산 메서드
func calMinute(_ start: String, _ end: String) -> Int {
    let start = Int(start.replacingOccurrences(of: ":", with: "")) ?? 0
    let end = Int(end.replacingOccurrences(of: ":", with: "")) ?? 0
    
    if start / 100 < end / 100 {
        return (60 - (start % 100)) + ((end / 100 - start / 100 - 1) * 60) + (end % 100)
    } else {
        return (((end - start) / 100) * 60) + ((end - start) % 100)
    }
}

// C, C#을 정확하게 구분하여 표현하기 위해 #음계를 소문자로 변환하고 Array로 변환하는 메서드
func convertSyllabletoArr(_ syllable: String) -> [String] {
    var syllableArr = Array(syllable).map({ String($0) })
    for (idx, s) in syllableArr.enumerated() {
        if s == "#" {
            syllableArr[idx - 1] = syllableArr[idx - 1].lowercased()
        }
    }
    return syllableArr.filter({ $0 != "#" })
}

// 총 재생된 음계 계산 메서드
func calSyllable(_ minute: Int, _ syllable: [String]) -> [String] {
    return Array(repeatElement(syllable, count: minute / syllable.count)).flatMap{ $0 } + syllable[0..<minute % syllable.count]
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions