素数かどうかを判定するプログラムをつくるには?


かぼちゃ  2005-07-22 23:02:11  No: 16505

自然数nを入力してそれが素数かどうかを判定するプログラムをつくるにはどうしたらよいでしょうか?内容を教えていただけると幸いです。


こうすけ  2005-07-22 23:14:09  No: 16506

素数の公式はまだ発見されていないので、自然数n(n > 0)を元にしたプログラムは不可能ですよ。
それができたらノーベル賞もの。

ただし、nの範囲が40まで、または100まで。
など、上限を加えるとしたらいくつか方法はあります。

例えばエラトステネスのふるいなど。


ウォレス  2005-07-23 01:10:39  No: 16507

・・・・・
長文PSOTしたのに消えた・・・
調子悪いですね・・・


Syake  2005-07-23 05:10:46  No: 16508

調子悪。3回目
単に数値がどうか判定ですよね。
素数は1と自身でしか割れない数値。
でしたよね。
ならば・・・

取り急ぎで1は除外
var
   i,intX :Integer;
   IntChk :Boolean;
begin
   intX := StrToInt(Edit1.Text);
   IntChk := False;
   for i := 2 to intX - 1 do
   begin
      if (intX mod i) = 0 then//剰余が無いので割れちゃった
      begin
         IntChk := True;
      end;
   end;
   if IntChk = False then
   begin
      ShowMessage('素数');
   end else begin
      ShowMessage('以外');
   end;
end;
てのはどうでしょうか?


ウォレス  2005-07-23 05:32:02  No: 16509

再チャレンジ

素数判定アルゴリズムは難易度が死ぬほど高いものがいっぱいあるみたいですが、課題で点が高くもらえそうな感じにするなら、

1.偶数か調べる
2.6n+1、6n-1か調べる
3.メルセンヌ数か調べる->ルカステストへ
4.√N以下のの奇数で順に割っていく

というのがオーソドックスではないでしょうか。


Syake  2005-07-23 19:32:18  No: 16510

問題が複雑になっとる。
最初の
>自然数nを入力してそれが素数かどうかを判定するプログラム

>素数判定アルゴリズムは・・・
は違う気がしますが。

http://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0
http://ja.wikipedia.org/wiki/%E7%B4%A0%E6%95%B0%E5%88%A4%E5%AE%9A
「素数判定」は自然数(n)が素数か合成数かを判定する事だとありますが。
違うのかな?


Syake  2005-07-23 19:39:32  No: 16511

失礼しました。
合成数は素数以外でしたね。
で「素数か?」と「素数判定」は同じことですね。
失礼しました。


Syake  2005-07-23 21:22:03  No: 16512

しつこいです。すいません。
やっぱり、間違いない。
何か勘違いか?

>自然数nを入力してそれが素数かどうかを判定するプログラム
ウォレスさんには申し訳ないのですが、この場合はメルセンヌ数も平方根
云々も複雑な公式も無関係のような・・・<m(__)m>
最初の内容とはずれているような

var
   i,j,IntX :Integer;
   IntChk :Boolean;
   IntCount :Integer;
   intMax :Integer;
begin
   IntCount := 0;
   intMax := StrToInt(Edit1.Text);
   Memo1.Clear;
   for i := 2 to IntMax do
   begin
      IntChk := False;
      for j := 2 to i -1 do
      begin
         if (i mod j) = 0 then
         begin
            IntChk := True;
            Break;
         end;
      end;
      if IntChk = False then
      begin
         IntCount := IntCount + 1;
         Memo1.Lines.Add(IntToStr(i));
      end;
   end;
   Edit2.Text := IntToStr(IntCount); // intMAX内に素数が何個有るか
end;
膨大な桁数を計算するならいざ知らず。
10万桁までなら確認しましたが、結果は正しく出力されますので関数化すればよいものと。
なんか、間違ってますか?


メラトニン  2005-07-24 00:36:52  No: 16513

掲示板直ったようですね、よかったです。
>Syakeさん
>膨大な桁数を計算するならいざ知らず。
その数が素数かどうかの判断の場合大抵の場合、対象となる素数は「膨大な桁数」です。それに対して如何に計算量を減らして判別するかの方法をウォレスさんが述べてくれています。
例えば2の倍数は割ってみる必要すらないですよね?


@123  2005-07-24 02:05:11  No: 16514

かぼちゃさんが欲している、返信と違うような、先輩方のを批判するつもりはないが、ただ「n入力してそれが素数かどうかを判定するプログラム」
を欲しがっているのでは?


メラトニン  2005-07-24 02:36:41  No: 16515

>>ただ「n入力してそれが素数かどうかを判定するプログラム」
だからそれが難題だと言ってるのです。

例えばn=
18819881292060796383869723946165043980716356337941
73827007633564229888597152346654853190606065047430
45317388011303396716199692321205734031879550656996
221305168759307650257059

は素数ですか?と聞かれたときSyakeさんのアルゴリズムでは
現在のPCでは説くことはほぼ不可能だと言うことがわかりますよね?
ちなみにこれが解けたら$10,000もらえます。
http://www.rsasecurity.com/rsalabs/node.asp?id=2093


