프로그래머스 Lv.2 : k진수에서 소수 개수 구하기 (T?)

나이든별 / Oldstar·2022년 5월 6일
0

Algo-log

목록 보기
3/13

프로그래머스 Lv.2 : k진수에서 소수 개수 구하기 (2022 카카오 블라인드 채용 기출문제)

양의 정수 n이 주어집니다. 이 숫자를 k진수로 바꿨을 때, 변환된 수 안에 아래 조건에 맞는 소수(Prime number)가 몇 개인지 알아보려 합니다.

0P0처럼 소수 양쪽에 0이 있는 경우
P0처럼 소수 오른쪽에만 0이 있고 왼쪽에는 아무것도 없는 경우
0P처럼 소수 왼쪽에만 0이 있고 오른쪽에는 아무것도 없는 경우
P처럼 소수 양쪽에 아무것도 없는 경우
단, P는 각 자릿수에 0을 포함하지 않는 소수입니다.
예를 들어, 101은 P가 될 수 없습니다.
예를 들어, 437674을 3진수로 바꾸면 211020101011입니다. 여기서 찾을 수 있는 조건에 맞는 소수는 왼쪽부터 순서대로 211, 2, 11이 있으며, 총 3개입니다. (211, 2, 11을 k진법으로 보았을 때가 아닌, 10진법으로 보았을 때 소수여야 한다는 점에 주의합니다.) 211은 P0 형태에서 찾을 수 있으며, 2는 0P0에서, 11은 0P에서 찾을 수 있습니다.

정수 n과 k가 매개변수로 주어집니다. n을 k진수로 바꿨을 때, 변환된 수 안에서 찾을 수 있는 위 조건에 맞는 소수의 개수를 return 하도록 solution 함수를 완성해 주세요.


제한 범위

1 ≤ n ≤ 1,000,000
3 ≤ k ≤ 10


처음 내 생각

  • 딱 생각이 안 날 땐, 주석화를 먼저 시킨 다음 무엇을 정의할지부터 생각을 해 보자.
  • 내가 생각했던 정의해야 하는 함수는, 진수 변환 함수와 소수 판별 함수.
  • 진수 변환을 어떻게 하느냐에 대해서 감을 잘 못 잡았던 것 같다. 단지 자릿수를 올려 가면서 나머지를 더하면 된다고 생각했다..
  • 소수 판별 함수의 경우, 제곱근 직전까지의 범위까지 나눠주면 판별할 수 있다고 생각했다.

충분한 자료검색

  • 뭘 정의해야 하는지는 감을 잘 잡았다.
  • 진수 변환을 할 때는, 집어넣어 준 n도 계속 나눠 줘야 한다. 그 나머지가 자릿수가 되는 거고.
  • 링크를 참조해서 작성한 진수 변환 함수는 다음과 같다.
def jinsu(n, k):
    result = ""
    while n > 0:
        n, mod = divmod(n, k)
        result += str(mod)

    return result[::-1]
  • divmod를 굳이 쓰지는 않아도 될 것 같다. mod = n % k; n = n // k로 해도 될 듯?
  • 다음으로, 소수 판별 함수는 제곱근까지는! 넣어서 나눠 봐야 한다.
def isPrime(n):
    if n in range(0, 2):
        return False
    elif n == 2:
        return True

    for i in range(2, int(sqrt(n))+1):
        if n % i == 0:
            return False

    return True

자 이제 답안을 작성해보자

  • 원하는 소수의 조건은, 소수이면서도 0에 둘러싸여 있거나 한 쪽, 또는 양 쪽에 수가 없을 경우. 중간에 0이 들어 있어서는 안 된다.
  • jinsu로 변환한 데이터는 String으로 반환된다.
  • 이럴 때 0을 없애려면? split()을 이용해주면 될 것이다.
  • 하지만 빈 문자열은 int로 변환할 수 없다는 것도 유념해야 한다.
from math import sqrt

def solution(n, k):

    def jinsu(n, k):
        result = ""
        while n > 0:
            n, mod = divmod(n, k)
            result += str(mod)

        return result[::-1]

    def isPrime(n):
        if n in range(0, 2):
            return False
        elif n == 2:
            return True

        for i in range(2, int(sqrt(n))+1):
            if n % i == 0:
                return False

        return True

    rawdata = jinsu(n, k)
    datas = rawdata.split("0")
    numbers = [x for x in datas if x != "" and isPrime(int(x))]

    return len(numbers)

느낀 점

  • 파이썬으로 알고리즘을 풀기로 한 이상, 좀 더 파이썬의 이모저모를 이용해보자.
  • 문자열이나 리스트를 뒤집을 때는 [::-1]을 활용할 수 있다.
  • math.sqrt()divmod 등을 유용하게 사용했다.
  • T? 라고 쓴 이유는, 검색해서 찾아본 것도 있기 때문. 하지만, 카카오 코딩테스트는 검색을 허용하니만큼, 실전적 입장에선 성공한 게 맞지 않을까? 하는 자문..
profile
함께 나아가고자 하는 사람

0개의 댓글