完全数と友愛数

NHKのドラマ「この声をきみに」を見た。
とある数学者が朗読と出会い、その魅力にとりつかれるドラマだ。
そのドラマを見てて、親和数(友愛数ともいう)が出てきた。
親和数とは、異なる 2 つの自然数の組で、自分自身を除いた約数の和が、互いに他方と等しくなるような数のこと。

ドラマでは、友人に親和数(100485, 124155)入りの手袋を渡すのだが、プログラムによって求めたとのこと。

それと似たもので、完全数というのもある。
完全数は、自分自身を除く正の約数の和が、自分自身に等しくなる自然数のこと。

僕もそれらを求めるコードが書きたくなったので、以下に書いた。
ただ、並列計算とかしてないので、すごく遅い。
ドラマでは上記の親和数を求めるのに「一晩かかった」と言ってた。
僕のは、さすがにそこまでではなかったものの、2時間はかかった。

# -*- coding: utf-8 -*-

#This prg gets perfect number and ambicable numbers.

import numpy as np

#以下で任意の自然数を入力。上記の親和数を求めるために、130000と入力したら2時間かかった。
nnn=int(input("Input the max number: "))  

def func01(a,b):
    dd = a//b
    ee = a%b
    ff = [(i+1) if ee[i]==0 else 0 for i,e in enumerate(list(dd)) ]
    g = np.sum(ff)    
    return g    
###########################################################
print("-----------------------")
## perfect number
ls01=list()
for N in range(1,nnn+1):    
    a = np.array([N for _ in range(N-1)])    
    b = np.array([i+1 for i in range(N-1)])
    g=func01(a,b)    
    if g==N:
        print("perfect number:",N)
        ls01bb.append(g)
    ls01.append(g)
###########################################################
print("-----------------------")
## amicable numbers
ls02=list()
for i,e in enumerate(ls01):
    try:
        if i+1==ls01[int(e)-1] and i+1<int(e):
            ls02.append((i+1,int(e)))
            print("ambicable numbers:",i+1,int(e))
    except:
        pass