python

python練習問題 | 映画「博士の愛した数式」にでた素数と完全数を計算する関数を作ろう

当サイトでは広告が表示される記事があります

「素数」と「完全数」という特別な数を見つけたいと思います。

「完全数」を知ったのは、映画「博士の愛した数式」でした。

下記の記事では、ITを学びたくなる映画の紹介をまとめていますので、ぜひぜひ。

長年授業でやってきたことをまとめて、 ITパスポートの無料Note(1度落ちちゃった方向け) 基本情報技術者対策のNoteを作ってます。興味あったらどーぞ(▼・ω・▼)

素数

素数を探そう

学生への課題は下記です。

  • 2~20の中での素数をリストarrに格納しなさい。

慣れたでしょうから、これだけで組めると思います。

arr=[]
for i in range(2,21):
  flag=0
  for j in range(2,i):
    if i%j==0:
      flag=1
      break
  if flag==0:
    arr.append(i)
    print(i)

jがi(自分自身)になるでに一度でも割り切れたら素数ではないので、

jが2~i-1の間に割り切れたらループを抜けて(break)、次の数(i+1)の計算にいきます。

flagが一度1に変化すると、そのループでは0に戻ることはないので、breakなくても大丈夫です。

breakがあると、割り切れたらそれ以上計算をしないので、計算回数を節約できるってことです。

2
3
5
7
11
13
17
19

問:1~7番目の素数を二乗して合計すると666になる

学生への課題は下記です。

  • arrから、7番目までの素数を取り出し、二乗して和をとってみましょう。
sum=0
for cnt,i in enumerate(arr,1):
  sum=sum + i**2
  if cnt==7:
    break
print(sum)

リストからインデックス(添え字)で直接引き出してもOKです。

sum=0
for i in range(0,7):
  sum = sum + arr[i]**2
print(sum)

素数かを判定する関数を作ってみよう

学生への課題は下記です。

  • 関数の名前は、judge_prime_numberとします。
  • 引数はnumだけとです。
  • 返値はTrueまたはFalseです。

いよいよ、関数の定義だけの課題文になりました。

グループ開発で各関数や各クラスを分担開発するときは、関数の名前と引数・返値を決めて、中身は各人にお任せという感じになります。

※クラス(class)は、オブジェクト指向で使うプログラム用語です。


def judge_prime_number(num):
  flag=0
  for i in range(2,num):
    if num%i==0:
      flag=1
  if flag==0:
    return True
  else:
    return False

下のように呼び出すことがでます。

print(judge_prime_number(11))
True

この関数に弱点があります。

素数は、1を含まない正の整数、つまり2,3,4,5,6,・・・の中になります。

いまの関数では、引数に-1や0を入れることもできます。

print(judge_prime_number(11))
print(judge_prime_number(-1))
print(judge_prime_number(0))
True
True # 間違い
True # 間違い

想定していない値が入力された時に、計算が間違えたり、最悪プログラムがエラーで止まります。

特に、0で割る計算などは、プログラムが止まる例としてよくあります。

想定していない値が入力された時の「例外処理」もプログラムに入れるべきです。

1,0,-1,-2,・・・が入力されたら、素数ではないのでFalseを返すように改良しましょう。

Falseに、「素数でない」「想定外の値が入力された」という2つの意味になってしまいますが、とりあえず今回はこれで。

def judge_prime_number(num):
  if num <=1:
    return False
  flag=0
  for i in range(2,num):
    if num%i==0:
      flag=1
  if flag==0:
    return True
  else:
    return False
print(judge_prime_number(11))
print(judge_prime_number(-1))
print(judge_prime_number(0))
True
False
False

問:3人の年齢を探してみよう

学生へのアナウンスは下記です。

  • 3人の年齢をa,b,cとおく。
  • a,b,cは素数である。
  • b-a, c-a, c-bも素数である。
  • 以上を満たす、a,b,cを求めよう。
  • judge_prime_number()を使ってください。
