개발자공부일기

프로그래머스 - k진수에서 소수 개수 구하기 본문

코딩테스트/프로그래머스

프로그래머스 - k진수에서 소수 개수 구하기

JavaCPP 2025. 1. 31. 20:31

https://school.programmers.co.kr/learn/courses/30/lessons/92335?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

문제 설명은 다음과 같다

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

  • 0P0처럼 소수 양쪽에 0이 있는 경우
  • P0처럼 소수 오른쪽에만 0이 있고 왼쪽에는 아무것도 없는 경우
  • 0P처럼 소수 왼쪽에만 0이 있고 오른쪽에는 아무것도 없는 경우
  • P처럼 소수 양쪽에 아무것도 없는 경우
  • 단, P는 각 자릿수에 0을 포함하지 않는 소수입니다.
    • 예를 들어, 101은 P가 될 수 없습니다.

예를 들어, 437674을 3진수로 바꾸면 211020101011입니다. 여기서 찾을 수 있는 조건에 맞는 소수는 왼쪽부터 순서대로 211, 2, 11이 있으며, 총 3개입니다.

 

예시를 잘 살펴보면 0을 구분자처럼 쓰고있는걸 알 수 있다.

function solution(n, k) {
    let answer = 0;
    
    n=n.toString(k); //k진법으로 바꾸기
    
    const arr = n.split("0"); //0을 기준으로 쪼개기
    
    
    return answer;
}

 

그래서 먼저 전달받은 n을 k진법으로 바꾸고 그 바꾼 숫자를 0을 구분자로 나눈 배열로 만들었다.

그리고 return값을 arr바꿔서 실행해보면

의도한대로 숫자들이 잘려서 배열이 되었다.

 

이제 배열을 forEach로 돌리며 소수인지 검사하기 위해 isPrime함수를 만들었다.

function isPrime(num) {
 
  for(let i = 2; num > i; i++) {
  if(num % i === 0) {
    return false;
   }
  }
 return num > 1; //1인경우 제외
}

function solution(n, k) {
    let answer = 0;
    
    n=n.toString(k);
    
    const arr = n.split("0");
    
    arr.forEach((num)=>{
       if(isPrime(num)) answer++;
    });
    
    return arr;
}

 

이렇게 했더니 시간초과로 실패했다. isPrime에서  2부터 자기자신까지 나눠보는 반복문때문에 그런듯 하다.

 

그래서 찾아보니까 에라토스테네스의 체 라는게 있더라

 

  • 알고리즘
    1. 2부터 구하구자 하는 모든 수 나열
    2. 2는 소수이므로 오른쪽에 2쓴다.
    3. 자신을 제외한 2의 배수 모두 지운다.
    4. 남은 수 가운데 3은 소수이므로 오른쪽에 쓴다.
    5. 자신을 제외한 3의 배수 모두 지운다.
    6. 남은 수 가운데 5은 소수이므로 오른쪽에 쓴다.
    7. 자신을 제외한 5의 배수 모두 지운다.
    8. 남은 수 가운데 7은 소수이므로 오른쪽에 쓴다.
    9. 자신을 제외한 7의 배수 모두 지운다.
    10. 위의 과정 반복하면 구하는 구간의 모든 소수가 남는다

 

  • 알고리즘 요약
    • 1보다 큰 모든 자연수는 소수의 곱으로 이루워졌다.
    • 자연수 n이 √n보다 작은 소수들로 나눠떨어지지 않으면 자연수 n은 소수이다.

근데 이 문제의 경우엔 n~m이 아니라 불특정한 정수배열이기 때문에 아래처럼 바꿔서 써봤다.

function isPrime (num) {
    if(!num || num === 1) return false;
    for (let i = 2; i <= Math.sqrt(num); i++) {
        if (num % i === 0) return false;
    }

    return num>1; //1의 경우 제외
}

function solution(n, k) {
    let answer = 0;
    
    n=n.toString(k);
    
    const arr = n.split("0");
    
    arr.forEach((num)=>{
       if(isPrime(num)) answer++; //소수면 asnwer 1씩 증가
    });
    
    return answer;
}

 

이렇게 하니 시간초과없이 통과했다.