¿Es un Mersenne Prime?


35

Un número es un Mersenne Prime si es primo y puede escribirse en la forma 2 n -1 , donde n es un número entero positivo.

Su tarea es, dado cualquier número entero positivo, determinar si es o no un primo de Mersenne. Puede enviar una función que devuelve un valor verdadero / falso o un programa completo que realiza IO.

Reglas:

  • Como se trata de , debe intentar hacerlo en el menor recuento de bytes posible. Las construcciones están permitidas.
  • Se aplican las lagunas de golf estándar: no puede leer los primos de Mersenne de archivos externos ni codificarlos en su programa.
  • Su programa debería funcionar para valores dentro del tamaño entero estándar de su idioma.

Casos de prueba

Como referencia, puede encontrar una lista de los Mimesenne Primes (conocidos) aquí . Algunos casos de prueba útiles son:

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

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

¡Feliz Navidad a todos! Que tengas unas buenas vacaciones, lo que celebres :)


2
Si pudiera, votaría esto como un engaño del desafío isprime , ya que realmente no agrega nada nuevo.
defecto

99
@flawr Son muy similares, pero para este desafío, es menos probable que haya una construcción y hay muchos enfoques interesantes para determinar si un número es representable como2^n-1
FlipTack

1
Creo que la definición de un número de Mersenne también exige que n sea primo (una condición que también se ha demostrado necesaria, pero no suficiente, para que (2 ^ n) -1 sea primo).
SuperJedi224

44
@ SuperJedi224 nsiempre es primo, pero sabiendo que no cambia nada, la definición sigue siendo correcta.
FlipTack

2
@TheBitByte Sí, si está implementando un algoritmo basado en la probabilidad que no funciona el 100% del tiempo, aún puede publicarlo, pero no estaría compitiendo :)
FlipTack

Respuestas:


19

Jalea , 5 bytes

&‘<ÆP

Pruébalo en línea!

Cómo funciona

&‘<Æ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.

El mismo problema que la respuesta de Adnan. Ver mothereff.in/byte-counter
Kelly Lowder

8
@KellyLowder Ese contador de bytes utiliza UTF-8. Tanto Jelly como 05AB1E usan conjuntos de caracteres de un solo byte.
Dennis

24

05AB1E , 5 bytes

Un número positivo en la forma 2 n - 1 en binario solo consta de 1 .

Código:

b`¹pP

Explicación:

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

Utiliza la codificación CP-1252 . Pruébalo en línea! o Verificar todos los casos de prueba .


55
Me preguntaba cuánto tiempo hasta que alguien usara ese truco :)
FlipTack

¹ toma 2 bytes, así que esto es 6.
Kelly Lowder

55
@KellyLowder En UTF-8, sí. Sin embargo, 05AB1E utiliza la codificación CP-1252 en lugar de la codificación UTF-8.
Adnan

10

Python , 45 bytes

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

Pruébalo en línea!

Cómo funciona

Los tres términos de la comparación encadenada

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

Haz lo siguiente:

  • -~n&ncalcula el AND bit a bit de n + 1 y n . Dado que n consiste únicamente en 1 bits si es un número de Mersenne, el AND bit a bit devolverá 0 si (y solo si) este es el caso.

  • all(n%i for i in range(2,n))devuelve True si y solo si n mod i no es cero para todos los valores de i en [2,…, n - 1] , es decir, si y solo si n no tiene divisores positivos aparte de 1 y n .

    En otras palabras, todo devuelve True si y solo si n es un número compuesto, es decir, n es 1 o un primo.

  • n Se explica por sí mismo.

La comparación encadenada devuelve True si y solo si las comparaciones individuales hacen lo mismo.

  • Desde todos los retornos ya sea Verdadero / 1 o Falso / 0 , -~n&n<all(n%i for i in range(2,n))sólo se pueden volver Verdadero si -~n&nlos rendimientos de 0 (es decir, si n es un número Mersenne) y todos los retornos verdadera (es decir, si n sea 1 o un primo).

  • La comparación se all(n%i for i in range(2,n))<nmantiene siempre que n> 1 , pero dado que todo devuelve True si n = 1 , no se cumple en este caso.


1
Wow, eso es increíble :)
ABcDexter

8

Brachylog , 7 bytes

#p+~^h2

Pruébalo en línea!

Un programa Brachylog es básicamente una secuencia de restricciones que forman una cadena: la primera restricción está entre la entrada y un desconocido anónimo (llamémosla A para el propósito de esta discusión), la segunda restricción está entre ese desconocido anónimo y un segundo anónimo desconocido (que llamaremos B ), y así sucesivamente. Como tal, el programa se descompone así:

#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

La única forma en que todas estas restricciones pueden satisfacerse simultáneamente es si B es una potencia de 2, es decir, la entrada es una potencia de 2 menos 1, y la entrada también es primo. (Brachylog usa un solucionador de restricciones internamente, por lo que el programa no será tan ineficiente como parece el orden de evaluación; se dará cuenta de que Ces de la forma [2, Y]antes de intentar expresar Bcomo la exponenciación de dos números).

Curiosamente, #p+~^ casi funciona, porque los primos tipo Mersenne solo pueden usar 2 como base en casos no degenerados ( prueba ), pero a) falla para los primos no Mersenne B -1, ya que pueden expresarse como B ¹, y b ) el intérprete de Brachylog existente parece estar confundido (entrando en un bucle infinito, o al menos de larga duración) por un programa que está tan limitado. Por lo tanto, parece poco probable que 7 bytes sean superados en Brachylog.


I'm impressed! As for the infinite loop problem, this is due to the overloading of predicates. Looking back I think I should not have implemented any overloading for predicates. This also causes problems in things like findall.
Fatalize

7

Mathematica 26 Bytes

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

See this proof

Works so long as there are no odd perfect numbers, and none are known to exist.


So your answer is not proven to be valid?
Jonathan Frech

I do not think that space is necessary.
Jonathan Frech

@JonathanFrech The formula n(n+1)/2 produces (even) perfect numbers whenever n is a Mersenne prime (Euclid). It appears to be unknown whether an odd perfect number can have the form n(n+1)/2, i.e. be a triangular number. All even perfect numbers are triangular where this n is a Mersenne prime (Euler).
Jeppe Stig Nielsen

1
@JeppeStigNielsen The question is if it is valid to use an unknown fact to base one's solution upon.
Jonathan Frech

7

Mathematica, 29 26 bytes

Edit: Saved 3 bytes thanks to Martin Ender

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

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

I suspect this would be faster since the first 42 exponents are hard-coded:

MersennePrimeExponentQ@Log2[#+1]&

6
PrimeQ@#&&1>BitAnd[#,#+1]&
Martin Ender

5

Perl 6, 29 bytes

{.base(2)~~/^1*$/&&.is-prime}

Try it

Expanded:

{             # bare block lambda with implicit parameter 「$_」

  .base(2)    # is its binary representation ( implicit method call on 「$_」 )
   ~~
  /^ 1* $/    # made entirely of 「1」s

  &&          # and

  .is-prime   # is it prime

}

since Perl 6 has arbitrarily large Ints, it doesn't pad the front of .base(2) with 0s.


5

Python, 83 82 79 76 73 bytes

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 bytes

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

This function implements the Lucas–Lehmer primality test, so while it isn't as short as some of the other Python offerings it's much faster at handling huge inputs.


Here's some test code that runs on Python 2 or 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)

output

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, here's a slightly more efficient version of f that doesn't re-test m on every loop:

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

You can write the while loop all on one line (no need for a newline and indent)
FlipTack

@FlipTack D'oh! Thankyou! I really don't know why I missed that... And I just noticed I can shave off a couple more bytes by reverting to Python 2.
PM 2Ring

4

R, 41 40 bytes

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

Oddly enough the builtin in R mersenne takes n as argument, not 2^n-1.

This takes x from STDIN, checks if it is prime using the matlab package and checks if the 2-log of x+1 is a whole number by taking mod 1 and checking for 'not zero-ness'.

Also, if you use the mersenne builtin, it ends up being slightly shorter, but feels like cheating:

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

Saved 1 byte thanks to @Billywob


Posted a similar answer but I deleted it now. May i suggest matlab::isprime to save one byte. Also you have to use <- for in-function assignment.
Billywob

@billywob Just noticed aswell that matlab::isprime was 1 byte shorter. (got a 1 second peak at your solution).
JAD

You can also use log2(x+1) instead log(x+1,2).
Billywob

2

Pyke, 10 bytes

_PQb2+}\1q

Try it here!

_P         -    is_prime(input)
     +     -   ^ + V
  Qb2      -    base_2(input)
      }    -  uniquify(^)
       \1q - ^ == "1"

2

Actually, 9 bytes

;├╔'1=@p*

Try it online!

Explanation:

Since every number of the form 2n-1 has all 1's in its binary representation, a Mersenne prime can be identified as a prime number with that quality.

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

2

Jelly, 5 bytes

Alternate approach to @Dennis' existing 5-byte Jelly answer:

B;ÆPP

Try it online!

How it works:

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

Since a Mersenne Prime is one less than a power of 2, its binary representation is excusively 1's. The output therefor is 1 for Mersenne primes, and 0 in all other cases .


2

Ceylon, 66 bytes

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

Formatted (and commented):

// 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;

With cheating (hardcoding the results in the range of Ceylon's Integer), we can get a byte shorter (65):

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

(It looks like the syntax highlighter misunderstands Ceylon's hex numerals as start-of-comment.)

If an anonymous function is okay, this one is 49 bytes:

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

2

Wolfram Language (Mathematica), 23 bytes

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

Try it online!

1 is handled correctly because PrimeQ[BitAnd[1,1+2]*1] == PrimeQ@1 == False. Otherwise, for BitAnd[#,#+2]# to be prime, we need that # is prime and BitAnd[#,#+2] == 1, which happens when # is a Mersenne number.


Nicely done! As someone who's never used Mathematica, however, your TIO code was confusing at first. Then I realized you're comparing your function against ngenisis's previous tied record holder. I think it'd be better just to show the function's output and maybe have a second link comparing it to the other solution(s).
Deadcode

2

ECMAScript regex, 42 31 bytes

^(?!(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.

Try it online!

Edit: Down to 31 bytes thanks to Neil.

The basic "is a power of 2 minus 1" test is ^(x(x*)(?=\2$))*$. This works by looping the operation "subtract 1, then divide evenly by 2" until it can be done no further, then asserting that the result is zero. This can be modified to match only numbers ≥1 by changing the last * to a +, forcing the loop to iterate at least once. Inserting an x before the last $ further modifies it to match only numbers ≥3 by asserting that the final result after looping at least once is 1.

The related "is a power of 2" test is ^((x+)(?=\2$))*x$. There is also a shorthand for matching powers of 2 minus 2, discovered by Grimy: ^((x+)(?=\2$)x)*$. All three of these regexes are of the same length.

Alternative 31 byte version, by Grimy:

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

Try it online!

# 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
Save 11 bytes by checking directly for a number 1 less than a power of 2: Try it online!
Neil

@Neil Thank you very much! I wish I'd thought of that, but then, this is exactly the kind of thing I wanted to happen!
Deadcode

1
Actually thinking about it would x(x+)(?=\3$) be slightly more efficient?
Neil

Yep, you're absolutely right.
Deadcode

2

Regex (ECMAScript), 29 bytes

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

Try it online!

Inspired by Grimy in chat

The regex asserts that the input is greater than 3, and that it is neither of the form: (xx+)\1+ or ((xx)+)(\1x)+.

The first matches composite numbers.
The second matches a number that is 1 less than a multiple of some odd number greater than 2.

The first will not match prime numbers, or 0 or 1.
The second will not match numbers of the form 2n1, or numbers that are 1 less than an odd prime.

Since 2 is the only prime that is 1 less than an odd prime, the negative lookahead, together with the assertion that the input is greater than 3, will match only mersenne primes.


1

Ruby, 47 bytes

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


1

Python, 65 bytes

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

Outputs via Exit Code. Recursion Error for False. No error for True.

How it works

Since 2^n-1 in binary is made entirely from 1's, the next 2^n-1 number can be generated by number|number+1.

This function uses this by recursively going through each 2^n-1number checking to see if it's a prime number and eqaul to the input. If the number is not a mersenne prime, python will eventually throw an error as the maximum recursion depth would have been exceeded.


1
If I am not mistaken, <0 ~> 0>.
Jonathan Frech

1

Pushy, 7 bytes

oBoIpP#

Try it online!

This takes advantage of the fact that mersenne numbers have only ones in their binary representation:

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

The stack product will only be 1 if the number has no zeroes in its binary representation, and its primality is True.


1

Pyth, 8 bytes

&.AjQ2P_

Verify all the test cases.

Pyth, 8 bytes

<.&QhQP_

Verify all the test cases.


How?

Code Breakdown #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.

How does that work?

A number of the form 2n - 1 always contains 1 only when written in binary. Hence, we test if all its binary digits are 1 and if it is prime.

Code Breakdown #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.

How does that work?

This tests if the input + 1 is a power of two (i.e. if it is a Mersenne number), and then performs the primality test. In Python, bool is a subclass of int, so truthy is treated as 1 and falsy is treated as 0. To avoid checking explicitly that one is 0 and the other is 1, we compare their values using < (since we only have 1 such case).


1

Java 8, 53 52 49 bytes

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

Bug-fixed and golfed by 4 bytes thanks to @Nevay.

Explanation:

Try it here.

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

The current solution returns true for every prime >2, not only for Mersenne primes, 56 bytes: n->{for(int i=2;i<n;n&=-n%i++>>-1);return(n&n+1)<1&n>2;}
Nevay

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

@Nevay Thanks.. And not sure why the test cases didn't include any primes that aren't mersenne primes.. Added them myself, and you were indeed right.
Kevin Cruijssen

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

1

Python 3, 68 bytes

a=int(input());print(a&-~a<1and a>1and all(a%b for b in range(2,a)))

Try it here

Python 2, 63 bytes

a=input();print(a&-~a<1)and a>1and all(a%b for b in range(2,a))

Try it here


Thanks for suggestion Jonathan


Open to any suggestions for reducing the bytecount.


1
1 and ~> 1and.
Jonathan Frech


0

Python, 93 Bytes

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

This code would work in both Python 2 and Python 3 so I have not specified a version.


0

Racket 76 bytes

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

Ungolfed:

(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))

Testing:

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

Output:

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

0

PHP, 53 bytes

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

takes command line argument; prints 1 for Mersenne prime, empty string else. Run with -r.

breakdown

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 bytes

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;}

Returns 1 if the number is a Mersenne Prime, 0 otherwise.


Suggest ~x+g(2,n) instead of x^g(2,n)-1
ceilingcat

0

Scala, 59 Bytes

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

This function requires the input to be a BigInt. You can easily convert a string "162259276829213363391578010288127" (2**107-1 is a Mersenne prime) into BigInt by doing BigInt("162259276829213363391578010288127"). It might go wrong as the name of isProbablePrime() method suggests. But the probability is not more than 0.5^(t.bigLength)*9.

Standalone script version is 72 bytes long.

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

Assume we save it as "t.scala", then then program can be run as

>scala t.scala 162259276829213363391578010288127
>true

You can remove the Probable from isProbablePrime if Scala has an isPrime function.
MilkyWay90

0

Perl 5, 53 bytes

52 bytes of code + 1 for -p

$f=0|sqrt;1while$_%$f--;$_=!$f*(sprintf'%b',$_)!~/0/

Try it online!


According to meta consensus, the -p is classified as another programming language, and hence doesn't count in your bytecount.
MilkyWay90
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.