Samotność liczb pierwszych

24

Niedawno przeczytałem powieść „Samotność liczb pierwszych”, w której główni bohaterowie są nieco porównani do podwójnych liczb pierwszych („ zawsze razem, ale nigdy nie dotykają ”).

Liczby bliźniacze jest liczbą pierwszą, która jest mniejsza albo dwa lub więcej niż dwa inne liczby pierwszej -do przykład podwójnego głównego pary (41, 43). Innymi słowy, liczba pierwsza bliźniacza jest liczbą pierwszą, która ma pierwszą dwójkę. Czasami termin podwójna liczba pierwsza jest używany dla pary podwójnych liczb pierwszych; alternatywną nazwą tego jest prime twin lub prime pair. Wikipedia

Chociaż nie podobała mi się ta przygnębiająca powieść, a odkąd ostatnio wpadłem w PPCG, to nasuwało mi się pytanie ...

Zadanie:

Biorąc pod uwagę dodatnią liczbę całkowitą N> 4, znajdź samotne liczby pierwsze ( izolowane liczby pierwsze AKA ) między najbliższymi parami liczb pierwszych bliźniaczych .

Proszę zauważyć, że w tym przypadku, z pojęciem samotnych liczb pierwszych , mam na myśli wszystkie liczby pierwsze, które nie są liczbami podwójnymi i pomiędzy parami liczb pierwszych . Dlatego N> 4, ponieważ dwie pierwsze pary liczb pierwszych to (3, 5) i (5, 7).

Przykład:

  1. N = 90.
  2. Znajdź dwie pierwsze pary podwójnych liczb pierwszych <N i> N. Są to: (71, 73) i (101, 103).
  3. Znajdź samotne liczby pierwsze w przedziale> 73 i <101.
  4. Są to: 79, 83, 89, 97.

Przypadki specjalne:

  • Jeśli N znajduje się między dwiema liczbami podwójnymi liczb pierwszych, znajdź najbliższe pary liczb pierwszych> N + 1 i <N-1. Przykład: N = 72, znajdź najbliższe pary liczb pierwszych bliźniaczych> 73 i <71, a następnie wyklucz z listy 71 i 73, ponieważ nie są samotnymi liczbami pierwszymi . Tak więc dla N = 72 oczekiwany wynik to: 67, 71 , 73 , 79, 83, 89, 97
  • Jeśli N należy do dwóch liczb pierwszych bliźniaczych, na przykład N = 73, najbliższymi parami liczb pierwszych bliźniaczych są (71, 73) i (101, 103). Jeśli N = 71, najbliższymi parami bliźniaczych liczb pierwszych są (59, 61) i (71, 73).

Przypadki testowe:

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

Zasady:

  • Napisz pełny program lub funkcję, która pobierze liczbę N ze standardowego wejścia.
  • Wypisuje listę samotnych liczb pierwszych w czytelnym formacie jako csv, lista, tablica itp.
  • Najkrótszy kod wygrywa.
  • Podaj (jeśli to możliwe) testowe skrzypce online.
Mario
źródło
4
Jaka jest oczekiwana wydajność dla danych wejściowych takich jak 71, 72 lub 73?
Martin Ender
1
Lonely Prime AKA Isolated Prime
Digital Trauma
@MartinEnder Rozszerzyłem moje pytanie o specjalne przypadki. Dziękuję za wyjaśnienie.
Mario,
1
Uważam, że specjalne przypadki trochę psują wyzwanie (i zostały dodane, gdy niektóre odpowiedzi zostały już opublikowane)
Luis Mendo
1
@JonathanAllan Tak, możesz rozważyć N> 4, ponieważ dwie pierwsze pary podwójnych liczb pierwszych to (3, 5) i (5, 7). Dodałem specyfikację, aby było jasne dla wszystkich.
Mario,

Odpowiedzi:

2

Właściwie 47 bajtów

To rozwiązanie dotyczy przypadku, w którym nznajduje się między dwiema liczbami podwójnymi, sprawdzając, czy dolna granica jest większa z pary podwójnych liczb pierwszych (eliminując podwójną liczbę pierwszą po lewej stronie od bycia naszą dolną granicą) i czy górna granica jest mniejszy pary liczb pierwszych bliźniaczych (eliminując Prime bliźniaka na prawo od nas od bycia nasza górna granica). Aby zapobiec włączeniu bliźniaczych liczb pierwszych do naszego zakresu, gdy mamy dolną i górną granicę, musimy usunąć liczby pierwsze ptam, gdzie p-2OR p+2jest liczbą pierwszą, stąd logiczne OR i negować w kodzie.

