質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

6回答

10225閲覧

Python 素数の表示

nobita

総合スコア66

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/05 11:14

現在 for文 と if文程度の基礎的な文法のみで 素数を小さいほうから2000番目を表示するプログラムを考えています。
アドバイス
お願いいたします。

a = 100000000000000000 j = [] for i in range(1,a+1): if a % i == 0: j.append(i) print(j[1999])

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

まず現状何ができているか確認しましょう。
確認のために、変数aの値は手ごろなものにします。

Python

1a = 20 2j = [] 3for i in range(1,a+1): 4 5 if a % i == 0: 6 j.append(i) 7 8# print(j[1999]) 9print(j)

実行結果 Wandbox

[1, 2, 4, 5, 10, 20]

見てわかるように、現状『指定の数の約数を列挙する』コードが完成しています。

素数を求められるようにする

素数の約数は、1とその数自体ですから、リストjの長さが2であったら素数だと言えます。
判定には組み込み関数 len を利用します。

Python

1>>> lst = [1, 2, 3] 2>>> len(lst) 33 4>>> 5>>> lst = [3, 1, 4, 1, 5, 9, 2] 6>>> len(lst) 77

約数の個数が二個ちょうどであるか ⇔ 素数であるか

素数を列挙できるようにする

直前に完成した、『素数判定プログラム』を利用します。

Python

1for i in range(上限): 2 素数判定 3 4 もし素数なら: 5 リストに追加

以上で完成です。

追記: nobitaさんが完成させたプログラム

Python

1a = 0 2b = 1 3q = [] 4w = [] 5i = 0 6 7 8for aa in range(1,100): 9 j = 0 10 for i in range(1,100): 11 12 if aa % i == 0: 13 14 j += 1 15 if 2 < j: 16 print(f"{aa}は素数ではない") 17 else: 18 print(f"{aa}は素数である")

イケてない部分もありますが、しっかり動いてるのでまずは充分でしょう。

書いてみた

他の回答に対抗して、『ifとforだけ』縛りを無視して書いてみた。

Python

1import itertools 2 3 4def is_prime(num, prime_list): 5 return all(num % prime != 0 for prime in prime_list) 6 7def gen_primes(): 8 prime_list = [2] 9 10 yield 2 11 for num in itertools.count(start=3, step=2): 12 if is_prime(num, prime_list): 13 prime_list.append(num) 14 yield num 15 16 17if __name__ == '__main__': 18 gen = gen_primes() 19 20 for _ in range(1999): 21 next(gen) 22 23 print( 24 next(gen) 25 )

投稿2018/09/05 11:24

編集2018/09/05 17:21
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/05 11:39

ありがとうございます。 """ a = 20 j = [] p = [] for i in range(1,a+1): if a % i == 0: j.append(i) h = len(j) if h == 2: p.append(i) print(p) """ これであってますか・・・泣き
LouiS0616

2018/09/05 11:40

実際どんな結果になったのですか?
nobita

2018/09/05 12:01

[2,3]なんですが・・・ 20の素数のみしか求まらないですよね・・・?? 小さいほうから2000個目の素数を求めるには a = 20 の部分は 2を当てはめて・3を当てはめて・と繰り返し処理をしないとですよね?
LouiS0616

2018/09/05 12:04

> 小さいほうから2000個目の素数を求めるには > a = 20 > の部分は 2を当てはめて・3を当てはめて・と繰り返し処理をしないとですよね? そのとおりです。その気付きが大事です。 つまり、素数を判定するループの外側に、もう一重ループが必要だと言うことがわかります。 ただし、ご提示のコードはまだ『素数判定プログラム』になっていません。 まずはaの値が素数のとき、『素数です』そうでないとき『素数ではありません』と表示するプログラムをしっかり完成させましょう。
nobita

2018/09/05 12:16

""" a = 30001 b = 1 i = 0 j = 0 for i in range(1,a + 1): if a % i == 0: print(i) j += 1 if 2 < j: print("素数ではない") else: ("素数です") """
nobita

2018/09/05 12:17

こんな感じですかね??
LouiS0616

2018/09/05 12:28

