Posts 방금그곡 [Python]
Post
Cancel

방금그곡 [Python]

URL https://programmers.co.kr/learn/courses/30/lessons/17683

문제 설명

  • 라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 ‘방금그곡’ 서비스를 이용하곤 한다. 방금그곡에서는 TV, 라디오 등에서 나온 음악에 관해 제목 등의 정보를 제공하는 서비스이다.
  • 네오는 자신이 기억한 멜로디를 가지고 방금그곡을 이용해 음악을 찾는다. 그런데 라디오 방송에서는 한 음악을 반복해서 재생할 때도 있어서 네오가 기억하고 있는 멜로디는 음악 끝부분과 처음 부분이 이어서 재생된 멜로디일 수도 있다. 반대로, 한 음악을 중간에 끊을 경우 원본 음악에는 네오가 기억한 멜로디가 들어있다 해도 그 곡이 네오가 들은 곡이 아닐 수도 있다. 그렇기 때문에 네오는 기억한 멜로디를 재생 시간과 제공된 악보를 직접 보면서 비교하려고 한다. 다음과 같은 가정을 할 때 네오가 찾으려는 음악의 제목을 구하여라.
    • 방금그곡 서비스에서는 음악 제목, 재생이 시작되고 끝난 시각, 악보를 제공한다.
    • 네오가 기억한 멜로디와 악보에 사용되는 음은 C, C#, D, D#, E, F, F#, G, G#, A, A#, B 12개이다.
    • 각 음은 1분에 1개씩 재생된다. 음악은 반드시 처음부터 재생되며 음악 길이보다 재생된 시간이 길 때는 음악이 끊김 없이 처음부터 반복해서 재생된다. 음악 길이보다 재생된 시간이 짧을 때는 처음부터 재생 시간만큼만 재생된다.
    • 음악이 00:00를 넘겨서까지 재생되는 일은 없다.
    • 조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.
    • 조건이 일치하는 음악이 없을 때에는 “(None)”을 반환한다.

입력 형식

  • 입력으로 네오가 기억한 멜로디를 담은 문자열 m과 방송된 곡의 정보를 담고 있는 배열 musicinfos가 주어진다.
    • m은 음 1개 이상 1439개 이하로 구성되어 있다.
    • musicinfos는 100개 이하의 곡 정보를 담고 있는 배열로, 각각의 곡 정보는 음악이 시작한 시각, 끝난 시각, 음악 제목, 악보 정보가 ‘,’로 구분된 문자열이다.
    • 음악의 시작 시각과 끝난 시각은 24시간 HH:MM 형식이다.
    • 음악 제목은 ‘,’ 이외의 출력 가능한 문자로 표현된 길이 1 이상 64 이하의 문자열이다.
    • 악보 정보는 음 1개 이상 1439개 이하로 구성되어 있다.

문제 풀이

  • change_pound_key : 악보중에 A와 A#은 in으로 표현할시 둘다 같게 되어버린다. 그래서 #이 붙은것은 모두 소문자로 변경하는 함수를 작성
  • calc_time : 노래가 재생된 시간(분)을 계산하는 함수로 끝나는 시간에서 시작하는 시간을 뺀것이다.
  • solution
    • 주어진 m은 change_pound_key를 사용하여 #이 있는 문자는 소문자로 변경
    • musicinfos에서 각 music들의 info를 for문과 split을 사용하여 music를의 정보를 전처리함
    • calc_time을 사용하여 음악 재생시간을 구함
    • music이 재생시간 보다 짧으면 재생시간까지, 재생시간 보다 길면 divmod를 사용하여 몫, 나머지를 이용해 전체 재생된 노래(repeat_song)를 구한다
    • repeat_song에 m이 있으면 result에 저장한다. (노래재생순서, 재생시간, 노래제목)
      • 똑같은 결과가 있으면 재생시간이 제일 긴것, 재생시간까지 같다면 더 먼저 나온것으로 sort를 함
    • result의 최상위 노래를 리턴, 만약 result에 아무것도 없다면 (None)를 리턴함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import datetime

def change_pound_key(music):
    music = music.replace('C#', 'c')
    music = music.replace('D#', 'd')
    music = music.replace('F#', 'f')
    music = music.replace('G#', 'g')
    music = music.replace('A#', 'a') 
    music = music.replace('E#', 'e') 
    return music
    
def calc_time(info):
    end_info = list(map(int, info[1].split(':')))
    start_info = list(map(int, info[0].split(':')))
    end_time = datetime.timedelta(minutes = end_info[1], hours = end_info[0])
    start_time = datetime.timedelta(minutes = start_info[1], hours = start_info[0])
    repeat_times = end_time - start_time
    repeat_times = repeat_times / 60
    return repeat_times.seconds
    
def solution(m, musicinfos):
    result = []
    m = change_pound_key(m)
    
    for idx ,i in enumerate(musicinfos):
        
        info = i.split(',')
        repeat_times = calc_time(info)
        music = change_pound_key(info[3])

        if len(music) >= repeat_times:
            repeat_song = music[:repeat_times]

        else : 
            q, r = divmod(repeat_times,len(music))
            repeat_song = music * q + music[:r]

        if m in repeat_song:
            result.append((idx, repeat_times, info[2]))
            
    if len(result) == 0:
        return "(None)"
        
    else:
        result = sorted(result, key = lambda x: (-x[1], x[0]))
        return result[0][2]
1
2
3
m = "ABCDEFG"
musicinfos = ["12:00,12:14,HELLO,CDEFGAB", "13:00,13:05,WORLD,ABCDEF"]
solution(m, musicinfos)
1
'HELLO'
1
2
3
m = "CC#BCC#BCC#BCC#B"
musicinfos = ["03:00,03:30,FOO,CC#B", "04:00,04:08,BAR,CC#BCC#BCC#B"]
solution(m, musicinfos)
1
'FOO'
1
2
3
m = "ABC"
musicinfos = ["12:00,12:14,HELLO,C#DEFGAB", "13:00,13:05,WORLD,ABCDEF"]
solution(m, musicinfos)
1
'WORLD'
This post is licensed under CC BY 4.0 by the author.