El programa que encontrará el próximo número primo

15

Introducción:


Accidentalmente corrompiste el flujo del tiempo con un dispositivo que hiciste por diversión, que resultó ser una máquina del tiempo. Como resultado, te empujaron al futuro lejano. Te diste cuenta de que la informática, la potencia de procesamiento y las computadoras en general han evolucionado en gran medida, una cantidad infinita para ser precisos . Entonces, se toma una computadora con memoria infinita y potencia de procesamiento. No tienes idea de cómo puede tener memoria infinita y poder de procesamiento infinito, pero simplemente lo aceptas y regresas al presente.

Desafío:


Escuchaste que la persona que descubrió la prima más grande en la actualidad 2^74,207,281 − 1recibió $ 100,000. Decide hacer un programa que encuentre la próxima prima, ya que desea recuperar el dinero que gastó en la computadora. Haces uno que toma la entrada de un número y encuentra el siguiente número primo, ya sea por fuerza bruta o por cualquier otro método.

Aclaraciones: tiene una máquina hipotética con memoria infinita y potencia de procesamiento. Su programa NO DEBE estar limitado (por ejemplo: los int. De C # pueden almacenar de -2,147,483,648a 2,147,483,647), bueno, su programa debe poder almacenar y trabajar con cualquier número de cualquier tamaño. Tiene recursos infinitos, por lo que no debería importarle si se quedaría sin memoria si lo permitiera.

Ejemplo de E / S:
Entrada: El primo descubierto más grande actualmente con 22,338,618 dígitos.
Salida: exactamente la próxima prima

Obviamente, no tiene que demostrar que funciona, ya que tomaría mucho tiempo calcularlo en una máquina física. Pero si movió su programa a una máquina hipotética con capacidad / memoria de procesamiento infinito, debería computar al instante.


Encontrar el próximo primo y verificar si un número es primo son dos cosas completamente diferentes

P. Ktinos
fuente
1
¿Tiene que ser específicamente el próximo prime ? Muchos algoritmos de búsqueda de números primos para números primos grandes solo buscan ciertos tipos de números y, por lo tanto, a veces pierden números primos ...
FlipTack
10
Creo que deberías agregar algunos casos de prueba serios.
FlipTack
3
" Su programa NO DEBE estar limitado ", pero sobre la base del ejemplo sospecho que cada idioma existente cuenta como limitado si no cabe otra razón que no sea el uso de un tipo finito para direccionar la memoria.
Peter Taylor el
1
Posible duplicado de ¿Es este número primo?
Post Rock Garf Hunter
2
@ mbomb007 ¿por qué? Todas las respuestas, excepto las integradas, solo agregan un contenedor adicional.
Post Rock Garf Hunter

Respuestas:

22

Mathematica, 9 bytes

NextPrime
Greg Martin
fuente
... ¿Esto realmente funciona?
wizzwizz4
12
Por supuesto, Mathematica siempre tiene una función incorporada
JungHwan Min
@ wizzwizz4, seguro, ¡pruébalo en línea!
Pavel
8

Python 3 , 45 bytes

f=lambda n,k=1,m=1:m%k*k>n or-~f(n,k+1,m*k*k)

Pruébalo en línea!

Dennis
fuente
3
Creo que este es el teorema de Wilson disfrazado. kes igual al resultado final, mcontiene (k-1)!^2. ¡Desde (k-1)! = -1 mod k solo se cumple cuando k es primo, ¡tenemos (k-1)! (K-1)! = 1 mod k, que cuando se multiplica por k será k mismo. ¡Calcula el cuadrado para deshacerse de la única excepción de (k-1)! = 0 mod k para k compuesto, que ocurre para k = 4. ¿Correcto?
orlp
Si, eso es correcto.
Dennis
Esto arroja RecursionError: maximum recursion depth exceeded in comparisonparaf(1000)
ovs
55
@ovs La pregunta dice que tenemos memoria infinita. Por lo tanto, podemos asumir un límite de profundidad de recursión infinitamente alto y, por lo tanto, no preocuparnos RecursionError.
FlipTack
6

Python 2, 78 77 76 74 bytes

def f(n):
 while 1:
    n+=1
    if[i for i in range(1,n)if n%i<1]==[1]:return n

-1 byte gracias a @KritixiLithos
-1 byte gracias a @FlipTack
-2 bytes gracias a @ElPedro

ovs
fuente
n%i<1es más corto quen%i==0
Kritixi Lithos
No necesita espacios en blanco después de eso if.
FlipTack
Creo que te refieres<1
Jonathan Allan
Creo que puede usar una pestaña en lugar de 2 espacios para las sangrías de segundo nivel, pero no puedo probar en este momento.
ElPedro
1
@ElPedro tiene razón. Puede cambiar los 2 espacios en frente n+=1y ifen pestañas y guardar 2 bytes
5

Jalea , 2 bytes

Æn

Pruébalo en línea!

Esto toma implícitamente la entrada z y, de acuerdo con el manual, genera la prima más cercana estrictamente mayor que z.

Steenbergh
fuente
4

Bash + coreutils, 52 bytes

for((n=$1,n++;`factor $n|wc -w`-2;n++)){ :;};echo $n

Pruébalo en línea!

La documentación para bash y factor no especifica un valor entero máximo que puedan manejar (aunque, en la práctica, cada implementación tiene un valor entero máximo). Presumiblemente, en el GNU del futuro en sus máquinas infinitamente grandes, bash y factor tendrán enteros de tamaño ilimitado.

Mitchell Spector
fuente
En realidad, los documentos especifican por factor que si se construye sin gnu mp solo se admite precisión simple.
Dani_l
1
@Dani_l Bueno, la entrada man para bash solo dice: "La evaluación se realiza en enteros de ancho fijo sin verificación de desbordamiento, aunque la división por 0 está atrapada y marcada como un error". No especifica el ancho. (Como recuerdo, las implementaciones de stock de bash en mis máquinas usan enteros con signo de 64 bits, pero no puedo verificarlo ahora). En cuanto al factor, seguramente se actualizará: las futuras computadoras del OP con infinitos recursos tendrán factor compilado con gnu_up para obtener precisión ilimitada :).
Mitchell Spector
3

