2018 KAKAO BLIND RECRUITMENT 방금그곡 파이썬

2 분 소요

2018 KAKAO BLIND RECRUITMENT 방금그곡 파이썬 풀이

이번 문제는 레벨 2입니다.

접근방식(+오류코드)

  1. 음악이 끝나는 시간과 시작하는 시간을 빼서 총 재생 길이를 구합니다.
  2. 재생 길이에 맞춰 멜로디가 몇 번 반복할 수 있는지 // 를 이용해서 구해주고
  3. 이에 맞춰 총 노래 악보를 구합니다.
  4. 해당 악보에 m이 포함될 경우 answer로 저장해줍니다.
  5. ”#”이 포함되어 있는 음이 있기 때문에 이를 인식해주기 위해서 새로운 def를 만들어주고 멜로디 길이를 구합니다.
  6. 또한 조건이 일치하는 곡이 여러 개 일 경우, 재생 시간이 제일 긴 음악을 선택해주고, 이 마저도 같다면 먼저 입력된 음악을 반환합니다.

제 코드는 53.3/100 점짜리 코드이고, roomedia님의 티스토리에서 정답 코드를 가져왔습니다.

내 풀이(오답)

from datetime import datetime
from collections import deque

def count_length(music):
    l = len(music[3])
    for i in music[3]:
        if i == "#":
            l -= 1
        else:
            pass
    return l

def solution(m, musicinfos):
    q = deque()
    answer = {}
    for i in range(len(musicinfos)):
        musicinfos[i] = musicinfos[i].split(',')
    for i in musicinfos:
        t = datetime.strptime(str(datetime.strptime(i[1], '%H:%M') - datetime.strptime(i[0], '%H:%M')), '%H:%M:%S')
        music_length = t.hour * 60 + t.minute
        # 샵이 포함 되어 있을 경우, 해당 길이를 1 줄여서 인식하도록 함
        score_length = count_length(i)
        if score_length > music_length:
            for s in i[3]:
                if s == "#":
                    music_length += 1
            total_play = i[3][:music_length]
        else:
            total_play = i[3] * (music_length // score_length)
        if m in total_play:
            if total_play[total_play.find(m) + len(m)] == "#":
                pass
            else:
                answer[i[2]] = music_length
                q.append(i[2])
    answer = dict(sorted(answer.items(), key=lambda x: x[1], reverse=True))
    if answer == {}:
        return "(None)"
    elif len(list(answer.keys())) >= 2 and (answer[list(answer.keys())[0]] == answer[list(answer.keys())[1]]):
        if q.popleft() == list(answer.keys())[0]:
            return list(answer.keys())[0]
        else:
            return list(answer.keys())[1]
    elif len(list(answer.keys())) >= 2 and (answer[list(answer.keys())[0]] > answer[list(answer.keys())[1]]):
        return list(answer.keys())[0]


    # if list(answer.keys)
    # print("q", q[0])
    # print(answer[list(answer.keys())[0]])
    return list(answer.keys())[0]

아래는 모범코드입니다.

모범코드

import math

def solution(m, musicinfos):
    answer = None
    m = m.replace("C#", "c").replace("D#", "d").replace("F#", "f").replace("G#", "g").replace("A#", "a")
    
    for musicinfo in musicinfos:
        start, end, title, code = musicinfo.split(",")
        
        hour, minute = map(int, start.split(":"))
        start = hour * 60 + minute
        
        hour, minute = map(int, end.split(":"))
        end = hour * 60 + minute
        duration = end - start
        
        code = code.replace("C#", "c").replace("D#", "d").replace("F#", "f").replace("G#", "g").replace("A#", "a")
        code *= math.ceil(duration / len(code))
        code = code[:duration]
        
        if m not in code:
            continue
            
        if answer == None or answer[0] < duration or (answer[0] == duration and answer[1] > start):
                answer = (duration, start, title)
    
    if answer:
        return answer[-1]
    
    return "(None)"

많은 분들이 #이 들어간 음을 replace 함수를 이용해서 소문자로 치환했습니다.

for 문으로 접근 후 여러 원소가 있을 경우 그 개수에 맞게 변수명을 지정해주면 된다는 것을 완전히 이해했습니다.

마지막의 if문을 통해 일치하는 곡이 여러 개일 때의 상황을 굉장히 간결하게 표현한 것 같습니다.

알고리즘도 모든 것과 마찬가지로 꾸준한 연습과 이해를 바탕으로 실력이 향상합니다.

Just do it & Keep steady

댓글남기기