본문 바로가기

코딩테스트

[프로그래머스] 약수의 합 - JS

정수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성해주세요.

 

 

첫번째 풀이 :

function solution(n) {
    var answer = 0;
    const arr = Array.from({length:n}, (v,i) => i + 1)
    const divisor = []
    
    arr.forEach(v => {
        if(n%v == 0){
            divisor.push(v)
        }
    })

    answer = divisor.reduce((a,b) => a + b)
    return answer
}

이렇게 문제를 풀었을 경우, 16번 케이스에서 런타임에러가 난다. 

 

 

두번째 풀이 : 

function solution(n) {
    var answer = 0;
    const arr = Array.from({length:n}, (v,i) => i + 1)
    
    answer = arr.reduce((a,b) => {
        if(n%b == 0) return a + b
        else return a + 0
        
    })

    return answer
}

혹시나 하는 마음에 for문이 실행되는 것을 한번으로 줄였는데, 

역시나 이건 그렇게 큰 영향을 미치지 않는 듯 했다. 

그래도 코드는 깔끔해졌다. 

이쯤되서 생각해보게 되는 것은,

이 문제를 O(n)으로 풀지않고 O(1) 방식으로 풀 수 있는 방법이 있는것일까? 

 

세번째 풀이 : (드디어 해결) 

function solution(n) {
    if(n == 0) return 0
    var answer = 0;
    const arr = Array.from({length:n}, (v,i) => i + 1)
    const divisor = []
    
    answer = arr.reduce((a,b) => {
        if(n%b == 0) return a + b
        else return a + 0
    })

    return answer
}

문제는 0이었다. 

0을 입력했을 때 런타임에러가 나는 것이었는데, 

나는 런타임에러를 잘못이해하고 단순히 시간초과라고 생각했던 것 같다. 
런타임에러는 다양한 상황에서 나오게 되는데, 이 블로그를 참고했다. (https://jaimemin.tistory.com/1522)

 

 

내가 짠 코드를 가지고 0을 입력한 후, replit에서 풀어보면 다음과 같은 에러메시지가 나온다. 

런타임 에러

Array.from 메서드에서 초기 배열을 생성할 때, 0개의 길이를 가진 배열을 생성하려고 했던 것이다. 그러면 당연히 빈 배열이 나올 것이고, 빈 배열으로 reduce 메서드를 돌리려고 했으니 에러가 났던 것. 

 

 

Array.from으로 연속된 수 생성하기 

 

돌이켜 생각해보니, 나는 Array.from 메서드를 제대로 이해하고 사용했던 것이 아닌 것 같다. 공식문서를 읽어보니 이렇게 설명이 되어있다. 

// Generate a sequence of numbers
// Since the array is initialized with `undefined` on each position,
// the value of `v` below will be `undefined`
Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]

Array.from에서 화살표 함수를 사용하면 연속된 수를 생성할 수 있다.

첫번째 인자에는 생성할 배열의 갯수를 적는다. 그럼 undefined의 배열이 갯수만큼 생성된다. 

두번째 인자에는 각각의 undefined로 채워져있는 각각의 포지션에 넣어줄 요소를 지정해준다. 

 

 


다른 사람의 풀이 : 

function solution(num) {
    let sum = 0;
    for (let i = 1; i <= num; i++) {
        if (num % i === 0) sum += i
    }
    return sum
}

=> 나는 굳이 1-n 의 수가 들어있는 배열을 만들어줬는데, 그럴 필요는 없었던 것 같다. 

=> 그냥 배열을 돌면서 인덱스를 활용하면 되는 것이었다..

=> 가끔 간단한게 눈에 안보인다.