ウォレス  2005-07-24 21:50:43  No: 16516

あ〜すみません。話をややこしくしたみたいですね。メラトニンさん、補足ありがとうございます。

単に素数かどうか?を判定する  and  時間はどうでもいい
であれば、自分以下の数で順に割れば構いません。

ただ、
自分の平方根より大きな約数は存在しない
偶数の素数は2しかない
5以上の素数は必ず、6n+1か6n-1になる
メルセンヌ数に限り、非常に簡単な判定法がある

というのが私でも理解できる範囲の枝狩り手法だということです。

逆に難易度がどんなに高くてもいいから多項式時間で解きたい場合には多項式時間で判定するアルゴリズムもあります。(すみません。受け売りです)
(とにかく巨大な数以外では他の判定方法のほうが有利だそうです。)

ちなみにRSAの賞金は魅力的ですが、みなさんチームで数百人単位でやってますので、個人じゃあ無理ですよね・・・

SFネタでよければグレッグ・イーガンの「宇宙消失」にそういうネタがあります。
あ〜さらに無意味なレスに・・


@123  2005-07-25 00:10:17  No: 16517

この掲示板てDelphiですよね
パソコンで答えの出る答えを聞いているんじゃないんですか
(時間オーダーとか、メモリーオーダー)
答えが出る範囲で答えを求めているんじゃないんですか。
たとえば質問で円周率を求めたいんですがと聞かれた場合
普通有限要素で答えますよね、違いますか

答えをどの程度をを指定していないからといって拡大解釈しすぎると思うのですが。


  2005-07-25 01:21:08  No: 16518

どうでもいいですが、質問者が出てこない限りお話になりません


メラトニン  2005-07-25 01:23:50  No: 16519

>@123さん
>「パソコンで答えの出る答え」
パソコンと言うのは「計算機」です。
例えばある問題を解く場合、その解法がA,B,C,Dとあったとします。
A:非常に単純で分かりやすい計算方法しかし遅い(無駄が多い)
B:難解だが高速(無駄が少ない)
C:難解だが完全回答
D:簡単で完全回答
といった場合あなたはどれを選択しますか?
プログラムとしては「D→C→B→A」の順に"有用"ではないでしょうか?
ただし、今回の場合D,Cを証明できた人は居ません。
だったらBを選択するのは当然のことかと思います。

>たとえば質問で円周率を"求めたい"んですがと聞かれた場合
>普通有限要素で答えますよね、違いますか
違います。
円周率はどこまでも求めることができます。
途中までしか求められない計算式があったとすればその回答は誤りと言って良いでしょう。

ただ、計算に使うための円周率であれば、必要な桁数だけを計算するのは正しいと思います。

私が上記で示した考えられないような自然数も皆パソコンで解こうとしています。
しかも現在解きつつある状態です。

アルゴリズムに関する質問の場合
「答えをどの程度をを指定していない」
場合は完全回答を意味するものと判断してください。
これはプログラムを扱う人間にとって常識といってもよいと思います。


そのとおり  2005-07-25 01:38:35  No: 16520

程度を指定しない質問で、あれこれ制限をつけて正しいとか正しくないとかは
議論してもあまり収穫はないでしょう。

わたしの場合は、素数の証明は難しいことを知っていますので、今回は回答しない
か、質問者が例えば「1000以下」とか限定しない限り回答をかくことはないでしょう。


Fusa  2005-07-25 02:52:26  No: 16521

ようやくなおりましたか。

とりあえず
大きい整数値を扱うユニットです。
http://www.mogya.com/index.php?cmd=read&page=%B4%C1%BF%F4%C5%C5%C2%EE

個人的にHigh(Cardinal)までの素数列を
求めたらそれで満足しちゃいましたので
そういう計算にはこのユニットは使ってないのですが

今回のような
数学的な動作をするプログラムには
役に立つと思いますよ。

小数点以下も半無限桁扱えるように
誰か改造してくれないかしら。


かぼちゃ  2005-07-25 09:38:58  No: 16522

みな様返信ありがとうございます。Syakeさんので大丈夫そうです!本当にありがとうございます。
追加なんですが、
1.  1000000001(0が8個続いています)が合成数であることを1秒以内に判定してください。
2.  1000000021(0が途中に7個続いています)が素数であることを10秒以内で判定してださい。
というプログラムを同時に作りたいんですが、教えていただきイです。


値が分かってるなら1msも要らん  2005-07-25 17:19:57  No: 16523

var
  i:Longint;

if i=1000000001 then
  Showmessage(素数でない)
else if i=1000000021 then
  Showmessage(素数)
else
  Showmessage(不明);


ウォレス  2005-07-25 18:44:16  No: 16524

あのお・・・

枝狩りをすれば私のPC(Pen4 3.2G)だとどちらも100msもかかりませんけど・・

それから訂正。

>自分の平方根より大きな約数は存在しない
嘘です。自分の平方根より大きな約数はチェックする必要がない
です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加