Máximo, 10 bytes

next_prime

Una función devuelve el primo más pequeño más grande que su argumento.

rahnema1
fuente
3

Brachylog , 2 bytes

<ṗ

Pruébalo en línea!

Explicación

(?) <   (.)      Input < Output
      ṗ (.)      Output is prime
                 (Implicit labelization of the Output at the end of the predicate)
Fatalizar
fuente
3

Python con sympy, 28 bytes

import sympy
sympy.nextprime

sympy.nextprimees una función que hace lo que dice en la lata. Funciona para todas las carrozas.

repl.it


Python, 66 59 bytes

-4 bytes gracias a Lynn (uso -~)
-3 bytes gracias a FlipTack (uso andy or, permitiendo ...==1cambiar a una ...-1condición).

f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n

repl.it

Una función recursiva que cuenta hasta que nse encuentra un primo al probar que solo existe un número hastan-1 que lo divide (es decir, 1). Funciona para todos los enteros, genera un error para las carrozas.

Funciona en 2.7.8 y 3.5.2, no funciona en 3.3.3 (error de sintaxis debido a la falta de espacio entre ==1y else)

Jonathan Allan
fuente
(n+1)%(i+1)es -~n%-~i, creo.
Lynn
Es, gracias ... Estaba tratando de hacer uno más corto usando el teorema de Wilson.
Jonathan Allan
¿Cortocircuito and/ ortrabajo, como f=lambda n:sum(-~n%-~i<1for i in range(n))==1and-~n or f(n+1)?
FlipTack
De hecho, eso ^ se puede jugar a f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n
golf
@FlipTack Originalmente los evité para que pudiera pasar por cero, pero funcionará, ¡eso es un ahorro de tres bytes!
Jonathan Allan
2

Python, 114 83 bytes

def g(b):
 while 1:
  b+=1
  for i in range(2,b):
   if b%i<1:break
  else:return b

Sin incorporaciones, si las hay.

-30 eliminando espacios en blanco y -1 cambiando b%i==0ab%i<1

sagiksp
fuente
3
Esto no encontrará el próximo prime si 1
ingresas
Ahora se supone que b> 2
sagiksp
No puedes inventar tus propias reglas ... debes seguir las especificaciones del desafío. En ninguna parte dice que puede asumir los límites de la entrada.
FlipTack
Incluso con esa suposición, esto falla para todas las entradas de valor par.
FlipTack
Soy un idiota, lo leí mal. Arreglado. @FlipTack
sagiksp
2

Perl 6 , 25 bytes

{first *.is-prime,$_^..*}

Cómo funciona

{                       }  # A lambda.
                  $_ ..*   # Range from the lambda argument to infinity,
                    ^      # not including the start point.
 first           ,         # Iterate the range and return the first number which
       *.is-prime          # is prime.

Perl 6 , 32 bytes

{first {all $_ X%2..^$_},$_^..*}

Con ineficaces pruebas de primalidad personalizadas.

