🔴 문제
정수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성해주세요.
제한사항 : n은 0 이상 3000 이하인 정수입니다.
(문제: 링크)
🔵 풀이 1 : for...in 구문 활용
1. 초기 풀이
n의 약수는 1부터 n까지의 자연수 중,
n을 나눴을 때 나머지가 0인 자연수라는 개념으로 접근했다.
func solution(_ n:Int) -> Int {
var sum = 0
for i in 1...n where n % i == 0 {
sum += i
}
return sum
}
2. 오류 발생 및 해결
▶ 오류
그런데 위 코드를 실행하면 16번 테스트에서 막히는데,
n=0일 때 for i in 1...0 where n % i == 0 이 되면서 런타임 오류가 발생하기 때문이다.
▶ 해결
n=0일 때 0이 반환되도록 하기 위해 if문을 추가할 수 있다.
func solution(_ n:Int) -> Int {
var sum = 0
if n == 0 {
return 0
} else {
for i in 1...n where n % i == 0 {
sum += i
}
return sum
}
}
3. 코드 보완; squareRoot() 활용
위 코드는 1부터 n까지 모든 수를 하나하나 비교해야 한다.
하지만 약수는 짝으로 발생한다는 개념을 활용하면 n의 절반만 비교해도 된다.
ex) 18의 약수 : 1, 2, 3, 9, 18 (짝: 1-18 / 2-9 / 3)
* 제곱근은 자기 자신과 짝꿍!
따라서, 먼저 n의 제곱근을 구하고,
1부터 n의 제곱근까지 for...in 루프에 돌리면서
약수 i와 그 짝꿍 n/i를 sum에 더해주면 된다.
func solution(_ n: Int) -> Int {
guard n > 0 else {
return 0
}
var sum = 0
let sqrtN = Int(Double(n).squareRoot())
for i in 1...sqrtN where n % i == 0 {
sum += i
if i != n / i {
sum += n / i
}
}
return sum
}
🔵 풀이 2 : filter, reduce 활용
Ternary conditional operator(?:)와 reduce로 풀까 고민하다가 포기했는데,
filter와 reduce로 이 문제를 해결한 사람들이 있었다!!
다음은 그 코드다.
func solution(_ n:Int) -> Int {
guard n != 0 else {
return 0
}
return Array(1...n).filter{n % $0 == 0}.reduce(0, +)
}
Ternary conditional operator로 푸는 걸 포기했던 이유가 코드를 한 줄로 만들 수 없기 때문이었는데,
filter를 활용하니, 한줄로 코딩이 가능하다.
<관련 개념 정리한 글> - Ternary conditional operator (링크) - 고차함수 filter, reduce (링크) |
'Swift > Code Kata (알고리즘)' 카테고리의 다른 글
[Swift|코드카타] (프로그래머스) 입문 #16. x만큼 간격이 있는 n개의 숫자 - map 함수 (1) | 2024.02.09 |
---|---|
[Swift|코드카타] (프로그래머스) 입문 #15. 나머지가 1이 되는 수 찾기 (1) | 2024.02.09 |
[Swift|코드카타] (프로그래머스) 입문 #13. 자릿수 더하기 - swift에 제곱 연산자(^) 없음 -> pow(_:_:) 활용 (0) | 2024.02.08 |
[Swift|코드카타] (프로그래머스) 입문 #12. 평균 구하기 (0) | 2024.02.07 |
[Swift|코드카타] (프로그래머스) 입문 #11. 짝수와 홀수 - String 따옴표 '' or "" (0) | 2024.02.07 |