メルセンヌプライムですか?


35

数が素数であり、2 n -1の形式で記述できる場合、数はメルセンヌ素数です。ここで、nは正の整数です。

あなたの仕事は、正の整数を与えられて、それがメルセンヌ素数であるかどうかを決定することです。真実/偽の値を返す関数、またはIOを実行する完全なプログラムのいずれかを送信できます。

ルール:

  • これは可能な限り最短のバイトカウントでこれを行う必要があります組み込みが許可されます。
  • 標準的なゴルフの抜け穴が適用されます-外部ファイルからメルセンヌ素数を読み取ったり、プログラムにハードコードしたりすることはできません。
  • プログラムは、言語の標準整数サイズ内の値に対して機能するはずです。

テストケース

参考のために、(既知の)メルセンヌプライムのリストはこちらにあります。便利なテストケースは次のとおりです。

2  -> False
1  -> False 
20 -> False
51 -> False
63 -> False

3    -> True
31   -> True
8191 -> True

みなさん、メリークリスマス!あなたが祝うものは何でも、素晴らしい休日を過ごしてください:)


2
本当に何も新しいものを追加しないので、私はこれをisprimeチャレンジのduとして投票したいと思います。
flawr 16

9
数として表現可能であるかどうかが、この挑戦のために、組み込みをになりにくいがあり、興味深いアプローチの多くは、決定にある- @flawr彼らは非常に似ている2^n-1
FlipTack

1
(。^ nは(2)のために、また、必要な証明されている条件が、十分ではない-1プライムように)私はn個の素数であることメルセンヌ数の定義はまた、義務と考えている
SuperJedi224

4
@ SuperJedi224 nは常に素数ですが、それが何も変わらないことを知っていれば、定義は正しいままです。
FlipTack 16

2
@TheBitByteはい-100%動作しない確率ベースのアルゴリズムを実装している場合、それを投稿することはできますが、競合することはありません:)
FlipTack

回答:


19

ゼリー、5バイト

&‘<ÆP

オンラインでお試しください!

使い方

&‘<ÆP  Main link. Argument: x

 ‘     Yield x+1.
&      Take the bitwise AND of x and x+1.
       This yields 0 iff x is a Mersenne number, i.e., iff x+1 is a power of 2.
   ÆP  Yield 1 if x is a prime, 0 if not.
  <    Compare the results to both sides,
       This yields 1 iff x is both a Mersenne number and a prime.

アドナンの答えと同じ問題。参照してくださいmothereff.in/byte-counter
ケリーLowder

8
@KellyLowderそのバイトカウンターはUTF-8を使用します。Jellyと05AB1Eはどちらもシングルバイト文字セットを使用します。
デニス

24

05AB1E、5バイト

2 n -1の形式の正数は、1のみで構成されます。

コード:

b`¹pP

説明:

b`      # Push each digit of the binary representation of the number onto the stack
  ¹p    # Check if the input is prime
    P   # Take the product of all these digits

CP-1252エンコードを使用します。オンラインでお試しください!または、すべてのテストケースを確認します


5
誰かがそのトリックを使用するまでどれくらい
かかるの

¹2つのバイトを要するので、これは6である
ケリーLowder

5
@KellyLowder UTF-8では、はい。ただし、05AB1EはUTF-8エンコードではなくCP-1252エンコードを使用します。
アドナン

10

Python、45バイト

lambda n:-~n&n<all(n%i for i in range(2,n))<n

オンラインでお試しください!

使い方

連鎖比較の3つの用語

-~n&n<all(n%i for i in range(2,n))<n

以下をせよ:

  • -~n&nn + 1nのビット単位のANDを計算します。nがメルセンヌ数の場合、1ビットのみで構成されるため、ビット単位のANDは、そうである場合(のみ)、0を返します

  • all(n%i for i in range(2,n))戻り真の場合にのみ、N iは国防省の全ての値に対してゼロでないI[2、...、N - 1] 、すなわち、および場合だけ、nが離れてからの正の約数を持たない1N

    言い換えれば、すべてのリターンは真の場合に限り、nは合成数である、すなわち、n個のいずれかである1またはプライム。

  • n 自明です。

