カーマイケル数

 投稿者:永野護  投稿日:2010年 4月 9日(金)12時57分46秒
  山中様、SECOND様、丁寧な回答ありがとうございました。
教えていただきましたプログラムを参考にして擬素数をみつけることができました。
両氏のお忙しいところ、まことに申し訳ないのですが、今度はカーマイケル数
の場合はどのようなプログラムにすればよいのか教えていただけないでしょうか。
十進BASICでできるのでしょうか。もし暇な時間があるようでしたら、よろしくお願いします。
 

Re: カーマイケル数

 投稿者:山中和義  投稿日:2010年 4月 9日(金)13時57分47秒
  > No.1165[元記事へ]

永野護さんへのお返事です。

> カーマイケル数の場合はどのようなプログラムにすればよいのか教えていただけないでしょうか。

前回の延長線では
!カーマイケル数

OPTION ARITHMETIC RATIONAL !有理数モード(多桁整数)

LET M=10000 !検索範囲

FOR n=2 TO M
   IF PrimeQ(n)=0 THEN !合成数nが

      FOR a=2 TO n-1 !底
         IF GCD(a,n)=1 THEN !自身と互いに素である任意の自然数aに対して
            IF MOD(a^(n-1),n)<>1 THEN EXIT FOR !a^(n-1)≡1 mod n を満たす
         END IF
      NEXT a
      IF a=n THEN PRINT n !最後までなら

   END IF
NEXT n

END

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
OPTION ARITHMETIC RATIONAL !有理数モード(多桁整数)
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !偶数なら
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSE !奇数なら
   LET k=3
   DO WHILE k*k<=n !3~√nの奇数のみで検証する
      IF MOD(n,k)=0 THEN EXIT FUNCTION !ひとつでも割り切れるものがあれば素数でない
      LET k=k+2
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

となりますが、多桁整数の計算のため時間を要します。

十進モードや2進モードで高速に計算するには、
関数GCDの定義とa^(n-1)のオーバーフロー対策をプログラムする必要があります。
!カーマイケル数

LET M=10000 !検索範囲

FOR n=2 TO M
   IF PrimeQ(n)=0 THEN !合成数nが

      FOR a=2 TO n-1 !底
         IF GCD(a,n)=1 THEN !自身と互いに素である任意の自然数aに対して
            IF modpow(a,n-1,n)<>1 THEN EXIT FOR !a^(n-1)≡1 mod n を満たす
         END IF
      NEXT a
      IF a=n THEN PRINT n !最後までなら

   END IF
NEXT n

END

EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !偶数なら
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSE !奇数なら
   LET k=3
   DO WHILE k*k<=n !3~√nの奇数のみで検証する
      IF MOD(n,k)=0 THEN EXIT FUNCTION !ひとつでも割り切れるものがあれば素数でない
      LET k=k+2
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

EXTERNAL FUNCTION modpow(a,n,b) !a^n≡x mod b のxを返す ※nは非負整数
LET S=MOD(1,b)
DO WHILE n>0 !べき乗nを2進展開する
   IF MOD(n,2)=1 THEN LET S=MOD(S*a,b) !ビットが1なら計算する
   LET a=MOD(a*a,b)
   LET n=INT(n/2)
LOOP
LET modpow=S
END FUNCTION

EXTERNAL FUNCTION gcd(a,b) !最大公約数
DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
LOOP
LET gcd=a
END FUNCTION
 

Re: カーマイケル数

 投稿者:永野護  投稿日:2010年 4月 9日(金)14時41分20秒
  > No.1166[元記事へ]

山中和義様、お忙しい中、度重なるご回答ありがとうございました。
大変参考になりました。
敬具
 

Re: カーマイケル数

 投稿者:山中和義  投稿日:2010年 4月 9日(金)20時27分8秒
  > No.1165[元記事へ]

永野護さんへのお返事です。

別解 カーマイケルのλ関数でカーマイケル数を求める
FOR n=1 TO 10000
   IF PrimeQ(n)=0 AND MOD(n,carmichaelLambda(n))=1 THEN PRINT n
NEXT n

END


EXTERNAL FUNCTION PrimeQ(n) !素数判定 1:素数、0:素数でない
LET PrimeQ=0
IF n<2 OR n<>INT(n) THEN EXIT FUNCTION !引数を確認する
!2以上の自然数なら
IF MOD(n,2)=0 THEN !偶数なら
   IF n=2 THEN LET PrimeQ=1 !2は素数
ELSE !奇数なら
   LET k=3
   DO WHILE k*k<=n !3~√nの奇数のみで検証する
      IF MOD(n,k)=0 THEN EXIT FUNCTION !ひとつでも割り切れるものがあれば素数でない
      LET k=k+2
   LOOP
   LET PrimeQ=1 !最後まで割り切れなければ、素数である
END IF
END FUNCTION

EXTERNAL FUNCTION gcd(a,b) !最大公約数
DO UNTIL b=0
   LET t=b
   LET b=MOD(a,b)
   LET a=t
LOOP
LET gcd=a
END FUNCTION


EXTERNAL FUNCTION lcm(a,b) !最小公倍数
LET lcm=a*b/gcd(a,b)
END FUNCTION

EXTERNAL FUNCTION carmichaelLambda(n) !カーマイケルのλ関数
!与えられた数nに対し、a^m ≡ 1 (mod n) が
!任意のnと互いに素なaについて成立するような最小のmを返す。
LET ans=1
IF MOD(n,8)=0 THEN LET n=n/2
FOR d=2 TO n
   IF MOD(n,d)=0 THEN
      LET y=d-1
      LET n=INT(n/d)
      DO WHILE MOD(n,d)=0
         LET n=INT(n/d)
         LET y=y*d
      LOOP
      LET ans=lcm(ans,y)
   END IF
NEXT d
LET carmichaelLambda=ans
END FUNCTION
 

Re: カーマイケル数

 投稿者:永野護  投稿日:2010年 4月10日(土)14時39分11秒
  > No.1168[元記事へ]

山中様の再三のお返事に感謝します。
お忙しい中、ありがとうございました。
私には少々難しいですが、参考にさせていただきます。
 

戻る