친화수 구하기
조회수 1891회
def amicable(num):
a = 0
for i in range(3, num):
if num % i == 0:
a = a + i
return a
for j in range(1, 500):
amicable(j)
for k in range(1, 500):
amicable(k)
if amicable(j) == amicable(k) and j != k:
print(j, '의 친화수는', k)
친화수를 구하기 위해 코드를 작성해 보았습니다.
여기서 친화수란 어느 한 수의 진약수를 모두 더하면 다른 수가 되는 것을 말합니다.
EX) 220, 284 인데, 220의 진약수는 1,2,4,5,10,11,20,22,44,55,110이고, 모두 더하면 284가 됩니다. 그리고 이 284의 진약수 1,2,4,71,142를 더하면 220이 됩니다. 이런 수를 친화수라고 하는데요
제가 1부터 500사이의 (먼저 간단하게) 친화수를 구해보려고 코드를 작성해 보았는데
결과가 제대로 나오지 않습니다. 어디가 문제일까요?
-
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
3 답변
-
우선 작성하신 코드 지적질부터 해보면요.
def amicable(num): a = 0 for i in range(3, num): if num % i == 0: a = a + i return a for j in range(1, 500): amicable(j) for k in range(1, 500): amicable(k) if amicable(j) == amicable(k) and j != k: print(j, '의 친화수는', k)
여기서
if amicable(j) == amicable(k) and j != k:
amicable(j)
와amicable(k)
는 호출 표현식입니다. 전체 코드의 모양을 보면 함수 호출은 앞의 반복문에서 끝났어야 할 것 같은데요. 여기서 다시 한 번 함수를 호출하는건 뭔가... 의도와는 전혀 다르게 작성된것으로 보입니다.왜냐면 이 시점에서
j
와k
는 무조건 499이기 때문입니다.amicable(499)
는 0이므로0 == 0
이라고 작성한것과 마찬가지죠.그리고 이어서 오는
j != k
는499 != 499
이렇게 되는데, 이 부분 역시 의도와는 전혀 관계 없는 이상한 코드가 됩니다.
rst = [] def amicable(num): a = 0 for i in range(3, num): if num % i == 0: a = a + i if a != 0: rst.append(a) for i in range(1, 501): amicable(i) rst.sort() print(rst)
이런식으로 진약수의 합을 별도로 저장(여기선
rst
)해놓은 후에 다시 뭔가를 해야하지 않을까요? -
개인적으로 해봤는데 중복되는 부분들을 줄이려면 신경써야 할 것들이 많네요
약간 무식한 방법으로 구해볼테니 한번 검토해 보시고 줄일 수 있는 부분들은 한번 줄여보시게 좋을 것 같습니다.
def amicable(num): a = 0 for i in range(1, num // 2 + 1): if num % i == 0: a += i return a r = [] for i in range(500): r.append(amicable(i))
우선 약수의 합을 더하는 부분을 보면, 예시로 들어주신 것에는 1과 2도 포함되어 있었기 때문에 for문을 3부터 시작하시면 안 됩니다.
그리고 모든 수는 그 수의 절반보다 큰 수의 배수가 될 수 없으므로, 굳이 1과 target number 사이의 모든 숫자를 확인할 필요도 없습니다.
윗 분이 리스트에 저장해서 처리를 하는 것에 대해 힌트를 주셨으니 저는 조금 다른 방법을 말씀드리겠습니다.
x = amicable(y) && y = amicable(x) && x != y
를 만족하는 x와 y 값을 찾는 것이므로for i in range(500): a = amicable(i) if i == amicable(a) and i != a: print(i)
이런 방식으로 구할 수 있습니다.
직접 돌려보시고, 더 빨리 구하기 위해 할 수 있는 일이 뭐가 있을지도 한번 고민해 보세요 ㅎㅎ
-
초보일 때에는 함수와 변수이름을 한글로 지어보는 것이 도움이 될 수 있다고 봐요.
질문자의 코드에서
amicable
은 사실 친화수를 구하는 함수가 아니라,진약수의합
을 구하는 함수죠.>>> def 진약수의합(n): s = 0 for i in range(1, n): if n%i == 0: s += i return s >>> def 친화수쌍구하기(N): 친화수쌍 = [] for i in range(N+1): s = 진약수의합(i) if i == 진약수의합(s): 친화수쌍.append((i, s)) return 친화수쌍 >>> 친화수쌍구하기(500) [(0, 0), (6, 6), (28, 28), (220, 284), (284, 220), (496, 496)] >>> def 친화수쌍구하기(N): 친화수쌍 = [] for i in range(N+1): s = 진약수의합(i) if i != s and i == 진약수의합(s): 친화수쌍.append((i, s)) return 친화수쌍 >>> 친화수쌍구하기(500) [(220, 284), (284, 220)]
댓글 입력