連鎖比較は、個々の比較が同じ場合にのみTrueを返します。

  • 以来、すべてのリターンのいずれか / 1または / 0-~n&n<all(n%i for i in range(2,n))のみ返すことができる真の場合には-~n&n利回り0(すなわち、場合nはメルセンヌ数である)と、すべてのリターンはTrue(場合、すなわちnはどちらか1またはプライム)。

  • 比較all(n%i for i in range(2,n))<nn> 1の場合は常に保持されますが、n = 1の場合はすべてTrueを返すため、この場合は保持されません。


1
うわー、それは素晴らしいです:)
ABcDexter

8

Brachylog、7バイト

#p+~^h2

オンラインでお試しください!

Brachylogプログラムは基本的にチェーンを形成する一連の制約です。最初の制約は入力と匿名の不明の間にあり(この説明のためにAと呼びます)、2番目の制約は匿名の匿名と2番目の匿名の間にあります不明(これをBと呼びます)など。そのため、プログラムは次のように分類されます。

#p      Input = A, and is prime
+       B = A + 1
~^      B = X to the power Y, C = the list [X, Y]
h       D = the head of list C (= X)
2       D = 2

これらのすべての制約を同時に満たすことができる唯一の方法は、Bが2のべき乗、つまり入力が2のべき乗から1を引いたもので、入力も素数である場合です。(Brachylogは内部で制約ソルバーを使用するため、プログラムは評価順序のように非効率になりません。2つの数値のべき乗として表現しようとする前Cの形式であることを認識します。)[2, Y]B

興味深いことに、#p+~^ ほとんどメルセンヌ状素数のみ非縮退の場合(にベースとして2を使用することができるので、動作証明)が、)非メルセンヌは、プライミングのためにそれは失敗Bを -1それらはのように表すことができるようにB ¹、およびB )既存のBrachylogインタープリターは、その制約が不十分なプログラムによって混乱している(無限ループ、または少なくとも長期のループに入る)ようです。したがって、7バイトがBrachylogで破られる可能性は低いようです。


私が感銘を受けた!無限ループの問題に関しては、これは述語のオーバーロードによるものです。振り返ってみると、述語のオーバーロードを実装すべきではなかったと思います。これは、findallなどの問題も引き起こします。
1

7

Mathematica 26バイト

