우호수(Amicable Numbers)는 서로 다른 두 수가 특별한 관계를 이루는 숫자 쌍입니다. 즉, 각 숫자의 진약수(proper divisor)의 합이 상대방 숫자와 정확히 일치하는 경우를 말합니다. 대표적인 예로 220과 284가 있으며, 220의 진약수 합은 284가 되고, 284의 진약수 합은 220이 됩니다.
두 숫자가 우호수인지 확인하려면 먼저 주어진 숫자를 반복(iterate)하면서 나머지 연산자(modulus operator)를 활용해 약수의 합을 구하는 메서드를 정의합니다. 그다음, 앞서 정의한 함수를 호출하여 두 숫자가 우호수 관계인지 최종적으로 판별하는 또 다른 메서드를 만들면 됩니다.
아래에서 실제 구현 과정을 살펴보겠습니다.
예제 코드
import math
def divided_sum_val(my_val) :
res = 0
for i in range(2, int(math.sqrt(my_val)) + 1) :
if (my_val % i == 0) :
if (i == int(my_val / i)) :
res = res + i
else :
res = res + (i + int(my_val / i))
return (res + 1)
def check_amicable(x, y) :
if (divided_sum_val(x) != y) :
return False
return (divided_sum_val(y) == x)
first_num = 220
second_num = 288
print("The numbers are :")
print(first_num)
print(second_num)
if (check_amicable(first_num, second_num)) :
print ("The given numbers are amicable in nature")
else :
print ("The given numbers are not amicable in nature")실행 결과
The numbers are : 220 288 The given numbers are not amicable in nature
코드 설명
정수를 매개변수로 받는 'divided_sum_val'이라는 이름의 메서드를 정의합니다.
'for' 반복문을 사용해 값을 순회하면서 해당 숫자의 약수 여부를 검사합니다.
반복 변수(i)가 숫자를 i로 나눈 몫과 같다면, 제곱근 근처의 중복 약수이므로 i만 한 번 더합니다.
그렇지 않은 경우에는 i와 몫(int(my_val / i))을 함께 더해 약수의 합을 누적합니다.
두 개의 숫자를 인자로 받는 'check_amicable' 메서드를 추가로 정의합니다.
이 메서드는 내부에서 'divided_sum_val'을 호출하고, 계산된 값에 따라 'True' 또는 'False'를 반환합니다.
확인할 두 숫자를 정의한 뒤 콘솔에 출력합니다.
정의된 메서드에 두 숫자를 전달하여 호출합니다.
판별 결과에 따라 해당 숫자 쌍이 우호수인지 아닌지 알려주는 메시지를 콘솔에 출력합니다.
위 예제에서 사용된 220과 288은 우호수 관계가 아니므로 "not amicable"이라는 결과가 출력됩니다. 만약 220 대신 284를 사용했다면 두 숫자는 우호수로 판별되어 "amicable" 메시지가 출력될 것입니다.