알고리즘/Programmers

[Swift_Programmes] 약수의 개수와 덧셈 🌟

YEN_ 2023. 11. 27. 12:02

 

프로그래머스 문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/77884

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


내가 제출한 풀이

import Foundation

func solution(_ left:Int, _ right:Int) -> Int {
    var value: Int = 0
    for i in left ... right {
        var sqrtValue = sqrt(Double(i)).truncatingRemainder(dividingBy: 1.0)
        value += sqrtValue == 0 ? -i : i
    }
    
    return value
}

풀이 과정

 

정수 left, right가 주어질 때, left는 right 보다 반드시 작다 는 조건을 가진다.

두 정수 사이 범위에서 약수가 짝수라면 + 홀수라면 -를 한 값을 반환하는 문제이다.

 

예시가 아주 친절

 

 

 

핵심

약수를 구하는 것은 1부터 주어진 값 n까지 전부 순회하며 나누어 보면 알 수 있다.

나누어 떨어진다면 그 숫자는 n의 약수이다.

 

 

하지만 숫자 크기가 최대 네자릿수인 제한 조건에서 반복문을 주구장창 돌리는 건 또 다시 시간 초과를 마주하게 될까 무서웠다.

 

약수를 구하는 방법에 대해 검색하다가 이런 것을 발견했다.

 

제곱근에 소수점이 없으면 약수의 갯수가 홀수고 있으면 짝수입니다.

 

마침 나는 며칠 전 제곱근 메서드 sqrt()를 사용하는 문제를 푼 적이 있다. 유레카ㅋㅋ

 

 

 

진짜 문제 풀이

우선 반복문을 사용해서 left, right 를 범위 연산자로 for - in을 돌린다. 그러면 left부터 right 까지의 숫자를 받아와서 반복문 안에서 사용할 수 있다.

 

left == 13
right == 17


for i in left ... right {
	print(i)
}

// 13
// 14
// 15
// 16
// 17

 

 

첫번째로는 반복문 안에서 sqrt() 메서드를 사용해서 제곱근을 구한다.

제곱근을 구할때 사용하는 매개변수는 Double이나 Float형을 사용해야 한다.

 

실제로 테스트 print 로 출력시켜본 결과

 

 

해당 테스트 케이스에서 16은 약수의 갯수가 1,2,4,8,16으로 5개이기 때문에 제곱근의 소수점이 없다.

 

Double, float 형을 1로 나누었을 때 나머지가 0이면 소수점이 없다는 것을 계산할 수 있다.

그러나 % 1 을 하면  '%' is unavailable: Use truncatingRemainder instead 라는 에러가 발생한다

Swift 3 부터는 이 방식 말고 truncatinRemainder 로 사용하도록 바뀌었다고 한다.

 

 

소수점 계산을 해서, 그 값이 0이라면(= 약수가 홀수) 정수 앞에 -를 붙이고 0이 아니라면(=약수가 짝수) 그대로 더하기 할당 연산자로 바로 계산해서 반환시켰다.

 

import Foundation

func solution(_ left:Int, _ right:Int) -> Int {
    var value: Int = 0
    for i in left ... right {
        var sqrtValue = sqrt(Double(i)).truncatingRemainder(dividingBy: 1.0)
        value += sqrtValue == 0 ? -i : i
    }
    
    return value
}