Calculer les écarts principaux

19

Trouver des nombres premiers est un rite de programmation de passage et très souvent un premier programme sérieux que quelqu'un crée (généralement avec la division d'essai).

Mais les nombres premiers seuls sont déjà épuisés. Une autre chose beaucoup plus intéressante est d'obtenir les écarts premiers: les écarts les plus longs jusqu'à présent entre des nombres premiers consécutifs. Ce sont assez rares et "précieux". Les premières paires et leurs différences sont:

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

Mon père les calculait à la main pour s'amuser jusqu'à 10 km. Voyons à quel point un code peut être court.

Règles:

  • pas de fonctions intégrées pour les tests principaux, la génération principale ou les écarts principaux
  • pas de récupération http://oeis.org/A002386 ou similaire (je peux vous sentir les tricheurs de loin :))
  • pas de tableaux précalculés
  • continuez à imprimer jusqu'à ce que votre type entier interne échoue sur vous

Le nombre de caractères le plus bas gagne. +10 caractères si vous imprimez uniquement les espaces sans les nombres premiers.

Vous pouvez également montrer des versions avec des fonctions intégrées si elles sont intéressantes. Sois créatif.

Clarification: vous passez par des nombres premiers et vous signalez chaque fois que vous voyez un écart qui est plus grand que tout écart que vous avez vu auparavant. Par exemple, entre 3 et 5, il y a un écart de 2 unités de large. L'écart entre 5 et 7 est également de 2, mais c'est une vieille nouvelle, on s'en fiche plus. Ce n'est que lorsque vous voyez un nouveau plus grand écart, que vous le signalez. Cela reflète la façon dont les nombres premiers deviennent de moins en moins fréquents, alors que les écarts deviennent de plus en plus larges.


EDIT : La plupart des réponses sont brillantes et méritent plus de reconnaissance. Cependant, jusqu'à présent, une entrée GolfScript avec 48 caractères est la plus courte.

orion
la source
1
Dans votre exemple, 3 est la fin d'une paire et le début de la paire suivante, alors que ce n'est pas le cas pour les autres nombres. Qu'est-ce que tu veux?
mmumboss
Peu importe, je l'ai maintenant.
mmumboss
Vous voudrez peut-être réécrire votre règle comme «aucune fonction intégrée pour les tests principaux, le calcul principal ou les écarts principaux». Sinon, une solution évidente utiliserait une fonction qui retourne le n e premier, puis incrémenterait n , réexécuterait la fonction et trouverait la différence.
user12205
2
Aww. j'aime OEIS
TheDoctor
J'ai le même doute que @mmumboss. Pourriez-vous s'il vous plaît xplain?
Clyde Lobo

Réponses:

3

GolfScript 66 59 57 49 48

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

Bien que j'ai du mal à l'exécuter ici http://golfscript.apphb.com/ (peut-être que ce site n'aime pas la boucle infinie?) Mais cela fonctionne très bien lorsque je l'exécute sur mon ordinateur avec golfscript.rb. Je suis assez nouveau sur GolfScript, donc cela peut probablement être approfondi encore plus. MISE À JOUR: Je ne pense pas que cela puisse être approfondi sans changer l'algorithme d'une manière ou d'une autre.

Les premières lignes sont imprimées (si vous n'aimez pas l'impression du "", vous pouvez ajouter; au début du script, mais cela augmente jusqu'à 49 caractères):

[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]
...

Idée générale lisible par l'homme de la façon dont cela fonctionne (quelques choses légèrement différentes puisque je n'utilise pas de pile dans cette version):

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
la source
11

Python, 121 110 109 108 104 103 caractères

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 première fois que j'ai essayé de répondre ici, j'espère que je l'ai bien fait ... pas sûr d'avoir même compté les caractères correctement.

Hmmm, je pourrais enregistrer un autre caractère sur l'impression en rétrogradant en Python 2.x ...