print("a b c b-a c-a c-b")
for a in range(2,100):
  for b in range(2,100):
    for c in range(2,100):
      if judge_prime_number(a) and judge_prime_number(b) and judge_prime_number(c):
        if judge_prime_number(b-a) and judge_prime_number(c-a) and judge_prime_number(c-b):
          print(f"{a} {b} {c}   {b-a}   {c-a}   {c-b}")
a b c b-a c-a c-b
2 5 7   3   5   2

b-a, c-aが素数(2以上の数)ってことは、b,c > aですね。

c-bも素数ってことは、c>bですね。

よって、少しだけ計算回数を減らせます。

print("a b c b-a c-a c-b")
for a in range(2,100):
  for b in range(a+1,100):    # bはaより大きいので。
    for c in range(b+1,100):  # cはbより大きいので。
      if judge_prime_number(a) and judge_prime_number(b) and judge_prime_number(c):
        if judge_prime_number(b-a) and judge_prime_number(c-a) and judge_prime_number(c-b):
          print(f"{a} {b} {c}   {b-a}   {c-a}   {c-b}")

完全数

完全数を探そう

6や28は「完全数」です。

6=1+2+3って、6の約数のうち6(自分)以外の和と等しい。

28=1+2+4+7+14って、28の約数のうち28(自分)以外の和と等しい。

約数って割り切れる数ってことです。

この完全数を探しましょう。

  • 2~10000の中にある完全数を表示しなさい。

ちなみに1は自分以外の約数がないので、完全数ではないです。なので2から探しましょう。

for num in range(2,10000):
  sum=0
  for i in range(1,num):
    if num%i==0:
      sum += i
  if sum == num:
    print(num)
6
28
496
8128

完全数か判定する関数を作ってみよう

完全数は、2021年8月時点で51個だけ発見されているようです。

8128の次は、33550336、8589869056です。確かめてみましょう。

学生への課題は下記です。

  • 完全数であるかを判定する関数 judge_perfect_number()を作ります。
  • 引数は判定したい数
  • 返値は完全数ならTrue・違うならFalseとします。
  • その関数を使って、33550336、8589869056について調べなさい。
def judge_perfect_number(num):
  sum=0
  for i in range(1,num):
    if num%i==0:
      sum += i
  if sum == num:
    return True
  else:
    return False
num=33550336
print(f"{num} {judge_perfect_number(num)}")
num=8589869056
print(f"{num} {judge_perfect_number(num)}")
33550336 True
8589869056 True

8589869056は、20分ぐらい計算させないと無理でしたw

まとめ

映画「博士の愛した数式」

今回は「素数」と「完全数」を探し出すプログラムを作りました。

さらに関数化して、あとで楽に呼び出して活用する練習をしました。

映画「博士の愛した数式」には、他にもいろんな数が出てきます。

原作の小説にはもっと出るみたいです。黄色い線の数は、今回のレベルでプログラムできそうです。

  • 虚数
  • 友愛数
  • 双子素数
  • メルセンヌ素数
  • 完全数
  • 過剰数
  • 不足数
  • 三角数
  • ルース=アーロン・ペア

数は無限個あるし、無限に続く無理数もあります。なのに、同じ数で割ると、有限な数1になる不思議。

素数のように不規則な数の集団、有限個な数の集団、二回掛け算すると-1になる虚数。

分母の中に分数が入った数、一定のルールの数を合算する級数。

数を並べた行列・行列式・テンソル。

物の個数を数えるために生まれた数が、人間によって拡張され表現されてきました。

数だけじゃなくて、図形や立体も表現できるんですよね。しかも3次元を超えて。

そして、それでこの世の物理法則を計算できるんですよね。

とても不思議です。

そしてコンピュータの無い江戸時代や紀元前にそんな数を研究している人たちがいっぱいいるんです。

その人たちの偉業のおかげで、今の文明があるんですね。

タイトルとURLをコピーしました