m명이 참여하는 중 내 차례에서 말할 수 t개를 구해야 하므로, 미리 t*m 개의 수까지 구해놓고 내 차례에서 말할 수를 카운트하자. 주어진 진법으로 변환한 문자열에서 몇 번째로 택할지는 for 문만 이용하면 어렵지 않게 구할 수 있다. 문제 풀이의 관건은 특정 수를 n진법으로 빠르게 변환하는 방법이다. 여태까지 파이썬 내 진수 변환 함수에 익숙하지 않아 직접 구했는데, 이번 차례에 어떤 종류의 진법 변환이든 빠르게 할 수 있도록 하자.
구체적으로 다뤄보자면 divmod를 사용하면 보다 편리하게 몫과 나머지를 그대로 대입할 수 있다. 또한 16진법 등 일반적인 digit를 사용하지 않는 진법의 경우 digits라는 딕셔너리에 {'10':'A' ...} 등으로 반환할 digit를 담아두고 사용하면 편리하다. 즉 위의 divmod에서 반환한 mod를 n진법에 알맞은 '문자열'로 변환할 때 digits.get(str(mod), str(mod))로 해두면 뒤의 str(mod)는 딕셔너리에서 다루지 않아도 되는 일반적인 케이스(0~9)이므로 디폴트 설정으로 값을 준다. 다른 식으로도 조건문을 통해 제어해도 되지만 get을 쓸 때 디폴트를 사용하는 게 보다 코드를 적을 때 간결하게 써보았다.
def get_code(n, t):
digits = {'10':'A', '11':'B', '12': 'C', '13':'D', '14':'E', '15':'F'}
result = '0'
for num in range(1, t):
code = ''
while num > 0:
num, mod = divmod(num, n)
code += digits.get(str(mod), str(mod))
result += code[::-1]
return result
def solution(n, t, m, p):
codes = get_code(n, m*t)
cnt = 0
result = ''
for i in range(p-1, len(codes), m):
result += codes[i]
cnt += 1
if cnt == t: break
return result