La solitude des nombres premiers

24

Récemment, j'ai lu le roman "La solitude des nombres premiers" où les personnages principaux sont quelque peu comparés aux nombres premiers jumeaux (" toujours ensemble, mais jamais touchant ").

Un nombre premier jumeau est un nombre premier qui est soit 2 de moins, soit 2 de plus qu'un autre nombre premier - par exemple, la paire de nombres premiers jumeaux (41, 43). En d'autres termes, un nombre premier jumeau est un nombre premier qui a un écart principal de deux. Parfois, le terme twin prime est utilisé pour une paire de jumeaux prime; un autre nom pour cela est le premier jumeau ou la première paire. Wikipédia

Bien que je n'aime pas beaucoup le roman déprimant, et depuis que je suis tombé dans PPCG ces derniers temps, cela m'a posé une question ...

Tâche:

Étant donné un nombre entier positif N> 4, trouvez les nombres premiers solitaires ( nombres premiers isolés AKA ) entre les couples les plus proches de nombres premiers jumeaux .

Veuillez noter que dans ce cas avec le terme nombres premiers solitaires , je veux dire tous les nombres premiers qui ne sont pas des nombres premiers jumeaux et entre des couples de nombres premiers jumeaux . C'est pourquoi N> 4 parce que les deux premiers couples de nombres premiers sont (3, 5) et (5, 7).

Exemple:

  1. N = 90.
  2. Trouvez les deux premiers couples de nombres premiers jumeaux <N et> N. Ils sont: (71, 73) et (101, 103).
  3. Trouvez les nombres premiers solitaires dans la plage> 73 et <101.
  4. Ils sont: 79, 83, 89, 97.

Cas spéciaux:

  • Si N est entre deux nombres premiers jumeaux, trouvez les couples les plus proches de nombres premiers jumeaux> N + 1 et <N-1. Exemple: N = 72, trouvez les couples les plus proches de nombres premiers jumeaux> 73 et <71 puis excluez de la liste 71 et 73 car ce ne sont pas des nombres premiers solitaires . Donc pour N = 72 le résultat attendu est: 67, 71 , 73 , 79, 83, 89, 97
  • Si N appartient à un couple de nombres premiers jumeaux, par exemple N = 73, les couples de nombres premiers jumeaux les plus proches sont (71, 73) et (101, 103). Si N = 71, les couples de nombres premiers jumeaux les plus proches sont (59, 61) et (71, 73).

Cas de test:

N = 70   >  Lonely primes are:  67
N = 71   >  Lonely primes are:  67
N = 72   >  Lonely primes are:  67, 79, 83, 89, 97 (not the twins 71 and 73)
N = 73   >  Lonely primes are:  79, 83, 89, 97 
N = 90   >  Lonely primes are:  79, 83, 89, 97
N = 201  >  Lonely primes are:  211, 223
N = 499  >  Lonely primes are:  467, 479, 487, 491, 499, 503, 509

Règles:

  • Écrivez un programme ou une fonction complète qui prendra le nombre N de l'entrée standard.
  • Afficher la liste des nombres premiers solitaires dans un format lisible comme csv, liste, tableau, etc.
  • Le code le plus court gagne.
  • Veuillez inclure (si possible) un violon en ligne testable.
Mario
la source
4
Quelle est la sortie attendue pour des entrées comme 71, 72 ou 73?
Martin Ender
1
Lonely Prime AKA Isolated Prime
Digital Trauma
@MartinEnder J'ai étendu ma question avec des cas spéciaux. Merci pour la clarification.
Mario
1
Je trouve que les cas spéciaux gâchent un peu le défi (et ont été ajoutés alors que certaines réponses avaient déjà été publiées)
Luis Mendo
1
@JonathanAllan Oui, vous pouvez considérer N> 4 parce que les deux premiers couples de nombres premiers jumeaux sont (3, 5) et (5, 7). J'ai ajouté la spécification pour qu'elle soit claire pour tout le monde.
Mario

