라떼는말이야

[프로그래머스 lv2] [3차]n진수 게임 본문

알고리즘/코딩 테스트

[프로그래머스 lv2] [3차]n진수 게임

MangBaam 2021. 8. 15. 12:38
반응형

2018 KAKAO BLIND RECRUITMENT 문제입니다.


문제 설명

튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다.

  1. 숫자를 0부터 시작해서 차례대로 말한다. 첫 번째 사람은 0, 두 번째 사람은 1, … 열 번째 사람은 9를 말한다.
  2. 10 이상의 숫자부터는 한 자리씩 끊어서 말한다. 즉 열한 번째 사람은 10의 첫 자리인 1, 열두 번째 사람은 둘째 자리인 0을 말한다.

이렇게 게임을 진행할 경우,
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 가 주어진다.

  • 2 ≦ n ≦ 16
  • 0 < t ≦ 1000
  • 2 ≦ m ≦ 100
  • 1 ≦ p  m

출력 형식

튜브가 말해야 하는 숫자 t개를 공백 없이 차례대로 나타낸 문자열. 단, 10~15는 각각 대문자 A~F로 출력한다.

입출력 예제

입출력 예제


나의 풀이

def solution(n, t, m, p):
    answer = ''
    for i in range(t*m):
        answer += change(i, n)
    answer = answer[:t*m]
    return answer[p-1::m]

def change(num, n):
    overTen = {10:'A', 11:'B', 12:'C', 13:'D', 14:'E', 15:'F'}
    if num == 0: return "0"
    answer = ''
    while num:
        num, r = divmod(num, n)
        answer = str(r) + answer if r < 10 else overTen[r] + answer
    return answer

 

change 함수

10진수 숫자 num과 진수 n이 주어지면 num을 n진법으로 바꿔 리턴하는 함수이다.

각 자리 수가 10 이상인 경우 ABCDEF로 바꿔주기 위해 overTen이라는 Dict를 사용했다.

만약 입력된 숫자가 0이라면 그대로 0을 리턴하고

나머지가 존재하는 동안 계속 나누어서 나온 나머지를 앞쪽에 붙여 나가는 방식이다.

진법 변경 방식

여기서 divmod 라는 함수가 사용되었는데, divmod는 나눗셈을 한 몫과 나머지를 한번에 반환해주는 함수이다.

q, r = divmod(10, 3) 을 하면 10을 3으로 나눈 몫은 q에, 나머지는 r에 저장되어 q에는 3, r에는 1이 저장된다.

만약 나머지가 10 이상이라면 overTen을 사용하여 알파벳으로 변경하여 붙여주고, 그렇지 않다면 그냥 숫자만 str로 변경하여 붙여주면 된다.

solution 함수

문제 이해를 위한 표

만약 3명이 게임에 참가하고, 4개의 숫자를 미리 알고 싶다면 위의 표처럼 작성될 수 있다.

solution 함수의 매개변수로 미리 구할 숫자의 개수 t와 게임에 참가하는 인원 m을 입력 받기 때문에 등장할 수 있는 수의 개수는 최소 t * m 개 이다. 

그렇기에 반복문을 t*m 번 돌리면 최소한의 숫자 개수는 만족할 수 있다.

위의 경우 3 * 4 = 12번 반복문을 돌리면 다음과 같은 숫자가 생성될 것이다.

12회 반복 후 생성되는 숫자들 (0 ~ 11)

하지만 위에서 생성된 숫자가 모두 필요한 것은 아니다. 두 자리 이상의 숫자의 경우 각 자리 수가 하나씩 세어지기 때문에 다시 한번 슬라이싱 해야한다.

즉, 진짜 필요한 개수는 t * m 개 이므로 (answer에 숫자들이 생성되어 있다면) answer[ :t*m] 으로 슬라이싱 해야한다.

answer[ :t*m]

그러면 표에서와 같이 0 ~ 10 까지 잘리게 된다.

 

마지막으로 위 숫자들 중에서 나의 숫자만 뽑아내야 한다.

  • 1번째 친구의 경우 0, 3, 6, 9
  • 2번째 친구의 경우 1, 4, 7, 1
  • 3번째 친구의 경우 2, 5, 8, 0

이 뽑아져야 한다.

p-1 부터 m 칸씩 뛰면 자신의 숫자를 추출할 수 있다.

 

테스트 결과

반응형
Comments