Calcular brechas primas

19

Encontrar primos es un rito de paso de programación y, con mucha frecuencia, un primer programa serio que alguien crea (generalmente con división de prueba).

Pero los primos solos ya están desgastados. Una próxima cosa mucho más interesante es obtener las brechas principales: las brechas hasta ahora más largas entre primos consecutivos. Estos son bastante raros y "preciosos". Los primeros pares y sus diferencias son:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
...

Mi padre solía calcularlos a mano para divertirse hasta 10k. Veamos qué tan corto puede ser un código.

Reglas:

  • sin funciones integradas para pruebas principales, generación primaria o brechas principales
  • no recuperar http://oeis.org/A002386 o similar (puedo oler a tramposos desde muy lejos :))
  • sin matrices precalculadas
  • siga imprimiendo hasta que su tipo entero interno le falle

El conteo de personajes más bajo gana. +10 caracteres si solo imprime los espacios sin los números primos.

También puede mostrar versiones con funciones integradas si son interesantes. Ser creativo.

Aclaración: revisa los números primos e informa cada vez que ve una brecha que es más grande que cualquier brecha que haya visto antes. Por ejemplo, entre 3 y 5, hay un espacio de 2 unidades de ancho. La brecha entre 5 y 7 también es 2, pero esa es una noticia vieja, ya no nos importa. Solo cuando ve una nueva brecha más grande, la informa. Esto refleja cómo los números primos son cada vez menos frecuentes, a medida que las brechas se hacen cada vez más amplias.


EDITAR : La mayoría de las respuestas son brillantes y merecen más reconocimiento. Sin embargo, hasta ahora, una entrada de GolfScript con 48 caracteres es la más corta.

Orión
fuente
1
En su ejemplo, 3 es el final de un par y el comienzo del siguiente par, mientras que este no es el caso para otros números. ¿Qué deseas?
mmumboss
No importa, lo tengo ahora.
mmumboss
Es posible que desee volver a escribir su regla como "no hay funciones integradas para la prueba principal, el cálculo de la prima o las lagunas principales". De lo contrario, una solución obvia sería utilizar una función que devuelve el n º primo, entonces la subasta n , ejecutar de nuevo la función y encontrar la diferencia.
user12205
2
Aww. me encanta OEIS
TheDoctor
Tengo la misma duda que @mmumboss. ¿Podría por favor xplain?
Clyde Lobo

Respuestas:

3

GolfScript 66 59 57 49 48

[2.0{:d{;\;.{).{(1$1$%}do(}do.2$-.d>!}do].p~.}do

Aunque tengo problemas para ejecutarlo aquí http://golfscript.apphb.com/ (¿tal vez a ese sitio no le gusta el bucle infinito?) Pero funciona bien cuando lo ejecuto en mi computadora con golfscript.rb. Soy bastante nuevo en GolfScript, por lo que probablemente esto pueda reducirse aún más. ACTUALIZACIÓN: No creo que esto pueda reducirse mucho más sin cambiar el algoritmo de alguna manera.

Primeras pocas líneas impresas (si no le gusta el "" que se está imprimiendo, puede agregarlo; al comienzo del guión, pero eso lo sube a 49 caracteres):

[2 3 1]
["" 3 5 2]
["" 7 11 4]
["" 23 29 6]
["" 89 97 8]
["" 113 127 14]
["" 523 541 18]
["" 887 907 20]
["" 1129 1151 22]
...

Idea general legible por humanos de cómo funciona esto (algunas cosas ligeramente diferentes ya que no estoy usando una pila en esta versión):

cur_prime = 2
next_prime = 2
gap = 0        

do {
    do {
        cur_prime = next_prime
        do {
            next_prime = next_prime + 1
            possible_factor = next_prime
            do {
                possible_factor = possible_factor - 1
            } while (next_prime % possible_factor > 0)
        } while (possible_factor != 1)
    } while (next_prime - cur_prime <= gap)

    gap = next_prime - cur_prime
    print [cur_prime next_prime gap]
} while (true)
SamYonnou
fuente
11

Python, 121 110 109 108 104 103 caracteres

p,n,m=[2],3,0
while 1:
 if all(n%x for x in p):
  c=n-p[0]
  if m<c:m=c;print(p[0],n,c)
  p=[n]+p
 n+=1

La primera vez que traté de responder aquí, espero haberlo hecho bien ... no estoy seguro de haber contado bien los caracteres.

Hmmm, podría guardar otro personaje en la impresión bajando a Python 2.x ...

Tal
fuente
121 caracteres, haga que el título sea un título #, en serio no cuenta los caracteres a mano, ¿verdad? javascriptkit.com/script/script2/charcount.shtml
user80551
No, no conté a mano :) Pero he visto otras respuestas de Python a algunas preguntas aplanadas en una línea de una manera que reduce el espacio en blanco, y, francamente, no estoy seguro de si una nueva línea se cuenta como 1 o 2 caracteres ...
Tal
1
Contamos las nuevas líneas como 1 carácter a menos que las reglas de la pregunta indiquen explícitamente lo contrario. Bienvenido a PPCG!
Jonathan Van Matre
3
¡Bienvenido! Buena respuesta, y también tiene margen de mejora. Por ejemplo, if all(n%x>0for x in p):es un poco más corto. También puede guardar algunos caracteres moviendo las declaraciones en la misma línea (por ejemplo a=1;b=2;f()).
grc
1
El último cambio rompió el código al no empujar [n] al frente como se indicó.
orion
4

