본문 바로가기
프론트엔드로 가는 길/프로그래머스

59. k진수에서 소수 개수 구하기 - 2022 KAKAO BLIND RECRUITMENT

by woody-j 2023. 9. 14.

https://school.programmers.co.kr/learn/courses/30/lessons/92335?itm_content=course14743https://school.programmers.co.kr/learn/courses/30/lessons/12918?itm_content=course14743#
[ 문제 설명 ]

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

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개입니다.
(211, 2, 11을 k진법으로 보았을 때가 아닌, 10진법으로 보았을 때 소수여야 한다는 점에 주의합니다.)
211은 P0 형태에서 찾을 수 있으며, 2는 0P0에서, 11은 0P에서 찾을 수 있습니다.
정수 n과 k가 매개변수로 주어집니다. 
n을 k진수로 바꿨을 때,
변환된 수 안에서 찾을 수 있는 위 조건에 맞는 소수의 개수를 return 하도록 solution 함수를 완성해 주세요.

[ 문제 풀이 ]

 

[첫번째] -> 문제 생김

 

이것은 소수 판별이 아니라 짝수,홀수 판별이라 할 수 있다

function solution(n, k) {
  //1. n->k진수로 변환후 0을 기준을 숫자 단위 나누기
  //2.1. 원소 중에 빈 배열있으면 삭제하고 문자열 숫자로변환
  const divisionArr = n
    .toString(k)
    .split("0")
    .filter((n) => n !== "")
    .map((n) => Number(n));
  //3. 나눈 배열 원소 중에 소수 분류
  return divisionArr.filter((n, i) => {
    if (n <= 1) {
      return false;
    } else if (n % i === 0) {
      if (n !== 2) {
        return false;
      }
    }
    return n > 1;
  }).length;
}

 

[두번째] -> 문제 생김

1. 소수 판별 로직

i0일 때부터 시작하기 때문에 error 발생 , 1부터 시작해야함

2. filter 함수 내부

for 루프 내에서 return true가 바로 실행되어 for 루프가 한 번만 반복하고 종료됨

else 를 사용하면 안됨.. 멍청아

 

function solution(n, k) {
  //1. n->k진수로 변환후 0을 기준을 숫자 단위 나누기
  //2.1. 원소 중에 빈 배열있으면 삭제하고 문자열 숫자로변환
  const divisionArr = n
    .toString(k)
    .split("0")
    .filter((n) => n !== "")
    .map((n) => Number(n));

  //3. 나눈 배열 원소 중에 소수 분류
  const result = divisionArr.filter((n) => {
    if (n <= 1) {
      return false;
    } 
     // 이 부분 수정
    else {
      for (let i = 0; i < n; i++) {
        if (n % i === 0) {
          return false;
        }
        return true;
      }
      //----- 하단 처럼
       //for (let i = 2; i * i <= num; i++) {
       // if (num % i === 0) {
           // return false;
        //}
    //}
    return true;
    }
  });
  return result.length;
}

 

[문제 해결]

1. n->k 진수로 변환

2. 0을 기준으로 숫자를 나눈다.

3. 빈 배열이 있으면 제거

4. 문자열을 숫자로 변환

5. 나눈 배열 원소를 소수를 분류

제곱근을 사용한 이유 :

복잡도가 있어서 효율적이게 하기 위함

6. 배열 길이 구하기

function solution(n, k) {
  //1. n->k진수로 변환후 0을 기준을 숫자 단위 나누기
  //2.1. 원소 중에 빈 배열있으면 삭제하고 문자열 숫자로변환
  const divisionArr = n
    .toString(k)
    .split("0")
    .filter((n) => n !== "")
    .map((n) => Number(n));

  //3. 나눈 배열 원소 중에 소수 분류
  const result = divisionArr.filter((n) => {
  // 1은 소수가 아니다.
  if (n === 1) return false;
  // 2부터 N제곱근까지의 수로 N을 나눴을 때
  for (let i = 2; i <= Math.sqrt(n); i++) {
    // 나누어 떨어지는 경우가 한 번이라도 있으면 N은 소수가 아니다.
    if (n % i === 0) return false;
  }
  // 모두 나누어 떨어지지 않으면 N은 소수이다.
  return true;
  });
  return result.length;
}

다른 풀이 방법

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

function solution(n, k) {
  let answer = 0;
  // n을 k진수로 변환
 const converted = n.toString(k);

  // 0을 기준으로 나누어 소수를 찾음
  const numbers = converted.split("0");
  
  for (const num of numbers) {
    if (num !== "" && isPrime(parseInt(num))) {
      answer++;
    }
  }

  return answer;
}

// 예시 테스트 케이스
console.log(solution(437674, 3)); // 출력: 3
console.log(solution(110011, 10)); // 출력: 2
  for (const num of numbers) {
    if (num !== "" && isPrime(parseInt(num))) {
      answer++;
    }
  }

내 풀이의 경우 ""원소를 포함하고 있는 원소를 filter하고 소수를 분류했다.

하지만 이 풀이의 경우에는 사전 작업 없이 바로 배열에서 해당 소수가 있으면 카운트를 수행했다.

좋군.

Object.prototype.toString()

10진수를 다른 수로 변환 & 다른 수를 10진수로 변환

 

10진수를 다른 진수로 변환하기 위해서는 toString()을,

다른 진수를 10진수로 변환하기 위해서는 parseInt()를 쓴다.

 

let intNum = 3; 
console.log(intNum.toString(2)); //11

let intNum = "11";
let parsing = parseInt(intNum, 2);
console.log(parsing);   //3

 

Math.sqrt

Math 객체의 함수로, 제곱값과 루트값을 구할 수 있다.

Math.sqrt(4);		// 2
Math.sqrt(16);		// 4

 

 

참고 블로그 :https://jae04099.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%A7%84%EC%88%98%EB%B3%80%ED%99%98-toString-parseInt

'프론트엔드로 가는 길 > 프로그래머스' 카테고리의 다른 글

61. 여행경로  (0) 2023.09.17
60. H-Index  (0) 2023.09.17
58. 체육복  (0) 2023.09.14
57. 문자열 다루기 기본  (0) 2023.09.12
56. 피보나치 수  (0) 2023.09.11