La solitudine dei numeri primi


24

Di recente ho letto il romanzo "La solitudine dei numeri primi" in cui i personaggi principali sono in qualche modo confrontati con i numeri primi gemelli (" sempre insieme, ma mai toccanti ").

Un numero primo gemello è un numero primo che è 2 in meno o 2 in più rispetto a un altro numero primo, ad esempio la coppia di numeri primi gemelli (41, 43). In altre parole, un numero primo gemello è un numero primo che ha un divario primo di due. A volte il termine gemello primo è usato per una coppia di numeri primi gemelli; un nome alternativo per questo è primo gemello o prima coppia. Wikipedia

Sebbene il romanzo deprimente non mi piacesse molto e da quando sono caduto nel PPCG ultimamente, questo mi ha fatto sorgere una domanda ...

Compito:

Dato un numero intero positivo N> 4, trova i numeri primi solitari ( numeri primi isolati AKA ) tra le coppie più vicine di numeri primi gemelli .

Si noti che in questo caso con il termine numeri primi solitari , intendo tutti i numeri primi che non sono numeri primi gemelli e tra coppie di numeri primi gemelli . Ecco perché N> 4 perché le prime due coppie di numeri primi sono (3, 5) e (5, 7).

Esempio:

  1. N = 90.
  2. Trova le prime due coppie di numeri primi gemelli <N e> N. Sono: (71, 73) e (101, 103).
  3. Trova i numeri primi solitari nella gamma> 73 e <101.
  4. Sono: 79, 83, 89, 97.

Casi speciali:

  • Se N è compreso tra due numeri primi gemelli, trova le coppie più vicine di numeri primi gemelli> N + 1 e <N-1. Esempio: N = 72, trova le coppie più vicine di numeri primi gemelli> 73 e <71 quindi escludi dall'elenco 71 e 73 perché non sono numeri primi soli . Quindi per N = 72 il risultato atteso è: 67, 71 , 73 , 79, 83, 89, 97
  • Se N appartiene a una coppia di numeri primi gemelli, ad esempio N = 73, le coppie più vicine di numeri primi gemelli sono (71, 73) e (101, 103). Se N = 71, le coppie più vicine di numeri primi gemelli sono (59, 61) e (71, 73).

Casi 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

Regole:

  • Scrivi un programma o una funzione completa che prenderà il numero N dall'input standard.
  • Stampa l'elenco di numeri primi solitari in un formato leggibile come csv, list, array, ecc.
  • Il codice più corto vince.
  • Si prega di includere (quando possibile) un violino online testabile.

4
Qual è l'output previsto per input come 71, 72 o 73?
Martin Ender,

1
Lonely Prime AKA Isolated Prime
Digital Trauma

@MartinEnder Ho esteso la mia domanda con casi speciali. Grazie per il chiarimento.
Mario,

1
Trovo che i casi speciali rovinino un po 'la sfida (e sono stati aggiunti quando alcune risposte erano già state pubblicate)
Luis Mendo,

1
@JonathanAllan Sì, puoi considerare N> 4 perché le prime due coppie di numeri primi gemelli sono (3, 5) e (5, 7). Ho aggiunto le specifiche per renderlo chiaro a tutti.
Mario,

Risposte:


2

In realtà, 47 byte

Questa soluzione si occupa del caso in cui si ntrova tra due numeri primi gemelli, controllando se il limite inferiore è il più grande di una coppia di numeri primi gemelli (eliminando il primo gemello a sinistra di noi dal nostro limite inferiore) e se il limite superiore è il più piccolo di una coppia di numeri primi gemelli (eliminando il primo gemello a destra di noi dal nostro limite superiore). Per evitare che i numeri primi gemelli vengano inclusi nel nostro intervallo una volta che abbiamo i limiti inferiore e superiore, dobbiamo rimuovere i numeri primi in pcui gli p-2OR p+2sono primi, quindi l'OR logico e negare nel codice.

Questo è un po 'lungo e probabilmente può essere ulteriormente giocato a golf. Suggerimenti di golf benvenuti. Provalo online!

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

Non ottengo l'output previsto 23quando 24viene fornito l' input . I limiti dei gemelli primi dovrebbero essere 17 / 19e 29 / 31, ed 23è un primo isolato nell'intervallo 19 .. 29.
AdmBorkBork,

@TimmyD Oh per l'amore degli esolang. O il bug in cui si pdice che 25è primo non è stato ancora risolto, oppure Dennis non è stato effettivamente rimosso dalla correzione del bug. Fammi andare a controllare.
Sherlock9,

@TimmyD Poiché la correzione del bug era già stata completata, questa risposta è ancora valida poiché l'interprete principale ha funzionato. Era solo che l'interprete online, Try It Online, non era stato ancora aggiornato. Da allora è stato aggiornato e TIO dovrebbe funzionare ora.
Sherlock9,

Sì, grazie per la spiegazione!
AdmBorkBork,

8

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

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

Accetta input $n. Definisce una nuova funzione fcome funzione regex prime (qui restituisce un valore booleano se l'input è un numero primo o no).

La parte successiva si imposta $iper essere uguale a $n, quindi scorre verso l'alto fino a quando non troviamo la metà inferiore del nostro limite superiore della nostra prima coppia gemella. Ad esempio, per l'input 90, questo si ferma a $i=101.

Quindi, passiamo dal limite superiore verso il basso. Lo so, sembra un ciclo infinito, ma alla fine finirà.

Se il numero attuale è un numero primo ( f(--$i)), ma il suo +/- 2 non è un numero primo, aggiungiamo $ial gasdotto. Tuttavia, se si +/- 2tratta di un numero primo, controlliamo se siamo più bassi di $n-1(cioè, per tenere conto della situazione quando si trova all'interno di una coppia di numeri primi gemelli), a quel punto noi exit. Al completamento del programma, la pipeline viene stampata sullo schermo tramite implicito Write-Output.

NB: grazie alla struttura ad anello, stampa i numeri primi in ordine decrescente. OP ha chiarito che va bene.

Esempi

L'output qui è separato dallo spazio, in quanto è il metodo di stringa di default per un array.

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

4

Haskell, 105 byte

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]

Provalo online


3

JavaScript, 186 183 168 158 byte

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


Benvenuti in PPCG! Bella prima risposta.
AdmBorkBork,

2

PHP, 207 byte

47 54 byte per la is_primefunzione che PHP non ha. Avrei battuto Mathematica senza quello. :-D

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

corri con -r. stampa una virgola finale.

abbattersi

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

Nota :

La is_primefunzione effettivamente ritorna trueper $n<2; ma almeno non genera un avvertimento. Inserisci $n=prima $n>1di risolvere.



@ JörgHülsermann: se darebbe almeno 11 byte, se gmp sarebbe nell'installazione standard. Provalo.
Tito,

1

Mathematica, 169 157 byte

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}+#]))}&

1

Racchetta 228 byte

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

Lo svantaggio di questa versione è che trova tutti i numeri primi fino a N e non solo quelli intorno a N.

Versione non golfata:

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

test:

(f 90)

Produzione:

'(97 89 83 79)

1

Racchetta 245 byte

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

Versione non golfata:

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

Produzione:

'(97 89 83 79)

1

Python 2.7: 160 byte

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

suggerimenti sono ben accetti :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.