꾸준하고 즐겁게

Programmers Coding Test 연습 문제 - [3차] n진수 게임 본문

카테고리 없음

Programmers Coding Test 연습 문제 - [3차] n진수 게임

wj9183 2021. 6. 20. 14:11
728x90

https://programmers.co.kr/learn/courses/30/lessons/17687

 

코딩테스트 연습 - [3차] n진수 게임

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

programmers.co.kr

N진수 게임

튜브가 활동하는 코딩 동아리에서는 전통적으로 해오는 게임이 있다. 이 게임은 여러 사람이 둥글게 앉아서 숫자를 하나씩 차례대로 말하는 게임인데, 규칙은 다음과 같다.
  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):
  #게임에서 나오는 수들
  num_list = []
  #1씩 더해가면서 게임에 나오는 수들을 찾아갈 변수
  num = 0
  #최종 결과를 위한 변수
  answer = ''
  #임시용 리스트
  temp = []

  #10진법일 때.
  if n == 10:
    #무한반복문 사용한다.
    while True:
      #결과 리스트에 num을 추가한다.
      num_list.append(str(num))
      #num에 1을 더한다.
      num= num + 1
      #만약 결과 리스트에 원하는 만큼의 결과를 얻었으면
      if len(list("".join(num_list))) == t*m:
        #무한 반복문을 종료한다.
        break

  #n이 10보다 적을 때.(10진법 이내일 때.)
  elif n < 10:
    #들어가면 안되는 숫자 리스트
    wrong_num = []
    #모든 숫자에 진법을 넘는 수가 없는지 확인할 cnt 변수.
    correct_num_cnt = 0
    #들어가면 안되는 숫자 리스트에 n 이상 10미만의 숫자를 문자열로 추가.
    for limit in range(n, 9+1):
      wrong_num.append(str(limit))
    #숫자를 가져온다.
    #여기서 range 함수 안의 숫자가 문제다. 대체 뭘로 정해줘야하는가. 그래서 while문으로 바꿨다.
    
    while True:
      #숫자를 한 단위씩 불러온다.(123이면 1,2,3)
      for each_num in list(str(num)):
        #만약 있어선 안될 숫자가 포함되면
        if each_num in wrong_num:
          #포문 끝내고 다음 숫자로 넘어간다.
          break
        #만약 있어선 안될 숫자가 없다면
        else:
          #일단 변수에 1을 더한다.
          correct_num_cnt += 1
          #적합한 숫자가 원래 수의 길이만큼 있으면
          if correct_num_cnt == len(str(num)):
            #게임의 나오는 수들을 모은 리스트에 넣는다.
            num_list.append(str(num))
            
          
      #포문이 끝날 때마다 다시 쓸 변수를 초기화해준다.
      correct_num_cnt = 0
      #num은 다음 반복에 사용하기 위해서 1을 더한다.
      num = num+1
      #while문을 돌다가 원하는 만큼의 결과를 얻었으면,
      if len(list("".join(num_list))) >= t*m:
        #while문을 종료한다.
        break

  #10진법 이상일 때.
  elif n > 10:
    #숫자를 계속해서 1씩 높여준다.(와일문과 1씩 늘어나는 변수 사용)
    while True:
      #원하는 만큼의 답변을 얻으면 바깥쪽 와일문 종료.
      if len(list("".join(num_list))) == t*m:
        break
      #만약 num이 9와 같거나 작으면 그냥 리스트에 추가한다.
      if num <= 9:
        num_list.append(str(num))
      #만약 num이 10 이상이면 아래를 실행한다.(알파벳이 들어가야하는 경우)
      else:
        #원래 num은 그대로 두고 몫이라는 변수를 만들어서 쓸 것이다.
        quotient = num
        #quotient을 소인수분해한다.(와일문 안에 와일문... 불안하다)
        while True:
          #quotient과 n을 비교한다.
          #quotient이 여전히 n보다 크거나 같으면
          if quotient >= n:
            #수를 n으로 계속 나눠서 그 나머지를 따로 리스트에 담는다.
            temp.append((quotient % n))
            #그 몫을 다시 quotient에 저장한다.
            quotient = quotient // n
          #quotient이 더이상 n으로 나눠지지 않게 작아졌으면
          elif quotient < n:
            #quotient을 리스트에 담고
            temp.append(quotient)
            #리스트를 반대로 정렬한다.
            temp.reverse()
            #temp의 숫자들을 하나씩 불러와서, 9보다 크면
            for i in range(len(temp)):
              if int(temp[i]) > 9:
                #55를 더해주고 아스키코드로 바꿔준다. 10에 55를 더하면 65로, A이기 때문이다.
                temp[i] = chr(temp[i] + 55)
              else:
                #문자열로 합쳐야하므로, 문자열로 바꿔준다.
                temp[i] = str(temp[i])   
            #리스트 내용물을 한 문자열로 합쳐준후
            temp_string = "".join(temp)
            #결과에 담는다.
            num_list.append(temp_string)
            #임시용 리스트를 재사용할 수 있도록 초기화한다.
            temp = []
            #안쪽 while문을 종료한다.
            break
      #num에는 다시 1을 더해서 다음 수를 만들어준다.
      num+=1
  
  #num_list의 요소들을 모두 분해한다.
  #먼저 다 문자열로 합친다.
  num_list = "".join(num_list)
  #리스트에 한 숫자(문자)씩 나눠서 요소로 삼는다.
  num_list = list(num_list)
  print(num_list)
  
  
  
  #포문으로 필요한 부분만 결과 문자열에 더한다.
  for i in range(p-1,len(num_list), m):
    #만약 하나의 숫자가 여러 자리라 자릿수가 딱 떨어지지 않았다면 여기서 맞춘다.
    if len(answer) == t:
      break
    answer+=(num_list[i])



  return answer