Tal
la source
121 caractères, faites un titre avec un titre #, vous ne comptez pas sérieusement les caractères à la main, n'est-ce pas? javascriptkit.com/script/script2/charcount.shtml
user80551
Non, je n'ai pas compté à la main :) Mais j'ai vu d'autres réponses Python à certaines questions aplaties sur une seule ligne de manière à réduire les espaces, et franchement, je ne sais pas si une nouvelle ligne est comptée comme 1 ou 2 caractères ...
Tal
1
Nous comptons les sauts de ligne comme 1 caractère, sauf indication contraire explicite des règles de la question. Bienvenue chez PPCG!
Jonathan Van Matre
3
Bienvenue! Belle réponse, et elle a aussi une marge d'amélioration. Par exemple, if all(n%x>0for x in p):est un peu plus court. Vous pouvez également enregistrer certains caractères en déplaçant des instructions sur la même ligne (par exemple a=1;b=2;f()).
grc
1
Le dernier changement a brisé le code en ne poussant pas [n] vers l'avant comme indiqué.
orion
4

JavaScript, 90 85 78 74 caractères

Short Code (Google Closure Compiler - Optimisations avancées; certaines modifications manuelles; plus de modifications par @ 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)

Code long

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

Production

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
...

Test assez inefficace pour les nombres premiers, mais de cette façon, il utilise moins de caractères.

Premier post ici, veuillez donc excuser toute erreur.

Sirko
la source
78 Personnages -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 Merci. Je n'ai pas repéré ceux-là. Édité.
Sirko
Encore plus inefficace mais 74 caractères -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

Permet une sortie infinie, bien qu'après un certain point de la séquence, le ventilateur tourne et vous commencez à soupçonner que votre CPU joue Freecell tout en faisant de son mieux pour avoir l'air occupé.

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]

Échantillon de sortie (ce sont ceux qu'il prend dans les premières 30 secondes):

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

Code non 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
la source
Le reconnaît-il ?
Riking
Oui, il ne s'exporte tout simplement pas de cette façon, mais il l'analyse très bien lorsque vous collez du code dans le bloc-notes. Je l'ai déjà marqué en conséquence mais je vais réviser pour simplifier.
Jonathan Van Matre
combien de caractères si vous faites usage Mathematica est intégré dans les fonctions Prime?
Michael Stern
76. Puisque la définition entière de p @ x_ n'est qu'une réimplémentation de NextPrime, elle peut être remplacée par 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

(Inefficace) expression de liste principale volée à Will Ness .

-edit- je ne savais pas que ce x|y=z|w=qserait valide.

Rhymoid
la source
2

MATLAB 104 89

Je viens d'implémenter la méthode de base en vérifiant chaque division possible.

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

Production:

  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
la source
Je suis allumé octaveet cette infchose ne fonctionne pas (et l'impression est différée jusqu'à la fin de la boucle). Matlab a-t-il une évaluation de la plage paresseuse?
orion
Matlab imprime en temps réel, à chaque itération de la boucle. Lorsque je démarre mon programme, je reçois un avertissement indiquant que l'index maximum est 2147483647, puis il démarre. Alternativement, je pourrais remplacer inf par intmax, mais c'est trois caractères de plus.
mmumboss
2

76 caractères, dogelang

Converti de ma version 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)

Production:

(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
la source
Doit être sélectionné comme gagnant!
Sarge Borsch
2

Golfscript, 59 51 50 caractères

Homme, chaque personnage est extrêmement difficile à perdre:

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

Production :

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

Explication :

La pile est configurée de sorte que chaque itération commence par la pile comme celle-ci, le haut étant à droite. Le [indique le marqueur de tableau actuel, ce qui signifie que lorsque l'interpréteur rencontre a ], tout sur la pile, de la marque au sommet, est placé dans un tableau.

g [ last | cur

gest l'écart maximum jusqu'à présent. De haut en bas:

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

À l'intérieur de la boucle:

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

Comment met-il tous les diviseurs dans une liste? Faisons-le étape par étape

 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]

Que fait-il si les diviseurs sont vides?

 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                             | 

Deux voies: oui et non. Si oui (notez queif consomme la valeur la plus élevée de la pile):

 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

Sinon:

 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

Notez dans les deux cas, notre pile est maintenant sous la forme ... | g [ c | c | c .

Maintenant, le dosaute la valeur supérieure de la pile - toujours c- et boucle si elle est positive. Puisquec toujours en augmentation, cela est toujours vrai, donc nous bouclons pour toujours.

Une fois sauté, le haut de la pile est g [ c | c, ce qui signifie que le dernier a été mis à jour c, la marque du tableau est au même endroit etg est toujours là où nous l'attendons.

Ce sont les opérations alambiquées de GolfScript. J'espère que vous avez aimé suivre!

Claudiu
la source
1
Excellente élucidation!
Jonathan Van Matre
1

Rubis, 110

Uniquement pour Ruby 2.0 en raison de la lazyméthode:

(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]}

Production:

[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
la source
1

Perl, 105 octets

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

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

L'algorithme est simple, se $psouvient du nombre premier précédent. Passe ensuite $ide 3à, lorsque le type $ i "échoue sur moi" ou devient négatif à cause d'un débordement. $iest testé de manière grossière en vérifiant tous les diviseurs de 2 à $i-1. Une ligne est imprimée si la différence actuelle est supérieure à la différence imprimée précédente $d.

Avec quelques octets supplémentaires, le temps d'exécution peut être amélioré:

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

Le résultat commence par:

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
la source
1
Ce n'est pas correct, vous devez trouver la série d'écarts croissants. Voir par exemple la réponse Ruby ou Matlab pour la sortie attendue.
mmumboss
1
@mmumboss: Oh, j'ai oublié cela. Fixé maintenant.
Heiko Oberdiek
Bon pour une langue où toutes les variables nécessitent un minimum de 2 caractères.
orion
1

Python, 93 91 caractères

Vérification principale naïve (vérifier si divisible par quoi que ce soit de 2 à n(moins de caractères que à 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

Le deuxième niveau de retrait est un caractère de tabulation.

Production:

2 3 1
5 7 2
7 11 4
23 29 6
89 97 8
113 127 14
523 541 18
...
Claudiu
la source
Bien, j'ai oublié cette plage jusqu'à nseulement les contrôles jusqu'àn-1
Claudiu
1

Bash et Perl pour certains premier regex ( 167 157 143 112 octets)

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

une sortie:

$./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
la source
Utiliser le retour arrière NP de regex pour contourner complètement les boucles et les structures de contrôle est une pure perfection. Cependant, testje proteste beaucoup et cela ne fonctionne pas pour moi. Vous pouvez également utiliser certains let n++et let f=c-pet remplacer testpar[ . Ou peut-être tester (())là où vous n'avez pas besoin $ni d'espace.
orion
test -n $d retourné vrai pour une chaîne vide. test -n "$d"était bien mais plus long. Cependant, la page de manuel indique que -n est facultatif, et il test $ds'est avéré que c'était ok. Et donc [ $d ]aussi. Et g = 0 devait être initialisé.
orion
@orion, désolé pour une raison quelconque, cela semblait fonctionner une fois maintenant, il est également tombé en panne sur ma machine, je suis revenu à 167. J'essaierai d'ajouter certaines de vos autres suggestions
Newbrict
Votre environnement peut avoir des variables prédéfinies.
orion
@orion pour une raison quelconque, votre modification a été rejetée, pouvez-vous la rééditer?
Newbrict
1

Perl 95 90 octets

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

ancienne version non 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"}
}

Ceci est similaire à mon autre soumission, sans bash.

Newbrict
la source
Je ne suis pas ennuyeux, je veux juste voir jusqu'où cela peut aller. Ici: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 qui est sérieux pour abus de boucle haha!
Newbrict
1

C (100)

Ma propre contribution, pas d'algorithme spécial, juste du 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;);}
orion
la source
"+10 caractères si vous imprimez uniquement les espaces sans les nombres premiers." - si vous supprimez l'impression de ret pvous aurez moins de caractères et
marquerez
La complétude est jolie :)
orion
1

Haskell, 134C

Golfé:

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

Non 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
la source
J'adore cette évaluation paresseuse!
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);}

J'ai utilisé la récursion pas la boucle habituelle de forouwhile .

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

Production:

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
la source
Ça ne marche pas. true / false ne sont pas définis, mais même si nous corrigeons cela, cela signale des lacunes erronées. Par exemple, il y a BEAUCOUP de nombres premiers entre 25219 et 43237. Votre récursivité est leakingen haut, parce que vous ne testez pas isPrime (n2), vous laissez des nombres premiers entre n1 et n2. Et cela ne peut pas vraiment être corrigé, car vous ne pouvez pas augmenter n2 sans rencontrer des nombres premiers.
orion
Tu as raison! Il est faux! Ma pensée était erronée depuis le début.
Loukas
1
Maintenant, c'est mieux .. :)
Loukas
+1 Maintenant qu'il est réparé, j'aime ça - c'est assez inhabituel (bien que pas efficace). Vous pourriez beaucoup jouer au golf. Passer returnen principal. Sautez le dernier else. Remplacez &&-> &et num%i==0par num%i<1. Et selon les anciennes normes c (il y aura des avertissements), vous n'avez pas besoin de spécifier des valeurs de retour pour les fonctions void et int (leurs arguments par défaut sont également int).
orion
Je jouais un peu et je suis descendu à 151 caractères, avec un seul appel récursif inconditionnel, un seul spécificateur de type ( int) et une fonction de test principale très réduite: 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 172 + 10 = 182

Je viens de remarquer cela dans la question:

Le nombre de caractères le plus bas gagne. +10 caractères si vous imprimez uniquement les espaces sans les nombres premiers.

Comme il s'agit de SQL et que les mots clés sont si longs, il est préférable de prendre la pénalité, en donnant ce qui suit. C'est la même idée que l'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))

ce qui donne:

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

Ancienne réponse (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)))

et dans un format lisible:

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

Cela crée un générateur de nombres dans c , la sous-sélection la plus intérieure crée les nombres premiers à l'aide d'un tamis d'Ératosthène, l'extérieur détermine le premier précédent et enfin le dernier choix soustrait l'un de l'autre.

Cela ne retournera rien car il exécute 1 x 10 124 requêtes récursives ... Donc, si vous voulez que cela fonctionne, diminuez ce nombre à quelque chose de sensé.

Ben
la source
Quand il s'agit d'un défi comme celui-ci, je pense que SQL n'est pas tellement Turing-complet, mais Turing-obstiné.
Jonathan Van Matre
Mais il est à tourner complet @ Jonathan, mais l' obtenir , il est parfois « intéressant » :-)?
Ben
Sachant que c'est Turing-complet, je visais à plaisanter. Manquait la marque, apparemment. :) Quoi qu'il en soit, il y a plusieurs réponses T-SQL dans mon profil ... apportez votre Oracle et faisons un duel!
Jonathan Van Matre
0

D - 153 + 10 = 163

Je prends volontiers la pénalité de +10 ici, car le nombre de caractères est toujours inférieur à ce qu'il aurait été si j'avais également imprimé les nombres premiers.

Golfé :

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

Version lisible :

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
la source
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 courte:

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
la source
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)}