次のような結果になったでしょうか。 1 19 1579 30001 素数ではない 細かなバグやスマートでない部分もありますが、おおむね正しいでしょう。 実際にaの値を変えてみて、確かに判定できているか確かめてみると良いです。 --- さて、次は外側のループを書けば良いですね。 # 1は素数でない。とりあえず上限は手ごろな値に。 for a in range(2, 100): __aが素数なら print(f'{a}は素数です') を実行する 註: 空白をアンダースコアで代替しています。
nobita

2018/09/05 12:54

外側のループで  aが素数ならprint(f"{a}は素数です") は for a in range(2,100): if a ・・・・・ ↑がよく分かりません。
nobita

2018/09/05 12:54

‘‘‘ a = 300 b = 1 i = 0 j = 0 for aa in range(2,100): aa += 1 for i in range(aa): i += 1 if aa % i == 0: print(i) j += 1 if 2 < j: print("素数ではない") else: ("素数です") ‘‘‘
nobita

2018/09/05 12:55

まだだめですが、こんな感じですか?
LouiS0616

2018/09/05 12:58

aa += 1 と i += 1 の行は不要です。 それらの値はfor文側がコントロールしてくれるので。 --- どの値が素数と判定されているか、もう少し見やすく出力してみましょう。 print(i) はコメントアウトしてしまって良いです。
nobita

2018/09/05 13:11