풀면서 주석 작성한 부분... 더 이상 설명은 없다.

읽어서 말이 안되는 건 어쩔 수 없다.

새벽에 썼기 때문이고, 적어도 오늘은 더이상 꼴도 보기 싫기 때문에.

 

 

 

def solution(n, t, m, p):
    num_list = []
    num = 0
    answer = ''
    temp = []

    if n == 10:
        while True:
            num_list.append(str(num))
            num= num + 1
            if len(list("".join(num_list))) == t*m:
                break

    elif n < 10:
        wrong_num = []
        correct_num_cnt = 0
        for limit in range(n, 9+1):
            wrong_num.append(str(limit))

        while True:
            for each_num in list(str(num)):
                if each_num in wrong_num:
                    break
                else:
                    correct_num_cnt += 1
                    if correct_num_cnt == len(str(num)):
                        num_list.append(str(num))

            correct_num_cnt = 0
            num = num+1
            if len(list("".join(num_list))) >= t*m:
                break
            
    elif n > 10:
        while True:
            if len(list("".join(num_list))) == t*m:
                break
            if num <= 9:
                num_list.append(str(num))
            else:
                quotient = num
                while True:
                    if quotient >= n:
                        temp.append((quotient % n))
                        quotient = quotient // n
                    elif quotient < n:
                        temp.append(quotient)
                        temp.reverse()
                        for i in range(len(temp)):
                            if int(temp[i]) > 9:
                                temp[i] = chr(temp[i] + 55)
                            else:
                                temp[i] = str(temp[i])   
                        temp_string = "".join(temp)
                        num_list.append(temp_string)
                        temp = []
                        break
            num+=1
    num_list = "".join(num_list)
    num_list = list(num_list)

    for i in range(p-1,len(num_list), m):
        if len(answer) == t:
            break
        answer+=(num_list[i])



    return answer

이건 코딩테스트에다 올려서 채점한 거.

따로 돌려보면 전부 제대로 작동하긴 작동하는 것 같은데, 채점하면 몇몇 테스트에서 시간초과 뜬다.

이중 와일문 안에 포문까지 들어갔으니, 돌려놓고 점심 나가서 먹고 와도 될 수준이라 할 말은 없다.

 

한 12시간 동안 풀었다. 전날 저녁에 풀고 다음날 아침에 풀고 저녁에 풀고 새벽에 풀고 오늘 일어나서 또 풀었다.

새벽에는 정말 머리가 안돌아가는 게 뭔지 실감했다. 덧셈 조차 못하겠는 것이였다.

하루 더 주고 정확도 제대로 만점하라면 코드 줄여서 할 수 있을 것 같긴 한데, 할 게 너무 많아서 아쉽다.

 

너무 비효율적이고 멍청하다.

이래가지고 취업이 될까.

취업 안되면 예전에 생각한대로 워홀이나 갔으면 좋겠는데, 요즘 인종차별이 특히 심해서.

갔다가 어디 으슥한 골목에서 맞아죽게 생겼다.

 

728x90