明日6月28日は6も28も完全数の日。
Manimを使って「完全数をチェックする方法」の動画を作成しました。約数を全部求めないで、素因数分解を使って約数の和を求める方法を紹介しています。
動画「完全数をチェックする方法」
動画「メルセンヌ素数と完全数」
完全数を語るうえで欠かせないのがメルセンヌ素数との関係です。メルセンヌ素数から必ず完全数を作れることを説明しています。
動画「完全数をチェックする方法」のManimのソースコード
%%manim -qm -v WARNING Perfect
mT = Text(" ")
class Perfect(Scene):
def construct(self):
def mTitle(txt): # title text
global mT
self.remove(mT)
mT = Text(txt, color = YELLOW).to_edge(UP)
self.add(mT)
def Tex(txtl, fs=50):
return MathTex(*txtl, font_size=fs)
def tLine(txt, fs=36):
return Text(txt, font_size=fs)
def Transf(s, d, dir=ORIGIN):
md = d.move_to(s.get_center()+dir)
self.play(Transform(s, md))
self.wait(3)
if True:
mTitle("完全数とは")
mL = VGroup(tLine("自分を除く約数の総和が自分に等しい数", 42),
tLine("例えば6と28は完全数"),
tLine("6 = 1+2+3"),
tLine("28 = 1+2+4+7+14"),
tLine("では496はどうでしょう?"),
tLine("これを確認する方法を紹介します"),
).arrange(DOWN)
self.play(Write(mL[:1])); self.wait(3)
self.play(Write(mL[1:4])); self.wait(3)
self.play(Write(mL[4:])); self.wait(3)
self.clear()
#--------------------------
mTitle("完全数をチェックする方法")
mL = VGroup(tLine("以下のステップで行います", 42),
tLine("1. 素因数分解を行う"),
tLine("2. 各素因数のべき乗をリスト"),
tLine(" 例 2の2乗なら->(1, 2, 4)"),
tLine("3. 各素因数のべき乗から約数の和を求める"),
tLine("約数を求めなくても和を計算できます"),
).arrange(DOWN)
for ml in mL:
self.play(Write(ml)); self.wait(3)
self.clear()
if True:
#--------------------------
mTitle("約数を求める")
mL1 = VGroup(tLine("12の素因数分解"), Tex(["2^2", r"\cdot 3", "= 12"], 60)).arrange(DOWN, buff=2).move_to(UP)
self.play(Write(mL1))
self.wait(3)
Transf(mL1[0], tLine("各素因数のべき乗をリスト"))
Transf(mL1[1][0], Tex([r"\begin{pmatrix} 2^0 \\ 2^1 \\ 2^2 \end{pmatrix}"], 50), LEFT*2)
Transf(mL1[1][1], Tex([r"\times \begin{pmatrix} 3^0 \\ 3^1 \end{pmatrix} "], 50), LEFT)
Transf(mL1[1][0], Tex([r"\begin{pmatrix} 1 \\ 2 \\ 4 \end{pmatrix}"], 50))
Transf(mL1[1][1], Tex([r"\times \begin{pmatrix} 1 \\ 3 \end{pmatrix} "], 50))
Transf(mL1[0], tLine("すべての組合せの積を求めます"))
Transf(mL1[1][2], Tex([r"= \begin{pmatrix} 1 \\ 2 \\ 4 \\ 3 \\ 6 \\ 12 \end{pmatrix}"], 50))
Transf(mL1[0], tLine("すべての約数が求まりました"))
#--------------------------
mTitle("ここから約数の和を求めます")
Transf(mL1[0], tLine("べき乗の和を求める"))
Transf(mL1[1][0], Tex([r"7"], 70))
Transf(mL1[1][1], Tex([r"\times \: \: 4"], 70))
Transf(mL1[1][2], Tex([r"= \: \: 28"], 70))
Transf(mL1[0], tLine("掛けると約数の和と等しくなります"))
Transf(mL1[0], tLine("約数の和は各素因数のべき乗の和の積\nで求まることが分かりました"))
self.clear()
#--------------------------
mTitle("496の約数の和を求めます")
mL1 = VGroup(tLine("496の素因数分解"), Tex(["2^4", r"\cdot 31", "= 496"], 60)).arrange(DOWN, buff=2).move_to(UP)
self.play(Write(mL1))
self.wait(3)
self.remove(mL1[1][2]) # remove 496
Transf(mL1[0], tLine("各素因数のべき乗をリスト"))
Transf(mL1[1][0], Tex([r"\begin{pmatrix} 2^0 \\ 2^1 \\ 2^2 \\ 2^3 \\ 2^4 \end{pmatrix}"], 50), LEFT*2)
Transf(mL1[1][1], Tex([r"\times \begin{pmatrix} 31^0 \\ 31^1 \end{pmatrix} "], 50), LEFT)
Transf(mL1[1][0], Tex([r"\begin{pmatrix} 1 \\ 2 \\ 4 \\ 8 \\ 16 \end{pmatrix}"], 50))
Transf(mL1[1][1], Tex([r"\times \begin{pmatrix} 1 \\ 31 \end{pmatrix} "], 50))
Transf(mL1[0], tLine("べき乗の和を求める"))
Transf(mL1[1][0], Tex([r"31"], 70))
Transf(mL1[1][1], Tex([r"\times \: \: 32"], 70))
Transf(mL1[0], tLine("掛けて約数の和を求めます"))
Transf(mL1[1][2], Tex([r"= \: \: 992"], 70))
self.play(Write(Tex([r"\: \: 992-496 = 496"], 70).move_to(DOWN)) )
Transf(mL1[0], tLine("496を引いて自分自身になります\n従って496は完全数です"))
self.wait(5)
(開発環境:Google Colab)