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

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

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

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

Q&A

解決済

4回答

2739閲覧

Python で素数判定プログラムを作る

nr5tm

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/09/30 09:47

前提・実現したいこと

素数判定プログラムを作る

Python で素数判定プログラムを以下のように作りました。

発生している問題・エラーメッセージ

9や21,49は素数でないのにもかかわらず、True と表示されてしまいます。
いろいろ調べてみましたが、どこに問題があるのかわかりません。
改善すべきところを教えてください。

また、この is_prime 関数を用いて、n 以下の素数を数えるプログラムはどうやればいいでしょうか。
合わせて教えていただけると幸いです。

該当のソースコード

def is_prime(n):
if n == 1:
return False
if n == 2:
return True
for k in range(2, int((n ** 0.5)+ 1)):
if n % k == 0:
return False
else:
return True

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

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

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

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

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

y_waiwai

2020/09/30 09:55

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
guest

回答4

0

ベストアンサー

試し割法ですね。
一度 n % k == 0 が成立しなかったからと言って、素数であると断定するのは尚早です。

return True は試し割が終わった後、for文の外側に置いて下さい。

投稿2020/09/30 10:02

LouiS0616

総合スコア35668

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

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

nr5tm

2020/09/30 10:06

ありがとうございます。解決しました
guest

0

再起処理で実装しないと無理かと。
というかfor文が一回回った時点で処理が終了しています。どこが悪いかとかそういうレベルではありません。すべて悪いです。

投稿2020/09/30 09:55

774

総合スコア79

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

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

LouiS0616

2020/09/30 10:03

素数を再帰処理で判定するコードってあんまり見ないですけど、例えばどんなのがありますか?
nr5tm

2020/09/30 10:06

ありがとうございます。もっと勉強します。
774

2020/09/30 10:43 編集

https://qiita.com/isso_w/items/8982d093760240330ebc これは配列でその中のってやつです。 自分が考えていたのは入力した数の平方根を上限とした配列を作り、それを多重でって考えていましたが、判定するだけなら確かに試し割りが良さそうですね。重ねて申し訳ありません、 というか試し割法なんてあるんですか。
LouiS0616

2020/09/30 10:56 編集

@774 さん エラトステネスの篩も非再帰で実装している例の方が多いと思いますよ。 https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Pseudocode 例えば分割統治法のアルゴリズムは再帰と親和性が高いですが(クイックソートなど)、 それでも再帰処理を使わないと書けないわけではありません。
774

2020/09/30 11:16

配列で作るならで思いついたのがその方法であって、後にコード見て再帰で良いんじゃね?ってなった感じです。 再帰じゃないと書けないのはおっしゃる通りですが…そうですね、初心者なのは分かるんですけどそもそもこのプログラムPythonのプログラムなのにインデントが整ってないんですよ。 よくそれで質問したなってので腹立って書きました。発言に勘違いがあったのは申し訳ないです。
LouiS0616

2020/09/30 11:22

コードブロックを使わないとインデントが潰れるので、おそらく質問者の手元では少なくとも文法エラーが出ないレベルにはインデントが付けられている筈です。 本当にインデント無しで実行したらSyntaxErrorで落ちます。
774

2020/09/30 11:28

これっておそらくですが学校の宿題かなんかをこっちで丸投げしてるんじゃないですか? だからこそおかしい点に気付かずそのまま投げてきたのでは? それは仮定が間違っているかと。
774

2020/09/30 11:30

まぁでもインデントコードブロックじゃないとつかないのか…
LouiS0616

2020/09/30 11:35

> 9や21,49は素数でないのにもかかわらず、True と表示されてしまいます。 と書いてあるのが丸々嘘で無い限り、インデントが本来付いていると考えるのは充分推論として成立していると思います。 逆に『学校の宿題の丸投げ』というのは、あり得ないとは言いませんが、現時点では「まあそういうふうに想像もできるよね」くらいの説得力しかありません。
774

2020/09/30 11:41

ですか。
774

2020/09/30 11:46

そうだとしても、あのコードは気持ち悪かったです。 まぁだからって言い過ぎか、発言が過激だったのは申し訳ありません。
guest

0

3 つの方法を書いてみました。
p.py

pythn3

1import math 2 3def is_prime(n): 4 if n < 2: 5 return False 6 if n == 2: 7 return True 8 9 for k in range(2, int(math.sqrt(n) + 1)): 10 if n % k == 0: 11 return False 12 return True 13 14def is_prime_2(n): 15 return not (n < 2 or any(n % x == 0 for x in range(2, int(n ** 0.5) + 1))) 16 17def primes_upto(limit): 18 is_prime = [False] * 2 + [True] * (limit - 1) 19 for n in range(int(limit**0.5 + 1.5)): # stop at ``sqrt(limit)`` 20 if is_prime[n]: 21 for i in range(n*n, limit+1, n): 22 is_prime[i] = False 23 return [i for i, prime in enumerate(is_prime) if prime] 24 25MAX = 100 26for x in range(1, MAX + 1): 27 if is_prime(x): 28 print(x, end=" ") 29print("") 30 31for x in range(1, MAX + 1): 32 if is_prime_2(x): 33 print(x, end=" ") 34print("") 35 36for x in primes_upto(MAX): 37 print(x, end=" ") 38print("")

実行例:
イメージ説明

参考情報;

  • Primality by trial division

https://rosettacode.org/wiki/Primality_by_trial_division#Python

  • Sieve of Eratosthenes

https://rosettacode.org/wiki/Sieve_of_Eratosthenes#Python

  • 素数の一覧

https://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0%E3%81%AE%E4%B8%80%E8%A6%A7

投稿2020/10/07 22:31

katoy

総合スコア22324

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

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

0

  • 関数定義の末尾の「:」が全角で書いてある
  • 試し割は、すべてのkについて割り切れなかったときだけTrue、ひとつでも割り切れる値があればFalse

Python

1def is_prime(n): 2 if n == 1: 3 return False 4 if n == 2: 5 return True 6 for k in range(2, int((n ** 0.5) + 1)): 7 if n % k == 0: 8 return False 9 return True 10 11 12for i in range(1, 20): 13 if (is_prime(i)): 14 print(i, end=", ") 15print()

result

12, 3, 5, 7, 11, 13, 17, 19,

投稿2020/09/30 10:13

編集2020/09/30 10:15
Daregada

総合スコア11990

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問