어떤 수를 입력받아 그 수의 약수를 모두 더한 수 sumDivisor 함수를 완성해 보세요. 예를 들어 12가 입력된다면 12의 약수는 [1, 2, 3, 4, 6, 12]가 되고, 총 합은 28이 되므로 28을 반환해 주면 됩니다.

문제 보러가기


코드 및 풀이

최초의 풀이는 다음과 같다. answer의 값이 1이므로 2부터 시작하는 반복문을 돌면서 num을 나눈 나머지가 0i의 값을 answer에 더해주고 리턴한다.

def sumDivisor(num):
    answer = 1
    for i in range(2, num + 1):
        if num % i == 0:
            answer += i
    return answer
    
print(sumDivisor(12))
# 28


다음과 같이 리스트 컴프리핸션을 통해 i 값을 모두 구한 뒤 sum()을 사용하여 더한 값을 리턴할 수도 있다.

def sumDivisor_2(num):
    return sum([i for i in range(1, num + 1) if num % i == 0])


3번째 방법은 약수의 성질을 이용한 것이다. 모든 수는 자기자신을 약수로 가지며 2로 나누어지는 것에 상관 없이 2로 나눈 값보다 작은 수들을 약수로 가지므로 다음과 같이 풀이할 수 있다.

def sumDivisor_3(num):
    return num + sum([i for i in range(1, (num // 2) + 1) if num % i == 0])


4번째 방법은 3번째와 비슷하지만 범위를 1에서부터 인자의 루트값으로 지정하여 조건에 맞는 값만 더한 후 자기자신을 더해준 값을 리턴해준다. 이렇게 하면 연산속도가 더욱 빨라진다.

def sumDivisor_4(num):
    return num + sum([i for i in range(1, (num ** .5) + 1) if num % i == 0])


풀이 별 실행시간 측정하기

각각의 함수를 100,000번 반복한 실행시간의 평균을 구했을 때 다음과 같이 시간이 걸린다. 근소한 차이지만 4번째 방식으로 풀이했을 때가 가장 시간이 적게 걸리는 것을 알 수 있다.

print(avg(e.sumDivisor_1(12)))
# 0.05220026650931686

print(avg(e.sumDivisor_2(12)))
# 0.08070019248407334

print(avg(e.sumDivisor_3(12)))
# 0.04699977580457926

print(avg(e.sumDivisor_4(12)))
# 0.04630019247997552



Julia Hwang

디발자를 꿈꾸는 웹개발자의 블로그입니다.