라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 ‘방금그곡’ 서비스를 이용하곤 한다. 방금그곡에서는 TV, 라디오 등에서 나온 음악에 관해 제목 등의 정보를 제공하는 서비스이다.
네오는 자신이 기억한 멜로디를 가지고 방금그곡을 이용해 음악을 찾는다. 그런데 라디오 방송에서는 한 음악을 반복해서 재생할 때도 있어서 네오가 기억하고 있는 멜로디는 음악 끝부분과 처음 부분이 이어서 재생된 멜로디일 수도 있다. 반대로, 한 음악을 중간에 끊을 경우 원본 음악에는 네오가 기억한 멜로디가 들어있다 해도 그 곡이 네오가 들은 곡이 아닐 수도 있다. 그렇기 때문에 네오는 기억한 멜로디를 재생 시간과 제공된 악보를 직접 보면서 비교하려고 한다. 다음과 같은 가정을 할 때 네오가 찾으려는 음악의 제목을 구하여라.
(None)
을 반환한다.입력으로 네오가 기억한 멜로디를 담은 문자열 m
과 방송된 곡의 정보를 담고 있는 배열 musicinfos
가 주어진다.
m
은 음 1
개 이상 1439
개 이하로 구성되어 있다.musicinfos
는 100개 이하의 곡 정보를 담고 있는 배열로, 각각의 곡 정보는 음악이 시작한 시각, 끝난 시각, 음악 제목, 악보 정보가 ’,
‘로 구분된 문자열이다.
HH:MM
형식이다.,
’ 이외의 출력 가능한 문자로 표현된 길이 1
이상 64
이하의 문자열이다.1
개 이상 1439
개 이하로 구성되어 있다.조건과 일치하는 음악 제목을 출력한다.
m | musicinfos | answer |
---|---|---|
ABCDEFG | [12:00,12:14,HELLO,CDEFGAB, 13:00,13:05,WORLD,ABCDEF] | HELLO |
CC#BCC#BCC#BCC#B | [03:00,03:30,FOO,CC#B, 04:00,04:08,BAR,CC#BCC#BCC#B] | FOO |
ABC | [12:00,12:14,HELLO,C#DEFGAB, 13:00,13:05,WORLD,ABCDEF] | WORLD |
첫 번째 예시에서 HELLO는 길이가 7분이지만 12:00부터 12:14까지 재생되었으므로 실제로 CDEFGABCDEFGAB로 재생되었고, 이 중에 기억한 멜로디인 ABCDEFG가 들어있다. 세 번째 예시에서 HELLO는 C#DEFGABC#DEFGAB로, WORLD는 ABCDE로 재생되었다. HELLO 안에 있는 ABC#은 기억한 멜로디인 ABC와 일치하지 않고, WORLD 안에 있는 ABC가 기억한 멜로디와 일치한다.
def solution(m, musicinfos):
answer = list() # name, playtime, index
tmp = list()
for i in range(len(m)):
if m[i] == '#':
tmp.append(tmp.pop().lower())
else:
tmp.append(m[i])
m = "".join(tmp)
for idx, music in enumerate(musicinfos):
start, end, name, rhythm = music.split(',')
s_hour, s_minute = map(int, start.split(':'))
e_hour, e_minute = map(int, end.split(':'))
play_time = abs(e_hour - s_hour)*60 + e_minute - s_minute
if play_time < 0:
play_time = 24 * 60 - s_hour * 60 + 60 - s_minute
result = list()
i = 0
cnt = 0
while cnt < play_time:
cur = rhythm[i:i + 1]
if cur != '#':
cnt += 1
result.append(cur)
else:
result.append(result.pop().lower())
i += 1
if i == len(rhythm):
i = 0
result = "".join(result)
if m in result:
answer.append((idx, name, play_time))
if len(answer) == 0:
return "(None)"
else:
answer.sort(key=lambda x: (-x[2], x[0]))
return answer[0][1]
세 차례의 코딩 테스트와 두 차례의 면접이라는 기나긴 블라인드 공채를 무사히 통과해 카카오에 입사한 무지는 파일 저장소 서버 관리를 맡게 되었다.
저장소 서버에는 프로그램의 과거 버전을 모두 담고 있어, 이름 순으로 정렬된 파일 목록은 보기가 불편했다. 파일을 이름 순으로 정렬하면 나중에 만들어진 ver-10.zip이 ver-9.zip보다 먼저 표시되기 때문이다.
버전 번호 외에도 숫자가 포함된 파일 목록은 여러 면에서 관리하기 불편했다. 예컨대 파일 목록이 [img12.png, img10.png, img2.png, img1.png]일 경우, 일반적인 정렬은 [img1.png, img10.png, img12.png, img2.png] 순이 되지만, 숫자 순으로 정렬된 [img1.png, img2.png, img10.png, img12.png”] 순이 훨씬 자연스럽다.
무지는 단순한 문자 코드 순이 아닌, 파일명에 포함된 숫자를 반영한 정렬 기능을 저장소 관리 프로그램에 구현하기로 했다.
소스 파일 저장소에 저장된 파일명은 100 글자 이내로, 영문 대소문자, 숫자, 공백(” ), 마침표(.), 빼기 부호(-“)만으로 이루어져 있다. 파일명은 영문자로 시작하며, 숫자를 하나 이상 포함하고 있다.
파일명은 크게 HEAD, NUMBER, TAIL의 세 부분으로 구성된다.
0
부터 99999
사이의 숫자로, 00000
이나 0101
등도 가능하다.파일명 | HEAD | NUMBER | TAIL |
---|---|---|---|
foo9.txt |
foo |
9 |
.txt |
foo010bar020.zip |
foo |
010 |
bar020.zip |
F-15 |
F- |
15 |
(빈 문자열) |
파일명을 세 부분으로 나눈 후, 다음 기준에 따라 파일명을 정렬한다.
MUZI
와 muzi
, MuZi
는 정렬 시에 같은 순서로 취급된다.MUZI01.zip
과 muzi1.png
가 입력으로 들어오면, 정렬 후에도 입력 시 주어진 두 파일의 순서가 바뀌어서는 안 된다.무지를 도와 파일명 정렬 프로그램을 구현하라.
입력으로 배열 files
가 주어진다.
files
는 1000 개 이하의 파일명을 포함하는 문자열 배열이다.muzi1.txt
, MUZI1.txt
, muzi001.txt
, muzi1.TXT
는 함께 입력으로 주어질 수 있다.)위 기준에 따라 정렬된 배열을 출력한다.
입력: [img12.png, img10.png, img02.png, img1.png, IMG01.GIF, img2.JPG] 출력: [img1.png, IMG01.GIF, img02.png, img2.JPG, img10.png, img12.png]
입력: [F-5 Freedom Fighter, B-50 Superfortress, A-10 Thunderbolt II, F-14 Tomcat] 출력: [A-10 Thunderbolt II, B-50 Superfortress, F-5 Freedom Fighter, F-14 Tomcat]
def sort_func(v):
h, n, t, i = v
h = h.lower()
n = int(n)
return (h, n, i)
def solution(files):
tmp = list()
for idx, v in enumerate(files):
hIndex = 0
nIndex = ''
tIndex = ''
for i in range(len(v)):
if v[i].isdecimal() and not nIndex:
nIndex = i
elif nIndex and not tIndex and not v[i].isdecimal():
tIndex = i
if not tIndex:
tIndex = len(v)
head = v[:nIndex]
number = v[nIndex:tIndex]
tail = v[tIndex:len(v)]
tmp.append((head, number, tail, idx))
tmp.sort(key=sort_func)
answer = list()
for v in tmp:
h, n, t, i = v
answer.append(h+n+t)
return answer
function isNumber(v){
const n = new Set(['1','2','3','4','5','6','7','8','9','0'])
if (n.has(v)) return true
return false
}
function solution(files) {
const tmp = []
for (let i=0; i<files.length; i++){
const file = files[i]
let nIndex = ''
let tIndex = ''
for (let j=0; j<file.length; j++){
if (!nIndex && isNumber(file[j])) nIndex = j
else if (nIndex && !tIndex && !isNumber(file[j])) tIndex = j
}
if (!tIndex) tIndex = file.length
const head = file.slice(0,nIndex)
const number = file.slice(nIndex, tIndex)
const tail = file.slice(tIndex, file.length)
tmp.push({file, head, number: Number(number), tail, index : i})
}
tmp.sort((a,b) => {
const ha = a.head.toLowerCase()
const hb = b.head.toLowerCase()
if (ha > hb) return 1
if (ha < hb) return -1
return a.number === b.number ? a.index - b.index : a.number - b.number
})
return tmp.map(v => v.file)
}
튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다.
이렇게 게임을 진행할 경우,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, …
순으로 숫자를 말하면 된다.
한편 코딩 동아리 일원들은 컴퓨터를 다루는 사람답게 이진수로 이 게임을 진행하기도 하는데, 이 경우에는
0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, …
순으로 숫자를 말하면 된다.
이진수로 진행하는 게임에 익숙해져 질려가던 사람들은 좀 더 난이도를 높이기 위해 이진법에서 십육진법까지 모든 진법으로 게임을 진행해보기로 했다. 숫자 게임이 익숙하지 않은 튜브는 게임에 져서 벌칙을 받는 굴욕을 피하기 위해, 자신이 말해야 하는 숫자를 스마트폰에 미리 출력해주는 프로그램을 만들려고 한다. 튜브의 프로그램을 구현하라.
진법 n
, 미리 구할 숫자의 갯수 t
, 게임에 참가하는 인원 m
, 튜브의 순서 p
가 주어진다.
n
≦ 16t
≦ 1000m
≦ 100p
≦ m
튜브가 말해야 하는 숫자 t
개를 공백 없이 차례대로 나타낸 문자열. 단, 10
~15
는 각각 대문자 A
~F
로 출력한다.
n | t | m | p | result |
---|---|---|---|---|
2 | 4 | 2 | 1 | 0111 |
16 | 16 | 2 | 1 | 02468ACE11111111 |
16 | 16 | 2 | 2 | 13579BDF01234567 |
def solution(n, t, m, p):
answer = ''
d = {10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F'}
order = 1
cur = 0
while len(answer) < t:
stack = list()
if cur == 0:
stack.append(0)
x = cur
while x > 0:
stack.append(x % n)
x //= n
while stack:
tmp = stack.pop()
if order == p:
if tmp in d:
answer += d[tmp]
else:
answer += str(tmp)
if len(answer) == t:
break
order += 1
if order > m:
order = 1
cur += 1
return answer