Jest to trochę długi i prawdopodobnie można go jeszcze pograć w golfa. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj 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.
Sherlock9
źródło
Nie otrzymuję oczekiwanego wyniku, 23gdy 24podano dane wejściowe . Te liczby bliźniacze granice powinny być 17 / 19i 29 / 31, i 23jest to odosobniony w zakresie podstawowym 19 .. 29.
AdmBorkBork
@TimmyD Oh za miłość do esolangów. Albo błąd, w którym pmówi się, że 25jest liczbą pierwszą, nie został jeszcze naprawiony, lub Dennis nie ściągnął Właściwie od czasu naprawy błędu. Pozwól mi sprawdzić.
Sherlock9,
@TimmyD Ponieważ poprawka została już ukończona, ta odpowiedź jest nadal aktualna, ponieważ działał główny interpreter. Po prostu tłumacz online Try It Online nie został jeszcze zaktualizowany. Od tego czasu został zaktualizowany i TIO powinno teraz działać.
Sherlock9
Tak - dziękuję za wyjaśnienie!
AdmBorkBork
8

PowerShell v2 +, 237 149 147 231 216 181 174 169 166 bajtów

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

Pobiera dane wejściowe $n. Definiuje nową funkcję fjako funkcję regularną wyrażenia regularnego (tutaj zwraca wartość logiczną, jeśli wejście jest liczbą pierwszą, czy nie).

Następna część $ijest równa $n, a następnie zapętla się w górę, aż znajdziemy dolną połowę górnej granicy podwójnej pary pierwszej. Np. Dla wprowadzania 90zatrzymuje się na $i=101.

Następnie zapętlamy od górnej granicy w dół. Wiem, wygląda na nieskończoną pętlę, ale ostatecznie się skończy.

Jeśli aktualna liczba jest liczbą pierwszą ( f(--$i)), ale jej +/- 2 nie jest liczbą pierwszą, dodajemy $ido rurociągu. Jeśli jednak +/- 2jest liczbą pierwszą, sprawdzamy, czy jesteśmy niżsi niż $n-1(tj. W celu uwzględnienia sytuacji, gdy znajduje się w podwójnej parze liczb pierwszych), w którym momencie my exit. Po zakończeniu programu potok jest drukowany do ekranowania przez domniemanie Write-Output.

NB - Ze względu na strukturę pętli drukuje liczby pierwsze w kolejności malejącej. OP wyjaśniła, że ​​to w porządku.

Przykłady

Dane wyjściowe są tutaj oddzielone spacjami, ponieważ jest to domyślna metoda stringowania dla tablicy.

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
źródło
4

Haskell, 105 bajtów

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]

Wypróbuj online

Damien
źródło
3

JavaScript, 186 183 168 158 bajtów

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

użytkownik470370
źródło
Witamy w PPCG! Ładna pierwsza odpowiedź.
AdmBorkBork
2

PHP, 207 bajtów

47 54 bajtów dla is_primefunkcji, której PHP nie ma. Pokonałbym Mathematica bez tego. :-RE

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

biegać z -r. drukuje przecinek końcowy.

awaria

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

Uwaga :

is_primeFunkcja faktycznie wraca truedo $n<2; ale przynajmniej nie daje ostrzeżenia. Wstaw $n=przed, $n>1aby naprawić.

Tytus
źródło
php.net/manual/en/function.gmp-nextprime.php czy ta biblioteka może pomóc?
Jörg Hülsermann
@ JörgHülsermann: Gdyby dał co najmniej 11 bajtów, gdyby gmp był w standardowej instalacji. Spróbuj.
Tytus
1

Mathematica, 169 157 bajtów

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
źródło
1

Rakieta 228 bajtów

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

Wadą tej wersji jest to, że wyszukuje wszystkie liczby pierwsze do N, a nie tylko te wokół N.

Wersja bez golfa:

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

Testowanie:

(f 90)

Wydajność:

'(97 89 83 79)
rnso
źródło
1

Rakieta 245 bajtów

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

Wersja bez golfa:

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

Wydajność:

'(97 89 83 79)
rnso
źródło
1

Python 2.7: 160 bajtów

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

sugestie są mile widziane :)

Aaron
źródło