Copiez ce code sur la console de votre navigateur. Ce sera pour toujours comme le nombre maximum est quelque chose autour1.79*10^308 .

Non 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
la source
0

C # 162 161 caractères

151 caractères + 10 caractères de pénalité = 161 caractères

Version courte:

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

Version longue:

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

Il était en fait préférable de prendre une pénalité de 10 caractères, car l'écriture est plus courte g(11 caractères avec pénalité) que p+" "+i+" "+g(13 caractères sans pénalité).

Boris B.
la source
0

Ruby 90 86 84 83 caractères

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

Quelques courts-circuits booléens, évaluation d'abus d'expression, etc.

Boris B.
la source
0

C 248

Le code compare les nombres premiers consécutifs a, b, puis vérifie si les écarts sont plus grands que g, puis trouve la paire suivante de nombres premiers.

#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
la source
C'est du C ++, n'est-ce pas?
Zacharý
0

Haskell, 154 144 137 123

Les nombres premiers psont générés à l'aide du tamis des gommes à effacer #, puis filtrés et imprimés à l'aide de %.

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 sortie ressemble à

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

j'espère que ça va.

Flonk
la source
0

Langue de Game Maker, 85

En supposant que toutes les variables non initialisées sont 0(c'est la valeur par défaut avec certaines versions 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
la source
0

Langue Game Maker, 74 + 55 = 129

En supposant que toutes les variables non initialisées sont 0(c'est la valeur par défaut avec certaines versions 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}

Le script pest ci-dessous:

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

Perl, 87 octets (à l' aide d'un module )

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

J'ai écrit le module, mais il faudrait ajouter 565 000 caractères supplémentaires au décompte. Publier principalement pour le plaisir, mais aussi pour offrir une alternative de performance, car je n'en vois pas jusqu'à présent utiliser des intégrés. 4,6 s pour les écarts à 1e9, 36s pour les écarts à 1e10, 6,5 min pour 1e11.

Pari / GP 2.8 peut être fait essentiellement de la même manière, quoique plus de 2 fois plus lentement:

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

Perl 153

Petit code:

$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++}}

facile à lire:

$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
la source
Cela génère toutes les lacunes, pas seulement les plus importantes jusqu'à présent.
orion