Cómo funciona

La estructura externa es la misma que la anterior, pero el predicado pasado a first(para decidir si un número dado es primo), ahora es:

{               }  # A lambda.
     $_            # Lambda argument (number to be tested).
          2..^$_   # Range from 2 to the argument, excluding the end-point.
        X          # Cartesian product of the two,
         %         # with the modulo operator applied to each pair.
 all               # Return True if all the modulo results are truthy (i.e. non-0).
smls
fuente
Esperaba obtener algo más corto con Perl 5, pero es difícil vencer a un incorporado .is-prime;)
Zaid
2

Pyke, 8 7 bytes

~p#Q>)h

Pruébalo aquí!

4 bytes, sin competencia

(Intérprete actualizado desde el desafío publicado)

~p<h

Pruébalo aquí!

~p   -   primes_iterator()
  <  -  filter(^, input() < i)
   h - ^[0]
Azul
fuente
¿Por qué el segundo no compite? No entiendo lo suficiente.
theonlygusti
@theonlygusti: por lo general, la única razón legítima para marcar un envío no competitivo aquí (en lugar de no enviarlo en absoluto) es porque solucionó un error o agregó una función en el idioma en que está escrito el programa, y ​​eso lo ayudó con el desafío . (Tiendo a escribirlo como "desafío de
@theonlygusti aclaró
Azul
1

J, 4 bytes

4&p:

Simple incorporado para el próximo prime.

Conor O'Brien
fuente
1

05AB1E , 16 13 bytes (Emigna @ -3 bytes)

2•7£?ÿ•o[>Dp#

Pruébalo en línea!

2•7£?ÿ•o        # Push current largest prime.
        [   #    # Until true..
         >Dp    # Increment by 1, store, check primality.
                # After infinite loop, implicitly return next prime.
Urna de pulpo mágico
fuente
No [>Dp#funcionaria?
Emigna
Todavía puede cortar 8 bytes más, ya que el programa debe tomar una prima como entrada y salida de la próxima prima.
Emigna
@Emigna, entonces esta pregunta es un duplicado.
Urna mágica del pulpo
Eso es probable sí.
Emigna
1

Perl, 30 bytes (29 +1 para -p):

(1x++$_)=~/^(11+?)\1+$/&&redo

Uso

Ingrese el número después de presionar Retorno (ingrese 12345 en el ejemplo a continuación, salidas 12347):

$ perl -pe '(1x++$_)=~/^(11+?)\1+$/&&redo'
12345
12347

Cómo funciona

  • Defina una cadena de 1's que tenga longitud ++$_, donde $_inicialmente es el valor de entrada
  • La expresión regular verifica si la cadena de 1s es de longitud no principal (explicado aquí ).
  • Si la longitud de la cadena no es primo, la verificación se vuelve a evaluar para el siguiente entero ( ++$_)
  • Si la longitud de la cadena es primo, el whilebucle implícito sale e -pimprime el valor de$_
  • Nota: no es necesario manejar el caso "1"de borde de longitud 1 porque nunca se usará para valores menores que 1, según la especificación.
Zaid
fuente
1

Java 7, 373 343 334 303 268 bytes

import java.math.*;class M{public static void main(String[]a){BigInteger n,i,o,r=new BigInteger(a[0]);for(r=r.add(o=r.ONE);;r=r.add(o)){for(n=r,i=o.add(o);i.compareTo(n)<0;n=n.mod(i).compareTo(o)<0?r.ZERO:n,i=i.add(o));if(n.compareTo(o)>0)break;}System.out.print(r);}}

-75 bytes gracias @Poke

Sin golf:

import java.math.*;
class M{
  public static void main(String[] a){
    BigInteger n,
               i,
               o,
               r = new BigInteger(a[0]);
    for(r = r.add(o = r.ONE); ; r = r.add(o)){
      for(n = r, i = o.add(o); i.compareTo(n) < 0; n = n.mod(i).compareTo(o)< 0
                                                        ? r.ZERO
                                                        : n,
                                                   i = i.add(o));
      if(n.compareTo(o) > 0){
        break;
      }
    }
    System.out.print(r);
  }
}

Pruébalo aquí.

Algunos ejemplos de entradas / salidas:

7 -> 11
1609 -> 1613
104723 -> 104729
Kevin Cruijssen
fuente
@Poke He jugado otros 31 bytes agregando staticpara el campo y el método p, pero eliminando el método cy pel parámetro.
Kevin Cruijssen 01 de
0

QBIC , 34 bytes

:{a=a+1[2,a/2|~a%b=0|b=a]]~a<b|_Xa

Basado en este probador de primalidad QBIC . Explicación:

:{a=a+1    Read 'a' from the command line, start an infinite loop 
           and at the start of each iteration increment 'a'
[2,a/2|    FOR b = 2, b <= a/2, b++
~a%b=0|    IF b cleanly divides a, we're no prime
b=a]]      so, break out of the FOR loop ( ]] = End if, NEXT )
~a<b|      If the FOR loop completed without breaking
_Xa        then quit, printing the currently tested (prime) number
           The second IF and the DO-loop are implicitly closed by QBIC.
Steenbergh
fuente
0

JavaScript (ES7), 61 bytes

a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}

Uso

f=a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}
f(2)