Réponses:

2

En fait, 47 octets

Cette solution traite du cas où se ntrouve entre deux nombres premiers jumeaux, en vérifiant si la limite inférieure est la plus grande d'une paire de nombres premiers jumeaux (en éliminant le premier jumeau à gauche de nous d'être notre limite inférieure) et si la limite supérieure est le plus petit d'une paire de nombres premiers jumeaux (en éliminant le nombre premier jumeau à droite de nous d'être notre limite supérieure). Pour éviter que les nombres premiers jumeaux soient inclus dans notre plage une fois que nous avons les limites inférieure et supérieure, nous devons supprimer les nombres premiers pp-2OR p+2est premier, d'où le OU logique et la négation dans le code.

C'est un peu long et peut probablement être joué plus loin. Suggestions de golf bienvenues. Essayez-le en ligne!

╗1`╜+;⌐p@p&`╓F╜+1`╜-;¬p@p&`╓F╜-x`;;¬p@⌐p|Y@p&`░

Ungolfing

╗         Store implicit input n in register 0.

1`...`╓   Get the first value x for which the following function f returns a truthy value.
  ╜         Push n from register 0.
  +         Add x to n.
  ;⌐        Duplicate n+x and add 2 to a copy of n+x.
  p         Check if n+x+2 is prime.
  @p        Swap n+x to TOS and check if n+x is prime.
  &         Logical AND the two results.
F         Push the first (and only) result of previous filtering
╜+        Add that result to n to get the upper bound for our solitude.

1`...`╓   Get the first value x for which the following function f returns a truthy value.
  ╜         Push n from register 0.
  -         Subtract x from n.
  ;¬        Duplicate n-x and subtract 2 from a copy of n-x.
  p         Check if n-x-2 is prime.
  @p        Swap n-x to TOS and check if n-x is prime.
  &         Logical AND the two results.
F         Push the first (and only) result of previous filtering.
╜-        Subtract that result from n to get the lower bound for our solitude.

x`...`░   Push values of the range [a...b] where f returns a truthy value. Variable m.
  ;;        Duplicate m twice.
  ¬p        Check if m-2 is prime.
  @⌐p       Check if m+2 is prime. 
  |Y        Logical OR the results and negate.
             This eliminates any numbers with neighboring primes.
  @p        Check if m is prime.
  &         Logical AND primality_check(m) and the previous negation.
             This keeps every other prime number in the range.
Sherlock9
la source
Je n'obtiens pas la sortie attendue 23lorsque l'entrée 24est donnée. Les bornes principales jumelles doivent être 17 / 19et 29 / 31, et 23est un nombre premier isolé dans la plage 19 .. 29.
AdmBorkBork
@TimmyD Oh pour l'amour des esolangs. Soit le bogue où pdit 25est premier n'a pas encore été corrigé, soit Dennis n'a pas été retiré depuis la correction du bogue. Laisse-moi aller vérifier.
Sherlock9
@TimmyD Comme la correction de bogue était déjà terminée, cette réponse est toujours valable car l'interprète principal a fonctionné. C'était juste que l'interprète en ligne, Try It Online, n'avait pas encore été mis à jour. Il a depuis été mis à jour et TIO devrait fonctionner maintenant.
Sherlock9
Oui - merci pour l'explication!
AdmBorkBork
8

PowerShell v2 +, 237 149 147 231 216 181 174 169 169 166 octets

param($n)filter f($a){'1'*$a-match'^(?!(..+)\1+$)..'}for($i=$n;!((f $i)-and(f($i+2)))){$i++}for(){if(f(--$i)){if((f($i-2))-or(f($i+2))){if($i-lt$n-1){exit}}else{$i}}}

