728x90
반응형
https://programmers.co.kr/learn/courses/30/lessons/17683?language=swift#
방금 들었던 곡과 악보를 비교하여 알맞는 노래의 제목을 반환하는 문제.
생각보다 조건들이 까다로운 구현 문제이다.
1. #이 붙은 문자열들을 변환해야한다.
2. 실제 playtime을 구할 때 모두 분으로 변환하여 차이를 구해줘야 한다.
2-1. playtime < 악보 길이
2-2. playtime > 악보 길이 : 같은 악보를 두 개 이어붙인다.
2-3. 악보를 playtime만큼 잘라서 사용한다.
3. 방금 들은 부분이 악보에 포함되는지 확인
4. 위 조건에 알맞는 곡이
4-1. 1개 이상이라면 해당 곡의 제목을 반환
4-1-1. 재생시간이 긴 순서대로 정렬 > 제목 리턴
4-2. 0개 즉 없다면 "(None)" 반환
------------
바로 코드를 보면서 가보자.
구현이기 때문에 하나하나 보는게 더 이해가 빠르다.
func solution(_ m:String, _ musicinfos:[String]) -> String {
// index접근 가능하도록 배열로 변환
let musicinfos = musicinfos.map {$0.components(separatedBy: ",")}
// # 붙은 것들 변환
let m = change(m)
// title, playtime 저장용
var res = [(String,Int)]()
for info in musicinfos {
// 실제 재생시간
let playtime = diff(info[0],info[1])
// 실제 재생음악
let music = change(info[3])
let title = info[2]
// 배열을 늘릴지 그대로 둘지
let repeatcnt = playtime / music.count
let sheet = repeatcnt == 0 ? music : String(repeating: music, count: repeatcnt + 1)
// prefix로 실제 재생시간 만큼 음악을 잘라냄
if String(sheet.prefix(playtime)).contains(m) {
res.append((title,playtime))
}
}
// 재생시간 먼저 비교 (타이틀은 따라옴)
return res.max {$0.1 < $1.1}?.0 ?? "(None)"
}
// 시간차이
func diff(_ s: String, _ e: String) -> Int {
var s = s.components(separatedBy: ":").map {Int($0)!}
var e = e.components(separatedBy: ":").map {Int($0)!}
return (e[0] * 60 + e[1]) - (s[0] * 60 + s[1])
}
// # 변환 (소문자로)
func change(_ s: String) -> String{
let s = s
return s.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")
}
"질문하기"에서 보면 E#, B#이 들어가서 문제가 안풀린다고 하지만, 그렇지 않다.
테케 27번을 가지고 말이 많은 것 같은데 아마 정렬하여 리턴하는 부분에서 잘못이 있지 않나 싶다.
max로 정렬하는 방법에 대해 다시 알 수 있었던 조금 복잡한 구현 문제였다..
끄읕
728x90
반응형