Salida

3
Luke
fuente
Bien, pero no creo que esto funcione, ya que JavaScript en sí mismo (no la computadora) perderá precisión después de solo 2 ^ 53.
ETHproductions
Tiene razón, pero no creo que se pueda evitar ese límite, incluso si dividimos el número en porciones de 32 bits en una matriz, porque eventualmente, el número debe procesarse en su conjunto. Si tiene una idea sobre cómo resolver esto, hágamelo saber.
Lucas
1
Hay bibliotecas JS para matemática de precisión arbitraria, incluso construí una en algún momento, así que estoy seguro de que es posible. Iré la próxima vez que esté en mi computadora
ETHproductions
Busqué en Google y parece interesante. También tendré una oportunidad.
Lucas
0

MATL, 3 bytes

_Yq 

La función Yqdevuelve el próximo primo del valor absoluto de la entrada si la entrada es negativa, por lo que implícitamente tomamos la entrada, la negamos ( _) y encontramos el siguiente primo usando Yq.

Pruébalo en línea!

Suever
fuente
0

Haskell, 42 46 43 bytes

f n=[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1

El código habitual para la fuerza bruta.

Por supuesto, esto encuentra el siguiente número primo más pequeño después den . No hay mayor prima.

Funciona para n > 0 .

editar: Asume que nes primo. Gracias al consejo de @Laikoni en los comentarios .

Will Ness
fuente
Puede guardar un byte reemplazándolo head[...]con [...]!!0. Sin embargo, creo que se puede suponer que nes primo, por lo que puede usar en [n..]lugar de [n+1..]y luego tomar el segundo elemento con [...]!!1.
Laikoni
0

SimpleTemplate, 132 bytes

El algoritmo es terrible, ya que tengo que hacer mi propio código para verificar si un número es primo o no.
Resultó ser horrible, pero funciona.

{@setY argv.0}{@setX 1}{@whileX}{@setX}{@set+T Y,-1}{@for_ from2 toT}{@ifY is multiple_}{@incX}{@/}{@/}{@ifX}{@incY}{@/}{@/}{@echoY}

Recibe el número como primer argumento, generando el resultado.


Sin golf:

{@set number argv.0}
{@set remainder 1}
{@while remainder}
    {@set remainder 0}
    {@set+ tmp number, -1}
    {@for divisor from 2 to tmp}
        {@if number is multiple divisor}
            {@inc by 1 remainder}
        {@/}
    {@/}
    {@if remainder}
        {@inc by 1 number}
    {@/}
{@/}
{@echo number}

¿Algún consejo sobre cómo eliminar eso último @if?

Ismael Miguel
fuente
0

Lua, 876 bytes

function I(a)a.s=a.s:gsub("(%d)(9*)$",function(n,k)return tostring(tonumber(n)+1)..("0"):rep(#k)end)end function D(a)a.s=a.s:gsub("(%d)(0*)$",function(n,k)return tostring(tonumber(n)-1)..("9"):rep(#k)end):gsub("^0+(%d)","%1")end function m(a,b)local A=K(a)local B=K(b)while V(0,B)do D(A)D(B)end return A end function M(a,b)local A=K(a)local B=K(b)while V(m(B,1),A)do A=m(A,B)end return A end function l(n)return#n.s end function p(a)local A=K(a)local i=K(2)while V(i,A)do if V(M(A,i),1)then return false end I(i)end return true end function V(b,a)A=K(a)B=K(b)if l(A)>l(B)then return true end if l(B)>l(A)then return false end for i=1,l(A)do c=A.s:sub(i,i)j=B.s:sub(i,i)if c>j then return true elseif c<j then return false end end return false end function K(n)if(type(n)=='table')then return{s=n.s}end return{s=tostring(n)}end P=K(io.read("*n"))repeat I(P)until p(P)print(P.s)

Lua, a diferencia de otros idiomas, tiene un tamaño entero máximo. Una vez que un número sea mayor que 2 32 , las cosas dejan de funcionar correctamente y Lua comienza a intentar hacer estimaciones en lugar de valores exactos.

Como tal, tuve que implementar un nuevo método para almacenar números, en particular, los almacené como cadenas Base10, porque Lua no tiene un límite de tamaño en las cadenas, que no sea el tamaño de la memoria.

Siento que esta respuesta es mucho más al espíritu de la pregunta, ya que tiene que implementar enteros de precisión arbitrarios, así como una prueba principal.

Explicado

-- String Math
_num = {}

_num.__index = _num

-- Increase a by one.
-- This works by grabbing ([0-9])999...$ from the string.
-- Then, increases the first digit in that match, and changes all the nines to zero.
-- "13", only the "3" is matched, and it increases to 1.
-- "19", firstly the 1 is turned to a 2, and then the 9 is changed to a 0.
-- "9" however, the 9 is the last digit matched, so it changes to "10"
function _num.inc(a)
    a.str = a.str:gsub("(%d)(9*)$",function(num,nines)
            return tostring(tonumber(num)+1)..("0"):rep(#nines)
        end)
end


-- Decrease a by one
-- Much like inc, however, uses ([0-9])0...$ instead.
-- Decrements ([0-9]) by one and sets 0... to 9...
-- "13" only the "3" is matched, and it decreases by one.
-- "10", the "1" is matched by the ([0-9]), and the 0 is matched by the 0..., which gives 09, which is clipped to 9.
function _num.dec(a)
    a.str = a.str:gsub("(%d)(0*)$",function(num,zeros)
        return tostring(tonumber(num)-1)..("9"):rep(#zeros)
    end)         :gsub("^0+(%d)","%1")
end

-- Adds a and b
-- Makes A and B, so that the original values aren't modified.
-- B is then decremented until it hits 0, and A is incremented.
-- A is then returned.
function _num.__add(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:inc()
        B:dec()
    end
    return A
end

-- Subs b from a
-- Works just like Addition, yet Dec's A instead of Incs.
function _num.__sub(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:dec()
        B:dec()
    end
    return A
end

-- A % B
-- Makes A and B from a and b
-- Constantly subtracts B from A until A is less than B
function _num.__mod(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while A >= B do
        A = A - B
    end
    return A
end

-- #a
-- Useful for golfiness
function _num.__len(n)
    return #n.str
end

-- Primacy Testing
-- Generates A from a and i from 2.
-- Whilst i is less than A, i is incremented by one, and if A % i == 0, then it's not a prime, and we return false.
-- Once that finishes, we return true.
function _num.isprime(a)
    local A = str_num(a)
    local i = str_num(2)
    while i < A do
        if A%i < 1 then
            return false
        end
        i:inc()
    end
    return true
end

-- b < a
-- A and B are generated from a and b
-- Fristly, if the length of A and B aren't equal, then that result is output.
-- Otherwise, each character is searched from left to right, the moment they are unequal, the difference is output.
-- If all the characters match, then it's equal. Return false.
function _num.__lt(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return false
end


-- b <= a
-- Same as b < a, but returns true on equality.
function _num.__le(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return true
end

-- Just straight up returns it's string component. Endlessly faster than the int equivalent, mostly because it never is anything _but_ the string form.
function _num.__tostring(a)
    return a.str
end

-- Just set up the metatable...
function str_num(n)
    if(type(n)=='table')then
        return setmetatable({str = n.str}, _num)
    end
    return setmetatable({str = tostring(n)}, _num)
end

-- Generate a new str_num from STDIN
Prime = str_num(io.read("*n"))

-- This is handy, because it will call Prime:inc() atleast once, and stop at the next prime number it finds.
-- Basically, if it weren't for all that overhead of making the math possible, that's all this would be.
repeat
    Prime:inc()
until Prime:isprime()
print(Prime)

Aunque lo anterior usa Metatables, en lugar de solo funciones regulares como la respuesta real, que resultó más pequeña.

Un taco
fuente
0

Rubí, 28 + 6 = 34 bytes

Usa la -rprimebandera.

f=->i{i+=1;i.prime??i :f[i]}

Versión no recursiva para 31 + 6 = 37 bytes:

->i{i+=1;i+=1 while i.prime?;i}
Tinta de valor
fuente
0

Python + primefac , 34 32 bytes

No es tan corto como usar sympy(otra respuesta ya lo usa), pero sigue siendo bastante corto y es mucho más rápido.

import primefac as p
p.nextprime

Pruébalo en línea

La entrada de 2**2000completa en un par de segundos.

mbomb007
fuente