Prend des informations $n. Définit une nouvelle fonction fcomme fonction regex prime (renvoyant ici un booléen si l'entrée est un nombre premier ou non).

La partie suivante $iest égale à $n, puis se boucle vers le haut jusqu'à ce que nous trouvions la moitié inférieure de notre borne supérieure jumelle. Par exemple, pour l'entrée 90, cela s'arrête à $i=101.

Ensuite, nous bouclons de la borne supérieure vers le bas. Je sais, ça ressemble à une boucle infinie, mais ça finira par finir.

Si le nombre actuel est un nombre premier ( f(--$i)), mais que ce +/- 2 n'est pas un nombre premier, nous ajoutons $iau pipeline. Cependant, s'il +/- 2s'agit d'un nombre premier, nous vérifions si nous sommes inférieurs à $n-1(c'est-à-dire pour tenir compte de la situation lorsqu'elle se trouve à l'intérieur d'une paire principale jumelle), moment auquel nous exit. À la fin du programme, le pipeline est imprimé à l'écran via implicite Write-Output.

NB - En raison de la structure en boucle, imprime les nombres premiers dans l'ordre décroissant. OP a précisé que c'était OK.

Exemples

La sortie ici est séparée par des espaces, car c'est la méthode de stringification par défaut pour un tableau.

PS C:\Tools\Scripts\golfing> 70,71,72,73,90,201,499,982|%{"$_ --> "+(.\the-solitude-of-prime-numbers.ps1 $_)}
70 --> 67
71 --> 67
72 --> 97 89 83 79 67
73 --> 97 89 83 79
90 --> 97 89 83 79
201 --> 223 211
499 --> 509 503 499 491 487 479 467
982 --> 1013 1009 997 991 983 977 971 967 953 947 941 937 929 919 911 907 887
AdmBorkBork
la source
4

Haskell, 105 octets

p x=all((>0).mod x)[2..x-1]
a%x=until(\z->p z&&p(z+2*a))(+a)x
f n=[x|x<-[(-1)%n+1..1%n-1],p x,1%x>x,(-1)%x<x]

Essayez-le en ligne

Damien
la source
3

JavaScript, 186 183 168 158 octets

// solution:
function d(d){function p(n){for(i=n;n%--i;);return!--i}u=d;for(;!p(d--)||!p(--d););for(;!p(u++)||!p(++u););for(;++d<u;)if(p(d)&&!p(d-2)&&!p(d+2))console.log(d)}

// runnable test cases:
console.info('Test ' + 70);
d(70);
console.info('Test ' + 71);
d(71);
console.info('Test ' + 72);
d(72);
console.info('Test ' + 73);
d(73);
console.info('Test ' + 90);
d(90);
console.info('Test ' + 201);
d(201);
console.info('Test ' + 499);
d(499);

user470370
la source
Bienvenue chez PPCG! Belle première réponse.
AdmBorkBork
2

PHP, 207 octets

47 54 octets pour la is_primefonction que PHP n'a pas. J'aurais battu Mathematica sans ça. :-RÉ

function p($n){for($i=$n>1?$n:4;$n%--$i;);return$i<2;}if(p($n=$argv[1])&p($n+2)|$z=p($n-1)&p($n+1))$n-=2;for($n|=1;!p($n)|!p($n-2);$n--);for($z++;$z--;$n+=2)for(;$n+=2;)if(p($n)){if(p($n+2))break;echo"$n,";}

courir avec -r. imprime une virgule de fin.

panne

// is_prime function:
// loops from $n-1 down to 1, breaks if it finds a divisor.
// returns true if divisor is <2 (==1)
// special case $n==1: initialize $i=4 to prevent warnings
function p($n){for($i=$n>1?$n:4;$n%--$i;);return$i<2;}

// is $n between primes?
if($z=p(1+$n=$argv[1])&p($n-1)) // set $z to go to the _second_ twin pair above
    $n-=2;
// no:
else
    if(p($n)&p($n+2))$n-=2;     // $n is part of the upper pair
    // p($n)&p($n-2):           // $n is part of the lower pair
    // else:                    // this is a lonely (isolated) prime

// 1. find closest twins <=$n
for($n|=1;!p($n)|!p($n-2);$n--);

// 2. list primes until the next twin primes
L:
for(;$n+=2;)if(p($n))
    if(p($n+2))break;       // next twin primes found: break loop
    else echo"$n,";         // isolated prime: print

// 3. if ($z) repeat (once)
$n+=2;  // skip twin pair
if($z--)goto L;

Remarque :

La is_primefonction retourne en fait truepour $n<2; mais au moins cela ne produit pas d'avertissement. Insérez $n=avant $n>1de fixer.

Titus
la source
php.net/manual/en/function.gmp-nextprime.php cette bibliothèque pourrait-elle aider?
Jörg Hülsermann
@ JörgHülsermann: Si donnerait au moins 11 octets, si gmp serait dans l'installation standard. Essayez-le.
Titus
1

Mathematica, 169 157 octets

Select[PrimeQ]@Sort@Flatten@{If[q@#,0,#],Most@NestWhileList[i-=2;#+i&,#,!q@#&]&/@(i=3;q=PrimeQ@#&&Or@@PrimeQ[{2,-2}+#]&;#+{1,-1}(1+Boole@PrimeQ[{1,-1}+#]))}&
JungHwan Min
la source
1

Raquette 228 octets

(λ(n)(let*((t 0)(lr(λ(l i)(list-ref l i)))(pl(drop(reverse(for/list((i(in-naturals))#:when(prime? i)#:final(and(> i n)
(= 2(- i t))))(set! t i)i))2)))(for/list((i(length pl))#:break(= 2(-(lr pl i)(lr pl(add1 i)))))(lr pl i))))

L'inconvénient de cette version est qu'elle trouve tous les nombres premiers jusqu'à N et pas seulement ceux autour de N.

Version non golfée:

(define (f n)
  (let* ((t 0)
         (lr (λ(l i) (list-ref l i)))
         (pl (drop(reverse  
                   (for/list ((i (in-naturals))
                              #:when (prime? i)
                              #:final (and
                                       (> i n)
                                       (= 2 (- i t))))
                     (set! t i)
                     i)) 2)))
    (for/list ((i (length pl))
               #:break (= 2 (- (lr pl i) (lr pl (add1 i)))) )
      (lr pl i)))
)

Essai:

(f 90)

Sortie:

'(97 89 83 79)
rnso
la source
1

Raquette 245 octets

(λ(n)(let((pl(reverse(let lp((n n)(t 0)(ol '()))(set! t(prev-prime n))(if(and(>(length ol)0)
(= 2(-(car ol)t)))(cdr ol)(lp t 0(cons t ol)))))))(let lq((n n)(t 0)(ol pl))(set! t(next-prime n))
(if(= 2(- t(car ol)))(cdr ol)(lq t 0(cons t ol))))))

Version non golfée:

(require math)
(define f
  (lambda(n)
    (let ((pl 
           (reverse
            (let loop ((n n) (t 0) (ol '()))
              (set! t (prev-prime n))
              (if (and
                   (> (length ol) 0)
                   (= 2 (- (car ol) t)))
                  (cdr ol)
                  (loop t 0 (cons t ol)))))))
      (let loop2 ((n n) (t 0) (ol pl))
        (set! t (next-prime n))
        (if (= 2 (- t (car ol)))
            (cdr ol)
            (loop2 t 0 (cons t ol))))))
  )

(f 90)

Sortie:

'(97 89 83 79)
rnso
la source
1

Python 2.7: 160 octets

t=lambda n:all(n%d for d in range(2,n))
def l(n):
 i=n
 while t(i)*t(i+2)-1:i+=1
 while t(n)*t(n-2)-1:n-=1
 print[x for x in range(n,i)if t(x)&~(t(x-2)|t(x+2))]

les suggestions sont les bienvenues :)

Aaron
la source