JavaScript, 90 85 78 74 caracteres

Código corto (compilador de cierre de Google: optimizaciones avanzadas; algunas ediciones manuales; más ediciones de @ MT0 )

for(a=b=2,c=0;b++;)for(d=b;b%--d;)d<3&&(c<b-a&&console.log(a,b,c=b-a),a=b)

Código largo

var lastPrime = 2,
    curNumber = lastPrime,
    maxDistance = 0,
    i;

// check all numbers
while( curNumber++ ) {

  // check for primes
  i = curNumber;
  while( curNumber % --i != 0 ) {}

  // if prime, then i should be equal to one here
  if( i == 1 ) {

    // calc distance
    i=curNumber-lastPrime;

    // new hit
    if( maxDistance < i ) {
      maxDistance = i;
      console.log( lastPrime, curNumber, maxDistance );
    }

    // remember prime
    lastPrime = curNumber;
  }
}

Salida

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52
31397 31469 72
...

Prueba bastante ineficiente para números primos, pero de esa manera usa menos caracteres.

Primero publique aquí, así que disculpe cualquier error.

Sirko
fuente
78 Personajes -for(a=b=2,c=0;b++;){for(d=b;b%--d;);1==d&&(c<b-a&&console.log(a,b,c=b-a),a=b)}
MT0
@ MT0 Gracias. No los vi. Editado
Sirko
Aún más ineficiente pero 74 caracteres -for(a=b=2,c=0;b++;)for(d=b;b%--d;)d<3&&(c<b-a&&console.log(a,b,c=b-a),a=b)
MT0
3

Mathematica, 114 108

Permite una salida infinita, aunque después de un cierto punto en la secuencia, el ventilador gira y comienza a sospechar que su CPU está jugando Freecell mientras hace todo lo posible para parecer ocupado.

