알고리즘

[BOJ] 2581번 - 소수(JS)

로돌씨 2024. 5. 28. 16:15

문제

자연수 M과 N이 주어질 때 M이상 N이하의 자연수 중 소수인 것을 모두 골라 이들 소수의 합과 최솟값을 찾는 프로그램을 작성하시오.

예를 들어 M=60, N=100인 경우 60이상 100이하의 자연수 중 소수는 61, 67, 71, 73, 79, 83, 89, 97 총 8개가 있으므로, 이들 소수의 합은 620이고, 최솟값은 61이 된다.

입력

입력의 첫째 줄에 M이, 둘째 줄에 N이 주어진다.

M과 N은 10,000이하의 자연수이며, M은 N보다 작거나 같다.

출력

M이상 N이하의 자연수 중 소수인 것을 모두 찾아 첫째 줄에 그 합을, 둘째 줄에 그 중 최솟값을 출력한다. 

단, M이상 N이하의 자연수 중 소수가 없을 경우는 첫째 줄에 -1을 출력한다.

 

예제

60
100

 

출력
620
61

 

풀이

const fs = require("fs");
let input = fs.readFileSync("예제.txt").toString().trim().split("\n").map(Number);
const [M,N] = input
var arr = [];
//M과 N사이의 수를 구해 arr에 push한다.
//그리고 arr 배열을 돌며 각 수가 소수인지 판단한 후 소수만 남은 배열을 만들고 , 그 배열을 더한 값과 그 배열 중 최소 값을 구해 출력한다.

//M과 N사이의 수를 돌며 소수일 시에 arr에 push

if([M,N] == [1,1]){
    console.log(-1)
}else{
    for(let i = M ; i <= N ; i++){
        if(isPrime(i)){
            arr.push(i)
        }
    }
    if(arr.length == 0){
        console.log(-1)
    }else{
        console.log(arr.reduce((a,b) => a+b))
        console.log(Math.min(...arr))
        
        }
    }
     //소수인지 판단하는 함수를 만듦
     function isPrime(num){
        //1은 소수가 아님
        if(num === 1) return false;
        //Math.squrt(num) -> num의 제곱근을 반환함
        for(let i = 2; i <= parseInt(Math.sqrt(num)); i++){
            //인자로 받은 num 이 i로 나누어 진다면 그것은 소수가 아님
            if(num % i === 0) return false;
        }
        //다 통과했다면 num은 소수임
        return true;
}

 

우선 소수인지 판별하는 함수 isPrime을 만든다. 

1은 소수가 아니기에 num의 인자에 1이 들어온다면 false를 리턴 ,

반복문을 돌며 2부터시작해 Math.sqrt(num) 즉 , " num의 제곱근을 정수로 변환한 값 " 까지 돈다.

만약 인자가 i로 나누어 나머지가 0이된다면 그것은 소수가 아니기에 false를 리턴한다.

모두다 아니라면 그것은 소수이기 때문에 true를 리턴하여 함수를 완성한다.

 

M과 N사이의 정수를 모두 돌며 isPrime함수가 true일시에 arr배열에 push한다.

이렇게했을때에 예제는 잘 통과되었었는데 63퍼센트에서 자꾸 런타임에러가떴었다. 이유가 무언가 하니 M과 N에 1이 들어온다면 반복문의 범위에서 에러가 나는 것이었다. 그래서 처음에 M과 N이 1 이라면 -1을 출력하는 조건문을 넣어주었고 , 그다음에 arr에 소수들을 추가했을때에 arr의 길이가 0이라면 ( 소수인 요소가 없다면 ) -1을 출력시켜 주었고 그것도 아니라면 reduce를 이용해 arr을 모두 더해 출력해주고 arr의 요소중 가장 작은값도 출력을 해주니 통과 할 수 있었다!