PerfectNumberQ[# (#+1)/2]&

この証明を見る

奇数の完全な数がなく、存在することがわかっていない限り機能します。


あなたの答えは有効であると証明されていませんか?
ジョナサンフレッチ

スペースは必要ないと思います。
ジョナサンフレッチ

@JonathanFrechこの式は、メルセンヌ素数(ユークリッド)のn(n+1)/2場合は常に(偶数)完全な数を生成しnます。奇数の完全数がの形式をとることができるかどうかn(n+1)/2、つまり、三角形の数であるかどうかは不明のようです。すべてでも、これはどこ完全数は三角形であるnメルセンヌ素数(オイラー)です。
ジェッペスティグニールセン

1
@JeppeStigNielsen問題は、未知の事実を使用して解決策の基礎を作ることが有効かどうかです。
ジョナサンフレッチ

7

Mathematica、29 26バイト

編集:マーティン・エンダーのおかげで3バイト保存

PrimeQ@#&&IntegerQ@Log2[#+1]&

PrimeQ@#&&1>BitAnd[#,#+1]&

最初の42の指数がハードコードされているため、これは高速になると思います。

MersennePrimeExponentQ@Log2[#+1]&

6
PrimeQ@#&&1>BitAnd[#,#+1]&
マーティンエンダー


5

Python、83 82 79 76 73バイト

def f(m):
 s,n=(m!=3)*4,m>>2
 while-~m&m<n:s,n=(s*s-2)%m,n>>1
 return s<1

Python 2、71バイト

def f(m):
 s,n=(m!=3)*4,m/4
 while-~m&m<n:s,n=(s*s-2)%m,n/2
 return s<1

この関数はLucas–Lehmerの素数性テストを実装しているため、他のPython製品のいくつかほど短くはありませんが、巨大な入力の処理ははるかに高速です。


Python 2またはPython 3で実行されるテストコードを次に示します。

from __future__ import print_function

def primes(n):
    """ Return a list of primes < n """
    # From http://stackoverflow.com/a/3035188/4014959
    sieve = [True] * (n//2)
    for i in range(3, int(n**0.5) + 1, 2):
        if sieve[i//2]:
            sieve[i*i//2::i] = [False] * ((n - i*i - 1) // (2*i) + 1)
    return [2] + [2*i + 1 for i in range(1, n//2) if sieve[i]]

def lucas_lehmer_old(p):
    m = (1 << p) - 1
    s = 4
    for i in range(p - 2):
        s = (s * s - 2) % m
    return s == 0 and m or 0

# much faster
def lucas_lehmer(p):
    m = (1 << p) - 1
    s = 4
    for i in range(p - 2):
        s = s * s - 2
        while s > m:
            s = (s & m) + (s >> p)
    return s == 0 or s == m and m or 0

def f(m):
 s,n=(m!=3)*4,m>>2
 while-~m&m<n:s,n=(s*s-2)%m,n>>1
 return s<1

# Make a list of some Mersenne primes
a = [3]
for p in primes(608):
    m = lucas_lehmer(p)
    if m:
        print(p, m)
        a.append(m)
print()

# Test that `f` works on all the numbers in `a`
print(all(map(f, a))) 

# Test `f` on numbers that may not be Mersenne primes
for i in range(1, 525000):
    u = f(i)
    v = i in a
    if u or v:
        print(i, u, v)
    if u != v:
        print('Error:', i, u, v)

出力

3 7
5 31
7 127
13 8191
17 131071
19 524287
31 2147483647
61 2305843009213693951
89 618970019642690137449562111
107 162259276829213363391578010288127
127 170141183460469231731687303715884105727
521 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151
607 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127

True
3 True True
7 True True
31 True True
127 True True
8191 True True
131071 True True
524287 True True

FWIW、すべてのループでf再テストしないわずかに効率的なバージョンがありmます:

def f(m):
 s,n=m!=3and 4,m>>2
 if-~m&m<1:
  while n:
   s=(s*s-2)%m
   n>>=1
 return s<1

whileループはすべて1行で記述できます(改行とインデントは不要です)
FlipTack

@FlipTack D'oh!ありがとうございました!私はそれを逃した理由を私は本当に知りません...そして、私はちょうど私がより多くのカップルは、Python 2に戻すことにより、バイトオフに剃ることができます気づいた
PM 2Ring

4

R、41 40バイト

matlab::isprime(x<-scan())&!log2(x+1)%%1

奇妙なことに、Rの組み込み関数は引数としてではなく、引数としてmersenne受け取りnます2^n-1

これはxSTDINから取得し、matlabパッケージを使用して素数であるかどうかx+1を確認し、mod 1を取得して「ゼロでない」ことを確認することにより、2-logが整数かどうかを確認します。

また、mersenneビルトインを使用すると、やや短くなりますが、不正行為のように感じます:

numbers::mersenne(log2(scan()+1))

@Billywobのおかげで1バイト節約


同様の回答を投稿しましたが、今すぐ削除しました。matlab::isprime1バイトを保存することをお勧めします。また<-、関数内の割り当てにも使用する必要があります。
ビリーウォブ16

@billywobは、matlab :: isprimeが1バイト短くなっていることにも気づきました。(ソリューションで1秒のピークを見つけました)。
JAD

log2(x+1)代わりにを使用することもできますlog(x+1,2)
ビリーウォブ16


2

実際には、9バイト

;├╔'1=@p*

オンラインでお試しください!

説明:

2 n -1 の形式のすべての数は、そのバイナリ表現ですべて1を持っているため、メルセンヌ素数はその品質の素数として識別できます。

;├╔'1=@p*
 ├╔'1=     only unique binary digit is 1
        *  and
;     @p   is prime

2

ゼリー、5バイト

@Dennisの既存の5バイトJelly回答への代替アプローチ:

B;ÆPP

オンラインでお試しください!

使い方:

B      Returns the binary representation of the input as a list [1, 0, 1, 1, ...]
 ;     And attach to this list 
  ÆP   a 1 if the input is a prime, 0 otherwise
    P  Calculates the product of this list of 1's and 0's

メルセンヌプライムは2のべき乗よりも1つ少ないため、そのバイナリ表現は1になります。そのための出力は、メルセンヌ素数の場合は1、その他の場合はすべて0です。


2

セイロン、66バイト

Boolean m(Integer c)=>c>2&&c.and(c+1)<1&&!(2:c-2).any((d)=>c%d<1);

フォーマット済み(およびコメント付き):

// Check whether a (positive integer) number is a mersenne prime number.
//
// Question:  http://codegolf.stackexchange.com/q/104508/2338
// My Answer: http://codegolf.stackexchange.com/a/104805/2338

Boolean m(Integer c) =>
        // check whether c+1 is a power of two
        c.and(c+1)<1 &&
        // the standard primality check by trial division
         !(2 : c-2).any((d) => c%d < 1) &&
        // we need to exclude 1, which is unfortunately
        // matched by both criteria above, but is no prime.
        c>1;

チート(Ceylonの整数の範囲で結果をハードコーディング)すると、バイトを短くすることができます(65):

Boolean h(Integer c) =>
        c.and(c+1)<1 && #20000000800a20ac.and(c+1)>0;

(構文ハイライターはCeylonの16進数をコメントの開始と誤解しているようです。)

無名関数に問題がない場合、これは49バイトです。

[2,3,5,7,13,17,19,31,61].map((p)=>2^p-1).contains

2

Wolfram言語(Mathematica)、23バイト

PrimeQ[BitAnd[#,#+2]#]&

オンラインでお試しください!

1があるため、正しく処理されますPrimeQ[BitAnd[1,1+2]*1] == PrimeQ@1 == False。さもなければ、BitAnd[#,#+2]#素数であるために#BitAnd[#,#+2] == 1、それが素数であり、#メルセンヌ数であるときに起こるが必要です。


うまくできました!しかし、Mathematicaを使用したことがない人として、最初はTIOコードが混乱していました。それから、あなたはあなたの機能をngenisisの以前に結ばれた記録保持者と比較していることに気付きました。関数の出力表示するだけで、他のソリューションと比較する2つ目のリンクがあれば良いと思います。
デッドコード

2

ECMAScript正規表現、42 31バイト

^(?!(xx+)\1+$)(x(x*)(?=\3$))+x$

^
(?!(xx+)\1+$)      # Assert that N is prime or 0 or 1.
(x(x*)(?=\3$))+x$  # Assert that N is a power of 2 minus 1 and is >= 3.
                   # The >=3 part of this prevents the match of 0 and 1.

オンラインでお試しください!

編集:ニールのおかげで31バイトまで。

基本的な「2のべき乗マイナス1」テストは^(x(x*)(?=\2$))*$です。これは、「1を引き、次に2で均等に割る」操作をそれ以上実行できなくなるまでループし、結果がゼロであることをアサートすることで機能します。これは、最後の値*をaに変更して+、ループを少なくとも1回繰り返すことにより、≥1の数のみに一致するように変更できます。x最後の前にを挿入する$すると、少なくとも1回ループした後の最終結果が1であることをアサートすることにより、≥3のみの数字に一致するようにさらに変更します。

関連する「2の累乗」テストは^((x+)(?=\2$))*x$です。Grimyによって発見された、2から2のべき乗を一致させるための省略形もあります。^((x+)(?=\2$)x)*$。これらの3つの正規表現はすべて同じ長さです。

Grimyによる代替の31バイトバージョン:

^(?!(xx+)\1+$|((xx)+)(\2x)*$)xx

オンラインでお試しください!

# Match Mersenne primes in the domain ^x*$
^                   # N = input number
(?!                 # "(?!p|q)" is equivalent to "(?!p)(?!q)"; evaluate the
                    # logical AND of the following negative lookaheads:
    (xx+)\1+$       # Assert that N is prime or 0 or 1
|
    ((xx)+)(\2x)*$  # Assert that N is a power of 2 minus 1; this is based
                    # on "(?!(x(xx)+)\1*$)" which matches powers of 2.
)
xx                  # Assert that N >= 2, to prevent the unwanted match of
                    # 0 and 1 by both of the negative lookahead statements.

1
2のべき乗よりも小さい数値1を直接チェックして、11バイトを節約します。オンラインで試してください!
ニール

@Neilどうもありがとう!私はそのことを考えていたらよかったのですが、それがまさに私が実現したかったようなことです!
デッドコード

1
実際にそれを考えるとx(x+)(?=\3$)、わずかに効率的ですか?
ニール

うん、あなたは絶対に正しい。
デッドコード

2

正規表現(ECMAScript)、29バイト

^(?!(xx+|(x(x))+)(\1\3)+$)xxx

オンラインでお試しください!

チャットで Grimyに触発

正規表現は、入力が3より大きく、次のいずれの形式でもないことを表明します。 (xx+)\1+または((xx)+)(\1x)+

最初は複合数に一致します。
2番目の値は、2より大きい奇数の倍数より1少ない数に一致します。

最初は素数、またはまたはと一致しません。 2番目はフォームの番号と一致しません01
2n1、または奇数の素数より1少ない数値。

2が奇数の素数より1少ない唯一の素数であるため、負の先読みは、入力が3より大きいというアサーションとともに、メルセンヌ素数のみに一致します。


1

ルビー、47バイト

->b{!("%b"%(b/2)=~/0/||(2...b).find{|a|b%a<1})}


1

Python、65バイト

f=lambda n,i=3:(n^i)-all(n%i for i in range(2,n))<0 or f(n,-~i|i)

終了コードを介した出力。Falseの再帰エラー。Trueの場合、エラーはありません。

使い方

以来、2^n-1バイナリ1件のから完全に作られて、次の2^n-1数により生成することができますnumber|number+1

この関数は、これを使用して、各2^n-1数値を再帰的に調べて、それが素数であり入力に等しいかどうかを確認します。数値がメルセンヌ素数でない場合、最大再帰深度を超えていたため、Pythonは最終的にエラーをスローします。


1
私が間違っていなければ、<0〜> 0>
ジョナサンフレッチ

1

Pushy、7バイト

oBoIpP#

オンラインでお試しください!

これは、メルセンヌ数がバイナリ表現に1つしかないという事実を利用しています。

oB      \ Pop input, push its binary digits.
  oI    \ Re-push the input
    p   \ Test its primality (0/1)
     P# \ Print the product of the stack

スタック積は1、その数値のバイナリ表現にゼロがなく、その素数がである場合のみになりますTrue


1

Pyth、8バイト

&.AjQ2P_

すべてのテストケースを確認します。

Pyth、8バイト

<.&QhQP_

すべてのテストケースを確認します。


どうやって?

コードの内訳#1

&.AjQ2P_    Full program with implicit input.

      P_    Is Prime?
   jQ2      Convert the input to binary as a list of digits.
 .A         All the elements are truthy (i.e. all are 1).
&           Logical AND.
            Output implicitly.

それはどのように機能しますか?

フォームの数2 N - 1が常に含ま1バイナリに書き込まれた場合にのみ。したがって、すべての2進数が1であり、かつ素数であるかどうかをテストします。

コードの内訳#2

<.&QhQP_    Full program with implicit input.

      P_    Is Prime?
    hQ      Input + 1.
 .&Q        Bitwise AND between the input and ^.
<           Is smaller than? I.e. The bitwise AND results in 0 and the primality test results in 1.
            Output implicitly.

それはどのように機能しますか?

これは、入力+ 1が2のべき乗かどうか(つまり、メルセンヌ数かどうか)をテストしてから、素数性テストを実行します。Pythonでは、はのboolサブクラスでintあるため、真理は1として扱われ、偽は0として扱われます。一方が0でもう一方が1であることを明示的にチェックしないように、これらの値を比較します<(そのようなケースは1つしかないため)。


1

Java 8、53 52 49バイト

n->{int i=1;for(;n%++i>0;);return(n&n+1|i^n)==0;}

@Nevayのおかげで、バグが修正され、4バイトずつ増えました

説明:

ここで試してみてください。

n->{                // Method with integer parameter and boolean return-type
  int i=1;          //  Temp integer `i`, starting at 1
  for(;n%++i>0;);   //  Loop and increase `i` as long as `n` is divisible by `i`
  return(n&n+1|i^n) //  Then return if `n` bitwise-AND `n+1` bitwise-OR `i` bitwise-XOR `n`
          ==0;      //  is exactly 0
}                   // End of method

現在のソリューションはtrue、メルセンヌ素数だけでなく56バイトを超えるすべての素数に対して返されますn->{for(int i=2;i<n;n&=-n%i++>>-1);return(n&n+1)<1&n>2;}
。– Nevay

1
52バイト:n->{int i=1;for(;++i<n&n%i>0;);return(n&n+1|i^n)<1;}
Nevay

@Nevayありがとう。そして、なぜテストケースにメルセンヌ素数ではない素数が含まれていないのかわからない。
ケビンCruijssen

1
49バイト: n->{int i=1;for(;n%++i>0;);return(n&n+1|i^n)==0;}
Nevay



0

Python、93バイト

def f(a):
 for b in range(a):
  if(a+1==2**b and not[i for i in range(2,a)if a%i<1]):return 1

このコードはPython 2とPython 3の両方で機能するため、バージョンを指定していません。


0

ラケット76バイト

(define(g m)(for/or((i m))(= m(-(expt 2 i)1))))(if(and(prime? n)(g n))#t #f)

ゴルフをしていない:

(require math)
(define(f n)
  (define (ispowerminus1 m)
    (for/or ((i m))
      (= m (-(expt 2 i)1))))
  (if (and (prime? n)
           (ispowerminus1 n))
      #t #f))

テスト:

(f 1)
(f 2)
(f 20)
(f 51)
(f 63)
(f 3)
(f 31)
(f 8191)

出力:

#f
#f
#f
#f
#f
#t
#t
#t

0

PHP、53バイト

for($i=$n=$argv[1];--$i&&$n%$i;);echo!($i-1|$n+1&$n);

コマンドライン引数を取ります。1メルセンヌ素数の場合、空の文字列の場合は印刷します。で実行-rます。

壊す

for($i=$n=$argv[1];--$i&&$n%$i;);   // loop $i down from $n-1 until $i divides $n
                        // If $n is prime, loop ends with $i=1. ($n=1 -> $i=0)
echo!($i-1|$n+1&$n);    // If $i!=1, $n is not prime. If ($n+1&$n)>0, $n is not Mersenne.
                        // If either $i-1 or $n+1&$n is truthy, the negation will be false.

0

C、94バイト

g(n,i){return--i?g(2*n,i):n;}n,r;f(x){for(n=r=1;++n<x;)r=x%n?x^g(2,n)-1?r:r|2:r&2;return r>2;}

数値がメルセンヌ素数の場合は1、それ以外の場合は0を返します。


提案する~x+g(2,n)代わりにx^g(2,n)-1
ceilingcat

0

Scala、59バイト

def f(t:BigInt)=t.isProbablePrime(t.bitLength*9)&(1+t)%2==0

この関数では、入力がである必要がありますBigInt。あなたは簡単に文字列「162259276829213363391578010288127を」(2 ** 107-1は、メルセンヌ素数である)に変換することができますBigInt実行してBigInt("162259276829213363391578010288127")isProbablePrime()メソッドの名前が示すように、うまくいかない可能性があります。しかし、確率は0.5^(t.bigLength)*9

スタンドアロンスクリプトバージョンの長さは72バイトです。

val t=BigInt(args(0));print(t.isProbablePrime(t.bitLength*9)&(1+t)%2==0)

「t.scala」として保存すると、プログラムは次のように実行できます。

>scala t.scala 162259276829213363391578010288127
>true

Scalaに機能がある場合はProbablefrom を削除できます。isProbablePrimeisPrime
MilkyWay90

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.