2018 KAKAO BLIND RECRUITMENT 방금그곡 파이썬
이번 문제는 레벨 2입니다.
접근방식(+오류코드)
- 음악이 끝나는 시간과 시작하는 시간을 빼서 총 재생 길이를 구합니다.
- 재생 길이에 맞춰 멜로디가 몇 번 반복할 수 있는지 // 를 이용해서 구해주고
- 이에 맞춰 총 노래 악보를 구합니다.
- 해당 악보에 m이 포함될 경우 answer로 저장해줍니다.
- ”#”이 포함되어 있는 음이 있기 때문에 이를 인식해주기 위해서 새로운 def를 만들어주고 멜로디 길이를 구합니다.
- 또한 조건이 일치하는 곡이 여러 개 일 경우, 재생 시간이 제일 긴 음악을 선택해주고, 이 마저도 같다면 먼저 입력된 음악을 반환합니다.
제 코드는 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
댓글남기기