프론트엔드 개발자가 될거야./코딩테스트
[코딩테스트] 프로그래머스 소수찾기 자바스크립트
정니정은니
2022. 10. 25. 12:48
어렵다..
내가 푼 답은 테스트 10번부터, 효율성 테스트는 통과를 못했다..╥﹏╥
일단 이 문제에서 알아야 할 것.
1과 자신을 제외한 값으로 나누었을 때
나머지가 0인 값이 1개라도 나오면 소수가 아니다.
< 에라토스테네스의 체 >
일종의 노가다 방식이라 상당히 무식한 방법이긴 하지만, 특정 범위가 주어지고 그 범위 내의 모든 소수를 찾아야 하는 경우, 아직까지 소수들 간의 연관성(=소수를 생성할 수 있는 공식)이 나오지 않았으므로 에라토스테네스의 체보다 빠른 방법이 없다. 프로그래밍에도 수학적 지식이 필요하다는 걸 일깨워주는 좋은 예시.
에라토스테네스의 체 - 나무위키
임의의 자연수 n에 대해 그 이하의 소수를 찾는 가장 간단하고 빠른[2] 방법이다. 예를 들어 1~100까지 숫자 중 소수를 찾는다 하자. 일단 1부터 100까지 숫자를 쭉 쓴다. 1234567891011121314151617181920212223
namu.wiki
< 제곱근(sqrt) 범위 나누기 기법 >
제곱근을 기준으로
그 곱은 대칭적으로 곱이 일어나므로
제곱근 이하의 작은 값까지만 검사를 하면
나머지는 검사를 할 필요가 없다는 방법을 의미
가장 중요한 것은 < 에라토스테네스의 체 > 이 개념을 모르면 효율성 검사에서 통과하지 못한다...
📌 문제설명
1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.
소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.
(1은 소수가 아닙니다.)
제한 조건
- n은 2이상 1000000이하의 자연수입니다.
입출력 예
n | result |
10 | 4 |
5 | 3 |
입출력 예 설명
입출력 예 #1
1부터 10 사이의 소수는 [2,3,5,7] 4개가 존재하므로 4를 반환
입출력 예 #2
1부터 5 사이의 소수는 [2,3,5] 3개가 존재하므로 3를 반환
📌 문제풀이
1. 내 풀이 : 효율성 테스트 통과X
function solution(n) {
let answer = 0;
let notAnswer = 0;
for(let i=2; i<=n; i++){
for(let j=1; j<=i; j++){
if(i % j === 0) notAnswer++
}
if(notAnswer===2) {answer++}
notAnswer = 0 //초기화!!!
}
return answer
}
2. 내 풀이 : 효율성 테스트 통과X
function solution(n) {
let arr = [];
for(let i=2; i<n+1; i++){
for(let j=1; j<i+1; j++){
if(i % j === 0) arr.push(i)
}
}
let answer = [];
for (let i=0; i<n+1; i++) {
if(arr.filter(num=> num === i).length === 2){answer.push(i)}
}
return answer.length
}
3. 누군가의 풀이 : 제곱근(sqrt) 범위 나누기 기법, 효율성 테스트 통과X
// 소수인지 판별하는 함수
function isPrime(x) {
for (let i = 2; i <= Math.sqrt(x); i++) {
if (x % i === 0) return false;
}
return true;
}
function solution(n) {
// 소수의 개수를 저장할 변수
let answer = 0;
// 1은 소수가 아니므로 2부터 n까지 모든 수에 대해
for (let i = 2; i <= n; i++) {
// 소수이면 소수의 개수에 1 추가
if (isPrime(i)) answer++;
}
return answer;
}
4. 누군가의 풀이 : 에라토스테네스의 체, 효율성 테스트 통과O
function solution(n) {
// 2부터 n까지의 수로 구성된 Set
const s = new Set();
for (let i = 2; i <= n; i++) {
s.add(i);
}
// 2부터 n의 제곱근보다 작은 최대 정수까지
for (let j = 2; j < Math.sqrt(n); j++) {
// Set에 해당 수가 포함되면
if (s.has(j)) {
// 그 수를 제외하고 그 수의 배수는 모두 삭제
for (let k = j * 2; k <= n; k += j) {
s.delete(k);
}
}
}
return s.size;
}
4. 누군가의 풀이 : 에라토스테네스의 체, 효율성 테스트 통과O
function solution(n) {
// 소수 리스트 담을 배열 생성
let arr = [];
// 0과 1을 제외한 2부터 n까지 배열에 담아줍니다.
for(let i=2; i<=n; i++) {
arr[i] = i;
}
for(let i=2; i<=n; i++) {
// 인덱스 2부터 반복문 돌면서 0이면 다시 다음 반복문을 돕니다.
if(arr[i]===0) continue;
// 각 인덱스(i)의 배수들을 0으로 지정해줍니다.
for(let j=i*2; j<=n; j+=i) {
arr[j] = 0;
}
}
// filter를 이용해 0이아닌 수들의 개수를 return합니다.
return arr.filter(v => v!==0).length;
}