티스토리 뷰

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


1. 접근 방식

  • 문자열을 더욱 쉽게 다루기 위해 C#, D#, F#, G#, A#은 c, d, f, g, a로 변환하자.

문자열에 문정 문자/문자열이 포함되어 있는지 확인하는 in 연산자를 사용하기 위해 # 붙은 음을 소문자로 바꾼다. 만약 소문자로 바꾸지 않고 그대로 in 연산자를 사용한다면, "ABC#D"에서 "ABC"를 찾을 때 문제가 발생한다. 실제 ABC#D에서는 C#이기 때문에 ABC가 존재하지 않지만, 단순 in 연산자를 사용하면 ABC가 존재한다는 결론을 내기 때문이다.

 

  • 재생 시간을 구하고, 해당 재생 시간만큼의 악보를 만들자.

먼저 노래가 총 얼만큼 재생되었는지 계산한다. 이는 노래가 (끝난 시각 - 시작 시각)으로 구할 수 있다.

이후엔 해당 노래의 음들을 통해 재생 시간만큼의 악보를 만든다. 예를 들어 "ABCD"가 6분 동안 재생되었다면 생성되는 악보는 ABCDAB이다.

 

  • 조건이 일치하는 음악이 여러 개일 때의 처리는 "<" 을 사용하자.

일치하는 음악이 여러 개라면 우선순위에 따라 최종 정답이 결정된다. 우선순위는 (1) 라디오에서 재생된 시간이 긴 음악 (2) 재생 시간이 같다면 먼저 입력된 음악이다.

in 연산자를 통해 네오가 기억하는 음익 생성된 악보에 존재하는지 확인한다. 이후엔 정답이라고 설정된 음악(answer)의 재생 시간 max_time과 현재 곡(title)의 재생 시간 time을 비교한다. 이때 비교 연산자는 < 을 사용한다. 왜냐하면 만약 max_time == time이더라도, 먼저 재생된 곡에 우선순위가 있기 때문에 기존 answer는 그대로 유지되기 때문이다.

 

 

2. 정답 코드

⚠️ 테스트 케이스 27번에서 자꾸 오류가 났는데, 문제에 누락된 E# 이라는 음이 존재하기 때문인 듯하다. 따라서 문제에서는 E#에 대한 언급이 없지만, change_note( ) 메서드에서 E#에 대한 처리를 추가하였다.

  • join 메서드: 리스트를 문자열로 반환함 Ex) '&'.join([ 'A', 'B', 'C' ]) => 'A&B&C'
def change_note(data):
    from collections import deque
    trans = {'C#': 'c', 'D#': 'd', 'F#': 'f', 'G#': 'g', 'A#': 'a', 'E#': 'e'}
    
    result = deque()
    accum = ''
    for x in data[::-1]:
        if x == '#':
            accum = '#'
        elif accum:
            result.appendleft(trans[x + accum])
            accum = ''
        else:
            result.appendleft(x)
            
    return ''.join(result)

def compute_time(start, end):
    sh, sm = map(int, start.split(':'))
    eh, em = map(int, end.split(':'))

    return (eh - sh) * 60 + (em - sm)

def get_score(time, code):
    length = len(code)
    score = ''
    for i in range(time):
        score += code[i % length]
    return score
    
def solution(m, musicinfos):
    m = change_note(m)
    
    answer = ''
    max_time = -1
    for info in musicinfos:
        s, e, title, code = info.split(',')
        code = change_note(code)        
        time = compute_time(s, e)
        score = get_score(time, code)
        
        if m in score and max_time < time:
            answer = title
            max_time = time
        
    if not answer:
        return '(None)'
    
    return answer
728x90