p@x_:=NestWhile[#+1&,x+1,Divisors@#≠{1,#}&];m=0;q=1;While[1<2,If[p@q-q>m,Print@{q,p@q,p@q-q};m=p@q-q];q=p@q]

Muestra de salida (Estas son las que recoge en los primeros 30 segundos):

{1,2,1}
{3,5,2}
{7,11,4}
{23,29,6}
{89,97,8}
{113,127,14}
{523,541,18}
{887,907,20}
{1129,1151,22}
{1327,1361,34}
{9551,9587,36}
{15683,15727,44}
{19609,19661,52}
{31397,31469,72}
{155921,156007,86}
{360653,360749,96}
{370261,370373,112}
{492113,492227,114}
{1349533,1349651,118}
{1357201,1357333,132}
{2010733,2010881,148}

Código sin golf:

p@x_ := NestWhile[
   # + 1 &,
   x + 1,
   Divisors@# ≠ {1, #} &];
m = 0;
q = 1;
While[
 1 < 2,
 If[
  p@q - q > m,
  Print@{q, p@q, p@q - q}; m = p@q - q];
 q = p@q]
Jonathan Van Matre
fuente
¿Lo reconoce ?
Riking
Sí, simplemente no se exporta de esa manera, pero lo analizará bien cuando pegue el código en el cuaderno. Ya lo he puntuado en consecuencia, pero lo revisaré para simplificar.
Jonathan Van Matre
el número de caracteres si se hace uso de Mathematica funciones integradas Prime?
Michael Stern
76. Dado que toda la definición de p @ x_ es solo una reimplementación de NextPrime, se puede reemplazar por p = NextPrime;
Jonathan Van Matre
3

Haskell - 122 116 114 112 110

q=[n|n<-[3..],all((>0).rem n)[2..n-1]]
d m((p,q):b)|q-p>m=print(p,q,q-p)>>d(q-p)b|q>p=d m b
main=d 0$zip(2:q)q

Expresión de lista principal (ineficiente) robada de Will Ness .

-editar- Nunca supe x|y=z|w=qque sería válido.

Rimoide
fuente
2

MATLAB 104 89

Acaba de implementar el método básico marcando cada división posible.

a=2;g=0;for n=3:inf;b=n*(sum(mod(n,1:n)<1)<3);h=b-a;if(h>g)g=h;[a,b,h]
end;a=max(a,b);end

Salida:

  2     3     1
  3     5     2
  7    11     4
 23    29     6
 89    97     8
113   127    14
523   541    18
887   907    20
mmumboss
fuente
Estoy encendido octavey esto infno funciona (y la impresión se difiere hasta que finaliza el bucle). ¿Matlab tiene evaluación de rango diferido?
orion
Matlab imprime en tiempo real, cada iteración del bucle. Cuando inicio mi programa, recibo una advertencia de que el índice máximo es 2147483647, y luego se inicia. Alternativamente, podría reemplazar inf con intmax, pero eso es tres caracteres más.
mmumboss
2

76 caracteres, dogelang

Convertido de mi versión de Python :

g=0
i=l=2
while i+=1=>all$map(i%)(2..i)=>(i-l>g=>(g=i-l),print(l,i,g)),(l=i)

Salida:

(2, 3, 1)
(3, 5, 2)
(7, 11, 4)
(23, 29, 6)
(89, 97, 8)
(113, 127, 14)
(523, 541, 18)
(887, 907, 20)
(1129, 1151, 22)
...
Claudiu
fuente
¡Debe ser seleccionado como el ganador!
Sarge Borsch
2

Golfscript, 59 51 50 caracteres

Hombre, cada personaje es extremadamente difícil de perder:

0[2.{).,2>{\.@%!},{.2$-.4$>{].p~\[}{;\;}if..}or}do

Salida :

[2 3 1]
[3 5 2]
[7 11 4]
[23 29 6]
[89 97 8]
[113 127 14]
...

Explicacion :

La pila está configurada para que cada iteración comience con la pila de esta manera, la parte superior a la derecha. El [indica que el actual marcador de matriz, es decir, cuando el intérprete se encuentra con una ], todo en la pila desde la marca hasta la parte superior se pone en una matriz.

g [ last | cur

ges la brecha máxima hasta ahora. De arriba para abajo:

 command         | explanation
-----------------+----------------------------------------
 0[2.            | initialize vars g=0, last=2, cur=2
 {...}do         | loop forever...

Dentro del bucle:

 )               | cur += 1
 .,2>{\.@%!},    | put all divisors of cur into a list
 {...}or         | if the list is empty, cur is prime, so
                 | the block is executed. otherwise,
                 | 'do' consumes the stack, sees it is truthy,
                 | and loops again

¿Cómo pone todos los divisores en una lista? Hagámoslo paso a paso

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack                                | n
 .,              | make list of 0..n-1                          | n [0,1,...,n-1]
 2>              | take elements at index 2 and greater         | n [2,3,...,n-1]
 {...},          | take list off stack, then iterate through    |
                 | the list. on each iteration, put the current |
                 | element on the stack, execute the block, and |
                 | pop the top of the stack. if the top is      |
                 | true then keep the element, else drop it.    |
                 | when done, push list of all true elements    |
                 | So, for each element...                      | n x
   \.            |   Swap & dup                                 | x n n 
   @             |   Bring x around                             | n n x
   %             |   Modulo                                     | n (n%x)
   !             |   Boolean not. 0->1, else->0. Thus this is 1 |
                 |   if x divides n.                            | n (x divides n)
                 | So only the divisors of n are kept           | n [divisors of n]

¿Qué hace si los divisores están vacíos?

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack                                | g [ last | cur
  .              | dup                                          | g [ l | c | c
  2$             | copy 3rd down                                | g [ l | c | c | l
  -              | sub. This is the current gap, cur-last       | g [ l | c | c-l
  .              | dup                                          | g [ l | c | c-l | c-l
  4$             | copy 4th down                                | g [ l | c | c-l | c-l | g
  >              | is cur gap > max gap so far?                 | g [ l | c | c-l | c-l>g
  {#1}{#2}if..   | #1 if c-l > g, #2 otherwise, and do ".." in  | ... | g [ c | c | c
                 | either situation                             | 

Dos caminos: sí y no. En caso afirmativo (tenga en cuenta que ifconsume el valor superior en la pila):

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack. note that now the old `g` is  | XX [ l | c | g
                 | garbage and `c-l` is the new `g`.            |
 ]               | close the array                              | XX [l, c, g]
 .p              | duplicate it and print it, consuming the dup | XX [l, c, g]
 ~               | pump array back onto the stack. Note now the | XX | l | c | j
                 | array marker [ is gone.                      | 
 \               | swap.                                        | XX | l | g | c                         
 [               | mark the array                               | XX | l | g | c [
 .               | this is the part after the if. dups the top, | XX | l | g [ c | c
                 | but it does this in two steps, first popping | 
                 | c then putting two copies on top, so the     | 
                 | array marker moves                           | 
 .               | dup again                                    | XX | l | g [ c | c | c

Si no:

 Command         | explanation                                  | stack
-----------------+----------------------------------------------+----------------
                 | initial stack. In this case g is still the   | g [ l | c | c-l
                 | max gap so far                               | 
 ;\;             | dump top of stack, swap, and dump again      | g [ c
 ..              | the part after the if. dup twice             | g [ c | c | c

Tenga en cuenta en cualquier caso, nuestra pila ahora está en la forma ... | g [ c | c | c.

Ahora doaparece el valor superior de la pila, siempre c, y se repite si es positivo. Como csiempre aumenta, esto siempre es cierto, por lo que hacemos un bucle para siempre.

Una vez que aparece, la parte superior de la pila es g [ c | c, lo que significa que se actualizó por última vez c, la marca de matriz está en el mismo lugar y gtodavía está donde la esperamos.

Estas son las operaciones complicadas de GolfScript. ¡Espero que hayas disfrutado seguirlo!

Claudiu
fuente
1
Excelente aclaración!
Jonathan Van Matre
1

Ruby, 110

Solo para Ruby 2.0 debido al lazymétodo:

(2..1.0/0).lazy.select{|n|!(2...n).any?{|m|n%m==0}}.reduce([2,0]){|(l,t),c|d=c-l;p [l,c,d]if d>t;[c,d>t ?d:t]}

Salida:

[2, 3, 1]
[3, 5, 2]
[7, 11, 4]
[23, 29, 6]
[89, 97, 8]
[113, 127, 14]
[523, 541, 18]
[887, 907, 20]
[1129, 1151, 22]
[1327, 1361, 34]
[9551, 9587, 36]
[15683, 15727, 44]
[19609, 19661, 52]
[31397, 31469, 72]
[155921, 156007, 86]
[360653, 360749, 96]
[370261, 370373, 112]
[492113, 492227, 114]
...
David Herrmann
fuente
1

Perl, 105 bytes

$p=2;$d=0;L:for($i=2;++$i>2;){!($i%$_)&&next L for 2..$i-1;if($i-$p>$d){$d=$i-$p;print"$p $i $d\n"}$p=$i}

Sin golf:

$p = 2;
$d = 0;
L: for ($i = 2; ++$i > 2; ){
    !($i % $_) && next L for 2..$i-1;
    if ($i - $p > $d) {
        $d = $i - $p;
        print "$p $i $d\n"
    }
    $p = $i
}  

El algoritmo es simple, $precuerda el número primo anterior. Luego $ipasa de 3arriba a arriba, cuando el tipo $ i "falla en mí" o se vuelve negativo debido al desbordamiento. $ise prueba de forma cruda comprobando todos los divisores de 2 a $i-1. Se imprime una línea, si la diferencia actual es mayor que la diferencia impresa anterior $d.

Con algunos bytes más, el tiempo de ejecución se puede mejorar:

$p = 2;
$d = 0;
L: for ($i=3; $i > 2; $i += 2){
    for ($j=3; $j <= sqrt($i); $j += 2){
        next L if !($i%$j)
    }
    if ($i - $p > $d) {
        $d = $i - $p;
        print "$p $i $d\n"
    }
    $p = $i
}

El resultado comienza con:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52
31397 31469 72
155921 156007 86
360653 360749 96
370261 370373 112
492113 492227 114
1349533 1349651 118
1357201 1357333 132
2010733 2010881 148
4652353 4652507 154
17051707 17051887 180
20831323 20831533 210
47326693 47326913 220
...
Heiko Oberdiek
fuente
1
Eso no es correcto, necesita encontrar la serie de brechas crecientes. Vea, por ejemplo, la respuesta de Ruby o Matlab para la salida esperada.
mmumboss
1
@mmumboss: Oh, he pasado por alto esto. Corregido ahora.
Heiko Oberdiek
Bueno para un lenguaje donde todas las variables requieren un mínimo de 2 caracteres.
orion
1

Python, 93 91 caracteres

Comprobación primitiva ingenua (verifique si es divisible por algo de 2 a n(menos caracteres que a n/2)):

g=0;i=l=2
while 1:
 i+=1
 if all(i%x for x in range(2,i)):
    if i-l>g:g=i-l;print l,i,g
    l=i

El segundo nivel de sangría es un carácter de tabulación.

Salida:

2 3 1
5 7 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
...
Claudiu
fuente
Bien, olvidé ese rango hasta nsolo cheques hastan-1
Claudiu
1

Bash y algo de Perl para expresiones regulares principales ( 167 157 143 112 bytes)

n=2
c=2
while p=$c
do perl -e\(1x$[++n]')=~/^(11+?)\1+$/&&exit 1'&&c=$n
((c-p>g))&&g=$[c-p]&&echo $p $c $g
done

alguna salida:

$./golfd.sh
2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
Newbrict
fuente
Usar el backtracking NP de regex para eludir completamente cualquier bucle y estructura de control es pura perfección. Sin embargo, testprotesta bastante y no me funciona. También se podría utilizar un poco de let n++y let f=c-py reemplazartest con [. O posiblemente pruebe en (())donde no necesita $o espacios.
orion
test -n $d devuelto verdadero para una cadena vacía. test -n "$d"estuvo bien pero por más tiempo. Sin embargo, la página de manual dice que -n es opcional, y resulta que test $destaba bien. Y por [ $d ]lo tanto también. Y g = 0 tuvo que ser inicializado.
orion
@orion, lo siento por alguna razón parece que ha funcionado una vez que ya se rompió en mi máquina también, yo invertí a 167. Voy a tratar de agregar algunas de sus otras sugerencias
Newbrict
Su entorno tal vez tenía variables predefinidas.
orion
@orion por alguna razón su edición fue rechazada, ¿puede volver a editar?
Newbrict
1

Perl 95 90 bytes

for($n=$c=2;$p=$c;$c-$p>$g&&printf"$p $c %d\n",$g=$c-$p){$c=$n if(1x++$n)!~/^(11+?)\1+$/}

versión anterior sin golf:

$n=$c=2;
while($p=$c){
    $c=$n if (1x++$n)!~/^(11+?)\1+$/;
    if ($c-$p>$g) {$g=$c-$p;print "$p $c $g\n"}
}

Esto es similar a mi otra presentación, sans bash.

Newbrict
fuente
No soy molesto, solo quiero ver hasta dónde puede llegar esto. A continuación:for($n=$c=2;$p=$c;$c-$p>$g&&printf"$p $c %d\n",$g=$c-$p){$c=$n if(1x++$n)!~/^(11+?)\1+$/}
Orion
@orion que es algo serio para el abuso de bucle jaja!
Newbrict
1

C (100)

Mi propia contribución, ningún algoritmo especial, solo golf:

i,g,r,p=2;main(){for(;r=p;p-r>g?printf("%d %d %d\n",r,p,g=p-r):0)for(i=0;i-p;)for(i=1,++p;p%++i;);}
Orión
fuente
"+10 caracteres si solo imprime los espacios sin los números primos". - si elimina la impresión de ry ptendrá menos caracteres y obtendrá la bonificación :)
CompuChip
Completness is pretty :)
orion
1

Haskell, 134C

Golfizado:

c n=null[x|x<-[2..n-1],n`mod`x==0]&&n>1
p=filter c[1..]
g l(m:n:o)
 |(n-m)>l=do print(m,n,n-m);g(n-m)(n:o)
 |True=g l(n:o)
main=g 0 p

Sin golf:

-- c function checks if n is a prime number
c n=null[x|x<-[2..n-1],n`mod`x==0]&&n>1

-- p is an infinite list of primes
p=filter c[1..]

-- g function prints a list of primes and differences.
--   l is the maximum difference seen so far
--   (m:n:o) is the list of unprocessed primes
g l(m:n:o)
 |(n-m)>l=do print(m,n,n-m);g(n-m)(n:o)
 |True=g l(n:o)

-- main starts the ball rolling with a default max-seen value of 0
main=g 0 p
danmcardle
fuente
Me encanta esa evaluación perezosa!
Jonathan Van Matre
1

C: 493 302 272 246

int e(int j){for(int i=2;i<j;i++)if(j%i<1)return 0;return 1;}void f(int a,int b,int c){if(e(a)&e(b))if(c<b-a){printf("%d %d %d\n",a,b,b-a);f(a+1,b+1,b-a);}else f(a+1,b+1,c);if(e(b))f(a+1,b,c);if(e(a))f(a,b+1,c);f(a+1,b+1,c);}int main(){f(2,3,0);}

Utilicé la recursión, no el bucle habitual de foro while.

int isPrime(int num){
    for( int i=2; i<num; i++ )
        if(num%i < 0) return 0;
    return 1;
}
void fun(int n1, int n2, int gap){
   if( isPrime(n1) & isPrime(n2) ){
        if( gap < n2-n1 ){
           printf("%d %d %d\n", n1, n2, n2-n1);
           fun(n1+1, n2+1, n2-n1);
        }else{
           fun(n1+1, n2+1, gap);
        }
   }
   if( isPrime(n2) ){
       fun(n1+1, n2, gap);
   }
   if( isPrime(n1) ){
       fun(n1, n2+1, gap);
   }
   fun(n1+1, n2+1, gap);
}

int main(){
   fun(2,3,0);
}

Salida:

2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
887 907 20
1129 1151 22
1327 1361 34
9551 9587 36
15683 15727 44
19609 19661 52
Loukas
fuente
Esto no funciona verdadero / falso no está definido, pero incluso si lo arreglamos, informa brechas incorrectas. Por ejemplo, hay MUCHOS números primos entre 25219 y 43237. Su recursión está leakingen la parte superior, porque no está probando isPrime (n2), está dejando números primos entre n1 y n2. Y esto realmente no se puede solucionar, porque no se puede aumentar n2 sin cumplir primos.
orion
¡Tienes razón! ¡Está mal! Mi pensamiento estuvo mal desde el principio.
Loukas
1
Ahora es mejor .. :)
Loukas
+1 Ahora que está arreglado, me gusta, es bastante inusual (aunque no eficiente). Podrías jugar mucho golf. Saltar returnen principal. Salta el último else. Reemplazar &&-> &y num%i==0con num%i<1. Y según los antiguos estándares c (habrá advertencias), no necesita especificar valores de retorno para las funciones void e int (sus argumentos también son predeterminados para int).
orion
Estaba jugando un poco y lo reduje a 151 caracteres, con una sola llamada recursiva incondicional, solo un especificador de tipo ( int) y una función de prueba principal muy reducida: e(j,i){while(j%++i);return i==j;}f(a,b,c){int A=e(a,1),B=e(b,1);if(A&B&&c<b-a)printf("%d %d %d\n",a,b,c=b-a);f(a+(B|!A),b+(A|!B),c);}main(){f(2,3,0);}
orion
1

Oracle SQL, 216 202 196 172 + 10 = 182

Acabo de notar esto en la pregunta:

El conteo de personajes más bajo gana. +10 caracteres si solo imprime los espacios sin los números primos.

Como se trata de SQL y las palabras clave son tan largas, en realidad es mejor tomar la penalización, dando lo siguiente. Es la misma idea que la original.

with c as(select level+1n from dual connect by level<1e124)select lead(n)over(order by n) from(select*from c a where not exists(select*from c where n<a.n and mod(a.n,n)=0))

que embellece a:

with c as ( 
 select level + 1 n 
   from dual 
connect by level < 1e124
        )
select lead(n) over ( order by n ) 
  from ( select *
           from c a 
          where not exists( select * 
                              from c 
                             where n < a.n 
                               and mod(a.n, n) = 0
                                   )
                )

Respuesta anterior (196)

with c as(select level+1n from dual connect by level<1e124)select n,p,p-n from(select n,lead(n)over(order by n)p from(select*from c a where not exists(select*from c where n<a.n and mod(a.n,n)=0)))

y en un formato legible:

with c as ( 
 select level + 1 n 
   from dual 
connect by level < 1e124
        )
select n, p, p-n 
  from ( select n, lead(n) over ( order by n ) p 
           from ( select * 
                    from c a 
                   where not exists (
                                select * 
                                  from c
                                 where n < a.n 
                                   and mod(a.n, n) = 0
                                       )
                         )
                )

Esto crea un generador de números c, la sub-selección más interna crea los números primos usando un Tamiz de Eratóstenes, el externo resuelve el primo anterior y finalmente la última selección resta uno del otro.

Esto no devolverá nada porque está realizando 1 x 10 124 consultas recursivas ... Entonces, si desea que funcione, reduzca este número a algo razonable.

Ben
fuente
Cuando se trata de un desafío como este, pienso que SQL no es tanto Turing completo, sino Turing obstinado.
Jonathan Van Matre
Pero es Turning-complete @Jonathan, aunque conseguirlo a veces es "interesante" :-)?
Ben
Sabiendo que es Turing completo, estaba intentando bromear. Perdí la marca, al parecer. :) De todos modos, hay varias respuestas T-SQL en mi perfil ... ¡traiga su Oracle y tengamos un duelo!
Jonathan Van Matre
0

D - 153 + 10 = 163

Estoy dispuesto a aceptar la penalización de +10 aquí, porque el recuento de caracteres aún es más bajo de lo que hubiera sido si hubiera impreso también los números primos.

Golfizado :

import std.stdio;bool p(int l){int n;foreach(i;1..l+1)n+=l%i==0?1:0;return n==2;}void main(){int g;foreach(l;0..int.max)if(l.p){if(g>0)(l-g).write;g=l;}}

Versión legible :

import std.stdio;

bool prime( int number )
{
    int divisors;

    foreach( i; 1 .. number + 1 )
        divisors += number % i == 0 ? 1 : 0;

    return divisors == 2;
}

void main()
{
    int lastPrime;

    foreach( number; 0 .. int.max )
        if( number.prime )
        {
            if( lastPrime > 0 )
                ( number - lastPrime ).write;

            lastPrime = number;
        }
}
Tony Ellis
fuente
0

JAVASCRIPT 174 char

var p=[2],l=2,g=0;
for(var n=3;n>0;n+=2){
  var o=0;
  for(var t=0;t<p.length;++t){
    if(n/p[t] == parseInt(n/p[t])){
      o=1;
    }
  }
  if(o==0){
    p.push(n);
    if(n-l>g){
      g=n-l;
      console.log(l,n,g);
    }
    l=n;
  }
}

version corta:

var p=[2],l=2,g=0;for(var n=3;n>0;n+=2){var o=0;for(var t=0;t<p.length;++t){if(n/p[t] == parseInt(n/p[t])){o=1;}}if(o==0){p.push(n);if(n-l>g){g=n-l;console.log(l,n,g);}l=n;}}
wuiyang
fuente
0

Javascript 138

for(var a=2,b=0,c=0;a++;){var d;a:{for(var e=a,f=2;f<e;f++)if(0==e%f){d=!1;break a}d=!0}d&&(0!=b&&a-b>c&&(c=a-b,console.log(b,a,c)),b=a)}

Copie este código a la consola de su navegador. Será por siempre como el número máximo es algo alrededor 1.79*10^308.

Sin golf:

var number = 2;
var lastPrime = 0;
var gap = 0;

while(number++)
{
    if (isPrime(number)) {
        if (lastPrime != 0) {            
            if (number - lastPrime > gap)
            {
                gap = number - lastPrime;
                console.log(lastPrime, number, gap);
            }
        }

        lastPrime = number;
    }
}

function isPrime(n){
    for (var i = 2; i < n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}
RononDex
fuente
0

C # 162 161 caracteres

151 caracteres + 10 caracteres de penalización = 161 caracteres

Version corta:

using System;class P{static void Main(){int p=2,g=0;for(int i=3;;i++){for(int j=2;j<i;j++)if(i%j==0)goto e;if(i-p>g)Console.WriteLine(g=i-p);p=i;e:;}}}

Versión larga:

using System;

class PrimeGaps
{
    private static void Main()
    {
        int lastPrime = 2;
        int largestGap = 0;

        for (int i = 3; true; i++)
        {
            // Prime test
            for (int j = 2; j < i; j++)
                if (i%j == 0)
                    goto nextI; // Skip to next iteration of i

            // Largest gap check
            if (i - lastPrime > largestGap)
            {
                largestGap = i - lastPrime;
                Console.WriteLine(largestGap);
            }

            // Remember last prime
            lastPrime = i;

            nextI:
                ; // Do nothing
        }
    }
}

En realidad, era mejor tomar 10 caracteres de penalización, ya que es una escritura más corta g(11 caracteres con penalización) que p+" "+i+" "+g(13 caracteres sin penalización).

Boris B.
fuente
0

Ruby 90 86 84 83 caracteres

r,i,g=2,2,0;while i+=1 do(2...i).all?{|j|i%j>0}&&((i-r<=g||p([r,i,g=i-r]))&&r=i)end

Algunos cortocircuitos booleanos, evaluación de abuso de expresión, etc.

Boris B.
fuente
0

C 248

El código compara los números primos consecutivos a, by luego comprueba si los espacios son mayores que g y luego encuentra el siguiente par de números primos.

#include <cstdio>
void f(int* a, int* b){*a =*b;int t=1;while (*b += 2){t=1;for(int i=3;i<*b;i+=2){if(*b%i==0){t=0; break;}}if(t)break;}}
int main(){int a=2,b=3,g=0;do{(b-a>g)?printf("%d %d %d\n",a,b,(g=b-a)): f(&a,&b);} while(b>=0);return 0;}
bacchusbeale
fuente
Esto es C ++, ¿no es así?
Zacharý
0

Haskell, 154 144 137 123

Los primos pse generan usando el tamiz de erasthotenes #, y luego se filtran e imprimen usando %.

p=2:3#1
n#m|all((>0).mod n)$take m p=n:(n+1)#(m+1)|1<2=(n+1)#m
(l:u@(o:_))%k|o-l>k=print(l,o,o-l)>>u%(o-l)|1<2=u%k
main=p%0

La salida se ve como

(2,3,1)
(3,5,2)
(7,11,4)
(23,29,6)
(89,97,8)

que espero que esté bien

Flonk
fuente
0

Game Maker Language, 85

Asumiendo todas las variables no inicializadas como 0(este es el valor predeterminado con algunas versiones de Game Maker).

a=2b=2for(d=2;b++;1)for(c<b-a;b mod --d;1)d<3&&(c=b-a&&show_message_ext("",a,b,c)a=b)
Timtech
fuente
0

Game Maker Language, 74 + 55 = 129

Asumiendo todas las variables no inicializadas como 0(este es el valor predeterminado con algunas versiones de Game Maker).

n=2while(n++){if p(n){if l{if n-l>g{g=n-l;show_message_ext("",l,n,g)}}l=n}

La secuencia de comandos pestá a continuación:

r=1a=argument0for(i=2i<a;i++){if a mod i=0r=0}return r}
Timtech
fuente
0

Perl, 87 bytes ( usando un módulo )

use Math::Prime::Util":all";$l=2;forprimes{if($_-$l>$m){say"$l $_ ",$m=$_-$l}$l=$_}1e14

Escribí el módulo, pero tendríamos que agregar 565,000 caracteres adicionales a la cuenta. Principalmente publicando por diversión, pero también para dar una alternativa de rendimiento ya que hasta ahora no veo ninguno usando builtins. 4.6s para huecos a 1e9, 36s para huecos a 1e10, 6.5min para 1e11.

Pari / GP 2.8 se puede hacer básicamente de la misma manera, aunque más de 2 veces más lento:

l=2;m=0;forprime(p=2,1e14,if(p-l>m,print(l," ",p," ",m=p-l));l=p)
DanaJ
fuente
-1

Perl 153

Código corto:

$i=$a=2;while($a=$i++){if(p($i)){if($m<$m2=$i-$a){$m=$m2;print"$a $i $m$/"}}}sub p{$d=2;$s=sqrt$_[0];while(){return 0if!($_[0]%$d);return 1if$d>$s;$d++}}

fácil de leer:

$i=$a=2;
while($a=$i++){
  if(p($i)){
    if($m<$m2=$i-$a){
      $m=$m2;
      print"$a $i $m$/"
    }
  }
}
sub p {
  $d=2;
  $s=sqrt$_[0];
  while(){
    return 0if!($_[0]%$d);
    return 1if$d>$s;
    $d++;
  }
}
Riymus
fuente
Esto genera todas las brechas, no solo las más grandes hasta ahora.
orion