‘‘‘ a = 300 b = 1 q = [] w = [] i = 0 j = 0 for aa in range(1,100): for i in range(1,aa): if aa % i == 0: q.append(aa) print(q) ```
nobita

2018/09/05 13:11

バーーっと数値が表示されますが、まだまだ素数ではなさそうです
LouiS0616

2018/09/05 13:16

このコードだと素数の判定自体できてないですね。 どんどん遠ざかっているので、21:16のコードまで一旦戻って考え直してはいかがでしょう。
nobita

2018/09/05 13:26

わかりました・・・泣
nobita

2018/09/05 13:55

``` a = 300 b = 1 q = [] w = [] i = 0 j = 0 for aa in range(1,100): for i in range(1,a + 1): if a % i == 0: print(i) j += 1 if 2 < j: print("素数ではない") else: ("素数です") ```
nobita

2018/09/05 13:56

こんな感じにしました。
LouiS0616

2018/09/05 14:00 編集

だいぶそれらしくなりました。 print(i) はもう排除しても良いでしょう。 また、素数の判定結果の出力部分は次のようにしてみてください。 if 2 < j: __print(f"{a}は素数ではない") else: __print(f"{a}は素数です") どのような結果になりますか。
nobita

2018/09/05 14:13

‘‘‘ a = 300 b = 1 q = [] w = [] i = 0 j = 0 for aa in range(1,100): for i in range(1,a + 1): if a % i == 0: j += 1 if 2 < j: print(f"{a}は素数ではない") else: print(f"{a}は素数で ‘‘‘
nobita

2018/09/05 14:13

こんな感じですか??
LouiS0616

2018/09/05 14:18

流れとしては良いんじゃないでしょうか。 ただ、おそらく2以外の数を全て合成数(非素数)と判定してしまっていると思います。 実はjの値がどんどん累積されてしまっています。 j = 0 をどこに置けばいいのか考えてみましょう。
nobita

2018/09/05 14:31

””” a = 0 b = 1 q = [] w = [] i = 0 for aa in range(1,100): j = 0 for i in range(1,100): if aa % i == 0: j += 1 if 2 < j: print(f"{aa}は素数ではない") else: print(f"{aa}は素数である") ””” こんな感じですが、 結果が、複数同じ数値を判断してしまってます・・・
LouiS0616

2018/09/05 14:36 編集

『複数同じ数値』とは? 実行結果をお見せください。長いようなら最初の20行くらいでも良いです。
nobita

2018/09/05 14:39

1は素数である 2は素数である 2は素数である 3は素数である 3は素数である 4は素数である 4は素数である 4は素数ではない 5は素数である 5は素数である 6は素数である 6は素数である 6は素数ではない 6は素数ではない 7は素数である 7は素数である 8は素数である 8は素数である 8は素数ではない 8は素数ではない 9は素数である 9は素数である 9は素数ではない 10は素数である 10は素数である 10は素数ではない 11は素数である 12は素数である 12は素数である 12は素数ではない 12は素数ではない 12は素数ではない 13は素数である 14は素数である 14は素数である 14は素数ではない 15は素数である 15は素数である 15は素数ではない 16は素数である 16は素数である 16は素数ではない 16は素数ではない 17は素数である 18は素数である 18は素数である 18は素数ではない 18は素数ではない 18は素数ではない 19は素数である 20は素数である 20は素数である 20は素数ではない 20は素数ではない 21は素数である 21は素数である 21は素数ではない 22は素数である 22は素数である 23は素数である 24は素数である 24は素数である 24は素数ではない 24は素数ではない 24は素数ではない 24は素数ではない 25は素数である 25は素数である 26は素数である 26は素数である 27は素数である 27は素数である 27は素数ではない 28は素数である 28は素数である 28は素数ではない 28は素数ではない 29は素数である 30は素数である 30は素数である 30は素数ではない 30は素数ではない 30は素数ではない 31は素数である 32は素数である 32は素数である 32は素数ではない 32は素数ではない 33は素数である 33は素数である 34は素数である 34は素数である 35は素数である 35は素数である 35は素数ではない 36は素数である 36は素数である 36は素数ではない 36は素数ではない 36は素数ではない 36は素数ではない 37は素数である 38は素数である 38は素数である 39は素数である 39は素数である 40は素数である 40は素数である 40は素数ではない 40は素数ではない 40は素数ではない 41は素数である 42は素数である 42は素数である 42は素数ではない 42は素数ではない 42は素数ではない 43は素数である 44は素数である 44は素数である 44は素数ではない 45は素数である 45は素数である 45は素数ではない 45は素数ではない 46は素数である 46は素数である 47は素数である 48は素数である 48は素数である 48は素数ではない 48は素数ではない 48は素数ではない 48は素数ではない 49は素数である 49は素数である 50は素数である 50は素数である 50は素数ではない 51は素数である 51は素数である 52は素数である 52は素数である 52は素数ではない 53は素数である 54は素数である 54は素数である 54は素数ではない 54は素数ではない 54は素数ではない 55は素数である 55は素数である 56は素数である 56は素数である 56は素数ではない 56は素数ではない 56は素数ではない 57は素数である 57は素数である 58は素数である 58は素数である 59は素数である 60は素数である 60は素数である 60は素数ではない 60は素数ではない 60は素数ではない 60は素数ではない 61は素数である 62は素数である 62は素数である 63は素数である 63は素数である 63は素数ではない 63は素数ではない 64は素数である 64は素数である 64は素数ではない 64は素数ではない 65は素数である 65は素数である 66は素数である 66は素数である 66は素数ではない 66は素数ではない 67は素数である 68は素数である 68は素数である 68は素数ではない 69は素数である 69は素数である 70は素数である 70は素数である 70は素数ではない 70は素数ではない 71は素数である 72は素数である 72は素数である 72は素数ではない 72は素数ではない 72は素数ではない 72は素数ではない 72は素数ではない 73は素数である 74は素数である 74は素数である 75は素数である 75は素数である 75は素数ではない 76は素数である 76は素数である 76は素数ではない 77は素数である 77は素数である 78は素数である 78は素数である 78は素数ではない 78は素数ではない 79は素数である 80は素数である 80は素数である 80は素数ではない 80は素数ではない 80は素数ではない 81は素数である 81は素数である 81は素数ではない 82は素数である 82は素数である 83は素数である 84は素数である 84は素数である 84は素数ではない 84は素数ではない 84は素数ではない 84は素数ではない 85は素数である 85は素数である 86は素数である 86は素数である 87は素数である 87は素数である 88は素数である 88は素数である 88は素数ではない 88は素数ではない 89は素数である 90は素数である 90は素数である 90は素数ではない 90は素数ではない 90は素数ではない 90は素数ではない 91は素数である 91は素数である 92は素数である 92は素数である 92は素数ではない 93は素数である 93は素数である 94は素数である 94は素数である 95は素数である 95は素数である 96は素数である 96は素数である 96は素数ではない 96は素数ではない 96は素数ではない 96は素数ではない 97は素数である 98は素数である 98は素数である 98は素数ではない 99は素数である 99は素数である 99は素数ではない
nobita

2018/09/05 14:39

です!!!!
LouiS0616

2018/09/05 14:43

if 2 < j: __print(f"{a}は素数ではない") else: __print(f"{a}は素数である") 上記のコード片が、内側のループに含まれてしまっているようです。 for i in range(1,a + 1): の行と頭の位置を揃えてください。
nobita

2018/09/05 14:50

できました!! ありがとうございます。 これを少し編集して2000個めを表示すればいいんですね!!
LouiS0616

2018/09/05 14:59 編集

ほぼ自力で完成させられましたね。こういう経験は大事です。 > これを少し編集して2000個めを表示すればいいんですね!! いろんな方法が考えられますね。 ・ 素数をリストを放り込んでいき、2000番目にアクセス ・ 最新の素数を変数primeに代入しながら見つけた素数の数をカウントしていき、2000個目を発見したときのprimeの値を利用する いきなり2000番目なんてやってもややこしくなるだけなので、まずは20番目とか手ごろなものを試してみてください。 これなら人力でも実行結果が正しいか確認できますし。 なお、定義上1は素数に含みませんので、検証の際はご注意ください。
nobita

2018/09/05 15:00

``` a = 0 b = 1 q = [] w = [] i = 0 for aa in range(1,100000): j = 0 for i in range(1,100000): if aa % i == 0: j += 1 if 2 < j: continue else: print(f"{aa}は素数である") w.append(aa) if len(w) == 2001: break print(w[1999]) ```
nobita

2018/09/05 15:01

いや、ご丁寧に教えていただいたおかげです。 まだ初心者ですが頑張ります。 ありがとうございました。
LouiS0616

2018/09/05 15:09

一応完成ですね。 実行時間は非常に食ってしまいますが... O(n^2) ですからね。 素数の判定部分をさらに効率化する必要があります。 とりあえず j の値が2を超えた時点で内側のループを脱出するようにするだけでも、速度面はかなり改善するでしょう。
nobita

2018/09/05 22:14

ありがとうございます!!!!!! 助かりました!!!
guest

0

https://ja.m.wikipedia.org/wiki/エラトステネスの篩

普通はこういうのを使います。
for文とif文で書けますよ。


参考程度に。本当にあってるかな…

python

1ps = [2] 2 3def is_prime_countup(num, ps): 4 for p in ps: 5 if num % p == 0: 6 return False 7 return True 8 9i = 3 10while len(ps) < 2000: 11 if is_prime_countup(i, ps): 12 ps.append(i) 13 i += 1 14 15print(ps) 16print(len(ps))

気持ち高速化してみる。

python

1from math import sqrt 2ps = [2] 3 4def is_not_prime_countup(num, ps): 5 l = sqrt(num) 6 return any(num % p == 0 for p in ps if p <= l) 7 8i = 3 9while True: 10 if not is_not_prime_countup(i, ps): 11 ps.append(i) 12 if len(ps) == 5000: 13 break 14 i += 1 15 16print(ps) 17print(len(ps))

いろいろと悲しみしかなかったといっておく…

python

1import time 2from math import sqrt 3 4def timer(func): 5 def itimer(*args, **kwargs): 6 st = time.time() 7 ret = func(*args, **kwargs) 8 print(time.time() - st) 9 return ret 10 return itimer 11 12N = 10000 13 14@timer 15def f(): 16 ps = [2] 17 18 def is_prime_countup(num, ps): 19 l = sqrt(num) 20 for p in ps: 21 if num % p == 0: 22 return False 23 if p > l: 24 return True 25 return True 26 27 i = 3 28 while len(ps) < N: 29 if is_prime_countup(i, ps): 30 ps.append(i) 31 i += 1 32 33 return ps 34 35@timer 36def g(): 37 ps = [2] 38 39 def is_not_prime_countup(num, ps): 40 l = sqrt(num) 41 return any(num % p == 0 for p in ps if p <= l) 42 43 i = 3 44 while True: 45 if not is_not_prime_countup(i, ps): 46 ps.append(i) 47 if len(ps) == N: 48 break 49 i += 1 50 51 return ps 52 53ansf = f() 54ansg = g() 55assert all(i == j for i, j in zip(ansf, ansg))

投稿2018/09/05 12:22

編集2018/09/05 14:45
mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/05 22:13

ありがとうございます。
guest

0

(i)素数かどうか判定する関数を作ります。
素数ならTrue, そうでないならFalseを返すようにしましょう。

(ii)while文で条件を満たすまでループさせて答えを求めます。

python

1import math 2 3def is_prime(n): 4 if n == 1: return False 5 6 for k in range(2, int(math.sqrt(n)) + 1): 7 if n % k == 0: 8 return False 9 10 return True 11 12count = 0 13num = 1 14 15while count < 2000: 16 17 num += 1 18 if is_prime(num): 19 count += 1; 20 21print(num)

投稿2018/09/05 11:39

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

R.Shigemori

2018/09/05 12:45

かっこいいですね。 ただ、このコードにたどり着くには高度な数学が必要そう。
nobita

2018/09/05 22:13

すごいです
guest

0

Pythonなど不要。そう、シェル芸ならね!

bash

1$ seq 100000|factor|awk '$0*=!$3'|head -2000

投稿2018/09/05 19:24

hichon

総合スコア5737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/05 22:10

難しいです・・・
guest

0

参考情報

  • Pythonで素数の効率的な無限のジェネレータを実装するには?

https://code.i-harness.com/ja/q/21c096

  • Finding nth Prime using Python and Sieve of Eratosthenes

https://codereview.stackexchange.com/questions/185219/

  • Calculating the Nth prime number

https://www.codeproject.com/Articles/1228398/Calculating-the-Nth-prime-number

Finding nth Prime using Python and Sieve of Eratosthenes のページの中のコードの一つを
実際に試してみます。2000 編目でなく 20000 番目を求めてみました。

python3

1def gen_primes(): 2 D = {} 3 q = 2 # first integer to test for primality. 4 5 while True: 6 if q not in D: 7 # not marked composite, must be prime 8 yield q 9 10 # first multiple of q not already marked 11 D[q * q] = [q] 12 else: 13 for p in D[q]: 14 D.setdefault(p + q, []).append(p) 15 # no longer need D[q], free memory 16 del D[q] 17 18 q += 1 19 20primes = gen_primes() 21 22# for p in primes: 23# print(p) 24 25for _ in range(19999): 26 next(primes) 27 28print(next(primes))

実行例:
イメージ説明

i病以下で処理できています。

投稿2018/09/05 14:03

編集2018/09/06 17:07
katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/05 22:10

ありがとうございます。
guest

0

素数の計算とのことですが、2000番目を求めるということなのでそのまま演算を行うと、処理時間が膨大になってしまう可能性があります。

まずは、求め方のアルゴリズムから考えたほうが良いでしょう。

素数を求める方法として有名なのは

  • エラトステネスの篩を適用したもの
  • フェルマーの小定理を用いるもの

(こちらは素数でない数(擬素数)を素数であると判断することがありますので、今回のご質問には不適切ですが)

などがあります。
また、上記を用いずとも、素数ではない数(合成数といいます)の以下の特徴を利用すると高速に処理が行えます。

ある合成数nは、2~√nまでの範囲に1つ以上の約数を持つ

例として21という数は、2~√21(≒4.58)までの範囲である3という約数を持つため合成数であるということです。
これは、21の約数として3を見つけることは、同時に対となる数7が存在することを見つけていることになるのです。

さて、これをpythonのコードで表現すると以下のようになります。

python

1p = [] 2limit = 100 3 4for k in range(2, limit+1): 5 factor = 0 6 7 # 繰り返しの上限を対象の平方根にする 8 for div in range(2, math.floor(math.sqrt(k))+1): 9 if k % div == 0: 10 factor += 1 11 12 # 範囲内の約数が無ければ素数である 13 if factor == 0: 14 p.append(k) 15

あとはこれに2000番目の値を表示する部分を加えれば目的を満たせると思います。

投稿2018/09/05 13:40

編集2018/09/05 13:48
Simb

総合スコア118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobita

2018/09/05 22:12

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問