[프로그래머스] LEVEL2 방금그곡 (Python)

Loopy·2021년 7월 11일
2

프로그래머스

목록 보기
13/32
post-thumbnail

[프로그래머스] LEVEL2 방금그곡


🧐 문제 설명


😍 나의 풀이

이 문제의 핵심 아이디어는 두 가지인 것 같다.

  1. 멜로디와 악보에 음으로 #이 들어 있는 것을 어떻게 처리할 것인가?

만약 #이 없이 ABC ... 이렇게 악보가 주어진다면 그냥 문자열을 한 문자씩 읽으면 되지만 ABB#CC#... 이렇게 나온다면 B와 B#을 구분하는 것을 한 문자씩 읽어서 해결할 수 없다.

→ 그래서, chg_shop 함수를 만들어서 '#'이 들어가는 음정은 소문자로 선처리하는 방법을 선택했다.

  1. 조건이 일치하는 음악이 여러 개일 때에는 라디오에서 재생된 시간이 제일 긴 음악 제목을 반환한다. 재생된 시간도 같을 경우 먼저 입력된 음악 제목을 반환한다.

또 다른 문제는 이 조건을 어떻게 구현할 것인가? 이다. 우선, 재생 시간을 문자열에서 int로 변환해서 분 단위로 변환한다. 그리고 music 리스트의 반복문을 진행하는 동안 곡 별로 인덱스(idx)를 기록한다.

→ 조건을 만족하는 곡을 찾을 때마다 [재생시간, 인덱스(idx), 곡 제목] 형태로 저장한다.

def chg_shop(music):    # '#'을 소문자로 처리하는 함수
    music = music.replace('A#', 'a')
    music = music.replace('C#', 'c')
    music = music.replace('D#', 'd')
    music = music.replace('F#', 'f')
    music = music.replace('G#', 'g')
    
    return music

def solution(m, musicinfos):
    answer = []
    music = []
    idx = 0 
    
    music = [i.replace(':', '').split(',') for i in musicinfos]
    
    for i in music:
        time = (int(i[1][:2])-int(i[0][:2])) * 60 + (int(i[1][2:])-int(i[0][2:]))   # time 문자열을 분 단위로 변환
        
        changed = chg_shop(i[3])    # 악보에 '#' → 소문자 변환 
        
        if len(changed) >= time:    # 악보 재생 정보 처리
            melody = changed[:time]    
        else:
            melody = changed * (time // len(changed)) + changed[:time%len(changed)]
        
        m = chg_shop(m) # 기억한 멜로디에 '#' → 소문자 변환
        
        if m in melody:
            answer.append([time, idx, i[2]])
            idx += 1
            
    if len(answer) > 1:
        answer = sorted(answer, key=lambda x: (-x[0], x[1]))    # 재생 시간이 길수록, 먼저 입력된 음악(idx) 순서로 우선순위
        return answer[0][2]
    
    elif len(answer) == 1:
        return answer[0][2]
    
    else:
        return "(None)"

👏다른 사람의 풀이

대부분 비슷하게 풀이한 것 같아서 설명은 생략...

def trans(text):
    return text.replace("C#", "H").replace("D#", "I").replace("F#", "J").replace("G#", "K").replace("A#", "L")

def split(music):
    temp = music.split(',')
    start = temp[0].split(':')
    end = temp[1].split(':')
    playTime = (int(end[0]) - int(start[0])) * 60 + int(end[1]) - int(start[1])
    return ([playTime, temp[2], trans(temp[3])])

def solution(m, musicinfos):
    m = trans(m)
    answerList = []
    for music in musicinfos:
        temp = split(music)
        if m in (temp[2] * ((temp[0] // len(temp[2])) + 1))[:temp[0]]:
            answerList.append(temp)
    if not len(answerList):
        return "(None)"
    return sorted(answerList, key=lambda x: -x[0])[0][1]

🥇 Today I Learn

lambda 정렬

  • 여러 조건으로 sort()을 해야하는 경우 사용
  • -를 붙이면, 현재 정렬차순(default:오름차순)과 반대로 하게 된다.
e = [(1, 3), (0, 3), (1, 4), (1, 5), (0, 1), (2, 4)]
f = sorted(e, key = lambda x : (x[0], -x[1]))
# f = [(0, 3), (0, 1), (1, 5), (1, 4), (1, 3), (2, 4)]

→ e 튜플 리스트의 각 요소들을 첫 번째 인자(x[0])을 기준으로 우선 오름차순 정렬하고, 같을 경우 두 번째 인자(x[1])을 기준으로 내림차순 정렬한다.

profile
공부 쫌 해!!!😂

0개의 댓글