😈 약수의 개수와 덧셈
📗 문제 설명
두 정수 left
와 right
가 매개변수로 주어집니다. left
부터 right
까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주세요.
👀 제한사항
- 1 ≤
left
≤right
≤ 1,000
📃 입출력 예
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 해야 합니다.
💎나의 풀이
나는 배열을 통해 문제를 해결할 것이다.
우선 left ~ right의 배열을 만들어주자
const solution = (left, right) => Array.from({ length: (right - left) + 1 }, (_, i) => i+left)
// 입출력 예 #1
[13,14,15,16,17]
// 입출력 예 #2
[24,25,26,27]
Array.from을 통해 배열을 만들어주고 left ~ right 의 정수로 잡아주었다.
이 배열의 value는 index+left 즉 left ~ right 값이 된다.
문제의 요구사항을 위해선 지금 만들어진 배열의 약수의 개수가 필요하다.
그렇기 때문에 만들어진 이 배열 안의 1 ~ 첫 번째로 만들어진 배열의 value (즉 left ~ right)까지의
숫자를 만들어준 뒤에
약수만 필터링해 줄 생각이다. 우선 1 ~ left~right까지의 숫자들로 2차원 배열을 만들자.
const solution = (left, right) => Array.from({ length: (right - left) + 1 }, (_, i) =>
Array.from({ length: left+i }, (_, j) => j + 1))
[ // 입출력 예 #1
[1,2,3,4,5,6,7,8,9,10,11,12,13],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]]
[ // 입출력 예 #2
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]]
이전에 value의 값이 되었던 left+i 는 2차원 배열의 length로 잡아주고
그 값은 마찬가지로 2차원 배열의 index를 더하여 값을 추가했다.
우선적으로 약수의 개수가 홀수인지 짝수인지 필터링을 해주어야 한다.
const solution = (left, right) => Array.from({ length: (right - left) + 1 }, (_, i) =>
Array.from({ length: left+i }, (_, j) => j + 1).filter((v) => (left+i) % v === 0))
[ // 입출력 예 #1
[1,13],
[1,2,7,14],
[1,3,5,15],
[1,2,4,8,16],
[1,17]]
[ // 입출력 예 #2
[1,2,3,4,6,8,12,24],
[1,5,25],
[1,2,13,26],
[1,3,9,27]]
입출력 예 설명에서 본 놈들이 잘 찍힌다.
이 이후가 문제다. 약수까지 만들었지만 이 친구들을 덧셈해줘야 한다.
우선 이대로 한 줄로 작성하기엔 무리가 있다.
위에 필터링한 부분과 2차원 배열을 만드는 부분으로 1차원 배열 안에서 함수를 작성해주어야 될 것 같다.
const solution = (left, right) => Array.from({ length: (right - left) + 1 }, (_, i) => {
const num = left + i;
const divisorCount = Array.from({ length: num }, (_, j) => j + 1)
.filter((v) => num % v === 0)
.length;
return divisorCount % 2 === 0 ? num : -num;
})
// 입출력 예 #1
[13,14,15,-16,17]
// 입출력 예 #2
[24,-25,26,27]
left+i 는 아까도 얘기했듯이 left ~ right의 배열 안의 값이다.
이 배열을 지속적으로 순회하여 값을 찾아주어야 되기 때문에 계속해서 쓰이기 때문에 변수로 만들어주었다.
divisorCount는 아까 우리가 만든 2차원 배열의 약수의 개수다.
조건을 주어 연산시켜주자.
음 아주 잘 나온다. 이제 배열을 합쳐주면 될 것 같다.
const solution = (left, right) => Array.from({ length: (right - left) + 1 }, (_, i) => {
const num = left + i;
const divisorCount = Array.from({ length: num }, (_, j) => j + 1)
.filter((v) => num % v === 0)
.length;
return divisorCount % 2 === 0 ? num : -num;
}).reduce((acc, cur) => acc + cur, 0);
// 입출력 예 #1
43
// 입출력 예 #2
52
우리가 원하는 값이 잘 나온다.
다른 분들이 한 걸 보자.
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;
}
거의 모든 분이 제곱근을 사용했다.
Math.sqrt(5) = 2.23606797749979 // 제곱근( x2 = a -> x가 제곱근)이 정수면 ( 양의정수, 0 , 음의정수) 약수의 개수가 홀수라고 한다.
수포자의 한계다.
제곱근이 정수면 약수의 개수는 홀수다 메--모
수학박사님들 잘 배워 갑니다.
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스 😈] JavaScript 크기가 작은 부분 문자열 (0) | 2023.11.24 |
---|---|
[프로그래머스 😈] JavaScript 피보나치 수 (0) | 2023.11.24 |
[프로그래머스 😈] JavaScript 이상한 문자 만들기 (1) | 2023.11.21 |
[프로그래머스 😈] JavaScript K번째수 (0) | 2023.11.21 |
[프로그래머스 😈] JavaScript 수박수박수박수박수박수? (1) | 2023.10.30 |