[TIL] 2023.04.17 Programmers_약수의 개수와 덧셈

Today I Learned

  • Programmers 문제 풀기

 


Programmers 문제 풀기

약수의 개수와 덧셈

문제 설명

두 정수 left right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해 주세요.

 

 

입출력 예

left right result
13 17 43
24 27 52

 

입출력 예 #1

  • 다음 표는 13부터 17까지의 수들의 약수를 모두 나타낸 것입니다.
약수 약수의 개수
13 1, 13 2
14 1, 2, 7, 14 4
15 1, 3, 5, 15 4
16 1, 2, 4, 8, 16 5
17 1, 17 2
  • 따라서, 13 + 14 + 15 - 16 + 17 = 43을 return 해야 합니다.

 

입출력 예 #2

  • 다음 표는 24부터 27까지의 수들의 약수를 모두 나타낸 것입니다.
약수 약수의 개수
24 1, 2, 3, 4, 6, 8, 12, 24 8
25 1, 5, 25 3
26 1, 2, 13, 26 4
27 1, 3, 9, 27 4
  • 따라서, 24 - 25 + 26 + 27 = 52를 return 해야 합니다.

 

나의 풀이

function solution(left, right) {
    let array = [];
    for (let i = left; i <= right; i++) {
        let count = 0;
        for (let z = 0; z <= i; z++) {
            if (i % z === 0) count += 1;
        }
        array.push(count);
    }
    return array.reduce((acc, cur, index) => acc + (cur % 2 === 0 ? index + left : -(index + left)), 0);
}
  1. 이중 for문으로 각 수마다 약수의 개수를 카운트에서 array에 push 한다.
  2. array에 reduce()를 사용해서 모든 요소를 더하는데, 이때 currentValue에 삼항 연산자를 이용해서 홀수인 경우에 +하고 홀수인 경우에 -한다.
  3. currentValue를 더할 때는 index + left를 이용해서 약수의 개수 -> 수로 변환한다.

 

나의 풀이 수정

function solution(left, right) {
    let answer = 0;
    for (let i = left; i <= right; i++) {
        let count = 0;
        for (let z = 0; z <= i; z++) {
            if (i % z === 0) count += 1;
        }
        if (count % 2 === 0) answer += i;
        if (count % 2 !== 0) answer -= i;
    }
    return answer;
}

다른 사람의 풀이를 보다 보니 굳이 reduce를 사용하지 않고 for문에 안에서 바로 계산하면 될 거 같아서 풀이를 수정했다.

 

 

다른 사람의 풀이 01

function solution(left, right) {
    var answer = 0;
    for (let i = left; i <= right; i++) {
        if (Number.isInteger(Math.sqrt(i))) {
            answer -= i;
        } else {
            answer += i;
        }
    }
    return answer;
}

제곱근이 정수라면 약수의 개수가 홀수가 된다는 점을 이용한 풀이. Number.isInteger(Math.sqrt(i))를 조건문에 넣고 answer에 바로 +, -를 한다.

 

 

다른 사람의 풀이 02

function solution(left, right) {
  let answer = 0;

  for (let i = left; i <= right; i++) {
    let count = 0;
    for (let j = 1; j <= i; j++) {
      if (i % j === 0) count++;
    }
    if (count % 2) answer -= i;
    else answer += i;
  }

  return answer;
}

내가 풀었던 방법에서 reduce 메서드를 사용하는 부분을 생략한 풀이 방법이다.

 

 


회고

오늘은 프로그래머스에서 이력서를 넣었다. 프로그래머스 이력서의 특징은 깃헙 링크 분석 서비스를 제공한다는 점. 

 

사이드 프로젝트에 해당 프로젝트의 레파지토리 링크를 첨부하면 이런 식으로 코드 분석을 해주는데 다른 사이트에는 없던 기능이라 재미있었다.