
악.,. 알고리즘이 계속 RangeError 떠서 너무 궁금해서 테스트 해본다는게 맞았습니다..
https://lhoiktiv.tistory.com/401
Node.js)백준 1016번: 제곱 ㄴㄴ 수
https://www.acmicpc.net/problem/1016 1016번: 제곱 ㄴㄴ 수 어떤 정수 X가 1보다 큰 제곱수로 나누어 떨어지지 않을 때, 그 수를 제곱ㄴㄴ수라고 한다. 제곱수는 정수의 제곱이다. min과 max가 주어지면, min보
lhoiktiv.tistory.com
이분 코드 복붙해 갔었습니다... 왜 내껀 안됐을까를 설명해보려고 합니다.
const fs = require('fs');
const [min,max] = fs.readFileSync("./dev/stdin").toString().trim().split(' ').map(Number);
// 총 개수 구하기
let count = max - min + 1;
const primeFilter = new Array(max + 1).fill(1); //RangeError 생긴 부분
// 소수 구하기
const primeNumber = [];
for (let i = 2; i <= Math.sqrt(max); i++) {
if (primeFilter[i]) {
primeNumber.push(i);
for (let j = i ** 2; j <= max; j += i) {
if (primeFilter[j]) {
primeFilter[j] = 0;
}
}
}
}
// nono가 아닌 애들 구하기
let notNoNo = new Set();
for (let i = 0; i < primeNumber.length; i++) {
const primeDouble = primeNumber[i] * primeNumber[i];
const startPoint = Math.ceil(min / primeDouble);
for (let j = startPoint; j <= max / primeDouble; j++) {
notNoNo.add(j * primeDouble);
}
}
console.log(count - notNoNo.size);
RangeError는 허용되지 않는 범위의 값을 주려고 할 때 , 생긴다고 하더군요.
https://runebook.dev/ko/docs/javascript/global_objects/rangeerror
차이점은 max의 제곱근까지만 소수를 구하면 되는데 저는 max까지 에란토스체로 거르고 있었더군요...
이를 보완해도 시간초과가 떴다..
let count = max - min + 1;
const maxSqrt = Math.floor(Math.sqrt(max));
const primeFilter = new Array(maxSqrt + 1).fill(true);
const primeNumber = [];
for (let i = 2; i <= primeFilter.length; i++) {
if (primeFilter[i]) {
primeNumber.push(i);
for (let j = i ** 2; j <= max; j += i) {
if (primeFilter[j]) {
primeFilter[j] = false;
}
}
}
}
let notNoNo = new Set();
for (let i = 0; i < primeNumber.length; i++) {
const primeDouble = primeNumber[i] * primeNumber[i];
const startPoint = Math.ceil(min / primeDouble);
for (let j = startPoint; j <= max / primeDouble; j++) {
notNoNo.add(j * primeDouble);
}
}
console.log(count - notNoNo.size);
이떄 에란토스체에서 최종적으로 primeNumber만 구하면 되니깐 함수로 만들어서 효율적으로 하겠다.
function sieveOfEratosthenes(max) {
const isPrime = new Array(max + 1).fill(true);
isPrime[0] = isPrime[1] = false;
for (let p = 2; p * p <= max; p++) {
if (isPrime[p]) {
for (let i = p * p; i <= max; i += p) {
isPrime[i] = false;
}
}
}
const primes = [];
for (let i = 2; i <= max; i++) {
if (isPrime[i]) {
primes.push(i);
}
}
return primes;
}
let count = max - min + 1;
const maxSqrt = Math.floor(Math.sqrt(max));
const primeNumber = sieveOfEratosthenes(maxSqrt);
let notNoNo = new Set();
for (let i = 0; i < primeNumber.length; i++) {
const primeDouble = primeNumber[i] * primeNumber[i];
const startPoint = Math.ceil(min / primeDouble);
for (let j = startPoint; j <= max / primeDouble; j++) {
notNoNo.add(j * primeDouble);
}
}
console.log(count - notNoNo.size);
통과는 했지만 원글보다 더 느리다.. 혹시 set대신 반복문을 하는게 메모리적으로 더 효율적이지 않을까?
function sieveOfEratosthenes(max) {
const isPrime = new Array(max + 1).fill(true);
isPrime[0] = isPrime[1] = false;
for (let p = 2; p * p <= max; p++) {
if (isPrime[p]) {
for (let i = p * p; i <= max; i += p) {
isPrime[i] = false;
}
}
}
const primes = [];
for (let i = 2; i <= max; i++) {
if (isPrime[i]) {
primes.push(i);
}
}
return primes;
}
let count = max - min + 1;
const maxSqrt = Math.floor(Math.sqrt(max));
const primeNumber = sieveOfEratosthenes(maxSqrt);
const notNoNo = new Array(count).fill(0);
for (let i = 0; i < primeNumber.length; i++) {
const primeDouble = primeNumber[i] * primeNumber[i];
let startPoint = Math.ceil(min / primeDouble) * primeDouble;
while (startPoint <= max) {
notNoNo[startPoint - min] = 1;
startPoint += primeDouble;
}
}
const notNoNoCount = notNoNo.reduce((acc, val) => acc + val, 0);
console.log(count - notNoNoCount);

결국 메모리는 더 컸지만 빠른 코드가 되었다..
후 ...
후기)
프로그래머스에 비해서 백준이 불친절한 느낌인데, 오히려 더 깊게 생각하게 만들어서 코드 개선이 많이 되는 느낌이다.. 문제 난이도 자체는 골드랑 프로그래머스 lv1~2랑 비슷한 느낌?
수정 ) 난이도가 카카오 기출이런건 lv1이랑 프로그래머스 실버~골드 사인거 같은데, 몇몇 거품 문제가 많아서 전체적으로 골드랑 lv3이랑 비슷한 거 같습니다.
'알고리즘 문제풀이' 카테고리의 다른 글
9466 텀 프로젝트 (Node.js) (0) | 2023.11.17 |
---|---|
백준 2842 집배원 한상덕 코드 리뷰 (node.js) (0) | 2023.11.08 |
카카오 신고결과 받기 문제 - ( 프로그래머스) (0) | 2023.09.10 |
나머지가 1이 되는 수 찾기 문제 최적화(에란토스체) (0) | 2023.08.19 |
소수찾기(에라토네스 체) 프로그래머스 (0) | 2023.07.11 |