Elencare i numeri primi di Sophie Germain


10

La domanda

Un primo di Sophie Germain è un primo p in modo che anche 2p + 1 sia primo. Ad esempio, 11 è un numero uno di Sophie Germain perché anche 23 è un numero primo. Scrivi il programma più breve per calcolare i numeri primi di Sophie Germain in ordine crescente

Regole

  • I numeri primi di Sophie Germain devono essere generati dal tuo programma, non da una fonte esterna.
  • Il programma deve calcolare tutti i numeri primi di Sophie Germain inferiori a 2³²-1
  • È necessario stampare ogni distinta Sophie Germain prime trovata dal programma.
  • Vince la persona con il punteggio più basso

punteggio

  • 2 punti per byte del tuo codice
  • -10 se riesci a mostrare un numero primo generato dal tuo programma maggiore di 2³²-1

I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Martin Ender,

Risposte:


4

CJam

Per 17 caratteri otteniamo un'enumerazione completa fino a 2 ^ 32:

G8#,{_mp*2*)mp},`

Per 4 caratteri in più, otteniamo un intervallo abbastanza grande da includere un numero primo SG maggiore di 2 ^ 32:

G8#K_*+,{_mp*2*)mp},`

da 4294967681 = 2 ^ 32 + 385 <2 ^ 32 + 400.

Naturalmente, potremmo anche estendere la gamma gratuitamente come

C9#,{_mp*2*)mp},`

Questo significa che puoi inviarlo senza il bonus per 17 personaggi o con il bonus per 21 personaggi
Meow Mix

@ user3502615 o con il bonus per 17 caratteri. Sebbene sia discutibile se l'elenco SG Prime I sia stato effettivamente generato "dal mio programma", dal momento che non ho un computer abbastanza potente per eseguirlo così lontano.
Peter Taylor,

I,considera Iun numero intero a 32 bit con segno, quindi il valore massimo per Iè 2 ** 31 - 1.
Dennis,

2
@Dennis, è una proprietà documentata della lingua o una stranezza dell'implementazione dell'implementazione Java?
Peter Taylor,

Non è documentato, ma il comportamento è coerente sia per Java che per l'interprete online.
Dennis,

3

Pyth, 19 byte * 2 - 10 = 28

Si noti che il compilatore / esecutore online non mostra l'output perché è un ciclo infinito.

K1#~K1I&!tPK!tPhyKK

Ha spiegato:

K1                      K=1
  #                     While true:
   ~K1                  K+=1
      I                 If
       &                logical AND
        !tPK            K is prime
            !tPhyK      2*K+1 is prime (y is double, h is +1)
                  K     Print K

PZnon restituisce un valore di verità o falsità. Restituisce la scomposizione in fattori primi di Z. Test per prime è !tPZ, che controlla se la fattorizzazione in prime contiene solo un fattore.
Jakube,

Sì. Ora funziona. !tPerrori 0e 1ad essere primi, tuttavia, poiché la loro fattorizzazione in primo piano contiene solo 1 fattore. La soluzione semplice è sostituire tutto Zcon Ke assegnare K2all'inizio.
Jakube,

Alcuni altri golf: assegnare K1invece di K2e scambiare if e l'incremento. In questo modo è possibile rimuovere il ). Ed +1*K2è la stessa cosa di hyK.
Jakube,

Ah, avevo appena letto di quelli sulla pagina del tutorial. Funziona
mbomb007

Il compilatore online non mostra un risultato, perché il programma è bloccato in un ciclo infinito. E il sito Web mostra solo l'output, al termine del programma. Ho testato il codice utilizzando il compilatore offline. Funziona.
Jakube,

1

Pyth - 2 * 16 byte - 10 = 22

Utilizza il metodo consueto di controllo primo in Pyth con !tPe lo applica sia al numero sia al suo numero primo sicuro, con un piccolo trucco per controllare entrambi contemporaneamente. Va su 10^10, quindi vado per il bonus.

f!+tPTtPhyTr2^TT

Spiegazione in arrivo.

f          r2^TT     Filter from 2 till 10^10
 !                   Logical not to detect empty lists
  +                  List concatenation
   tP                All but the firs element of the prime factorization
    T                The filter element
   tP                All but the firs element of the prime factorization
    hyT              2n+1

Prova meno di 1000 online .


1
Questo richiede una macchina con circa 40 GB di memoria RAM. Abbastanza efficiente ;-)
Jakube,

Non penso che tu possa rivendicare il - 10 a meno che tu non abbia effettivamente eseguito correttamente il codice?
orlp,

@orlp no, ho chiesto a OP e mi ha detto che sarebbe sufficiente ridurre
Maltysen,

1
#include<stdio.h>
#include<math.h>

int isprime(int);
int main(){
    int check,n,secondcheck;
    printf("enter how long you want to print\n");
    scanf("%d",&n);
    for(int i=2;i<n;i++){
        check = isprime(i);
        if(check==0){
        secondcheck = isprime(2*i+1);
        if(secondcheck==0){
        printf("%d\t",i);
        }
        else
        continue;
        }
    }
}
int isprime(int num){   
    int check = num,flag=0;
     num = sqrt(num);
    for(int i=2;i<=num;i++){
        if(check%i==0){
            flag=1;
            return 1;
        }
    }
    if(flag==0){
        return 0;
    }
}

3
Si prega di prendere in considerazione il golf del programma (rimuovendo lo spazio ... ecc) e vedere fino a dove si può arrivare.
Mhmd,

0

CJam, 34 (2 * 22 - 10)

C9#{ImpI2*)mp&{Ip}&}fI

Stampa tutti i numeri primi di Sophie Germain sotto 12 ** 9, che include 4294967681 > 2 ** 32.

Stimo che ci vorranno circa 8 ore sulla mia macchina. Lo eseguirò stasera.


0

Haskell, 2 * 54-10 = 98 132

i a=all((>0).rem a)[2..a-1]
p=[n|n<-[2..],i n,i$2*n+1]

iè un primo controllo. pprende tutti i numeri ndove entrambi ne 2*x+1sono primi. pè un elenco infinito.

Modifica: modo migliore per verificare se 2*n+1è primo.


0

Julia, 2 * 49 - 10 = 88

p=primes(2^33)
print(p[map(n->isprime(2n+1),p)])

Li stampa in formato elenco, [2,3,5,11,...]. Se tale formato, l'utilizzo della primesfunzione o l'attesa del completamento del calcolo per la stampa non sono accettabili, vengono stampati uno per riga durante l'esecuzione.

isprime=f
for i=1:2^33;f(i)&&f(2i+1)&&println(i)end

È un po 'più lungo, 52 caratteri. Entrambi calcolano tutti i numeri primi di Sophie Germain 2^33, quindi dovrebbero ottenere lo sconto di 10 punti.


0

Python 3, 124 123 byte

i=3
q=[2]
while 1:
 p=1
 for x in range(2,round(i**.5)+1):p=min(p,i%x)
 if p:
  q+=[i];s=(i-1)/2
  if s in q:print(s)
 i+=2

Come funziona?

i=3                                 # Start at 3
q=[2]                               # Create list with first prime (2), to be list of primes.
while 1:                            # Loop forever
 p=1                                # Set p to 1 (true)
 for x in range(2,round(i**0.5)+1): # Loop from 2 to the number's square root. x is the loop value
     p=min(p,i%x)                   # Set p to the min of itself and the modulo of
                                    # the number being tested and loop value (x).
                                    # If p is 0 at the end, a modulo was 0, so it isn't prime.
 if p:                              # Check if p is 0
  q+=[i]                            # Add the current number (we know is prime) to list of primes (q)
  s=(i-1)/2                         # Generate s, the number that you would double and add 1 to make a prime.

  if s in q:print(s)                # If (i-1)/2 is a prime (in the list), then that prime satifies
                                    # the condition 2p+1 is prime because i is 2p+1, and i is prime
 i+=2                               # Increment by 2 (no even numbers are prime, except 2)

Provalo online qui .


Il mio computer dice che ha generato lo 0,023283% di tutti i numeri primi di Sophie Germain inferiori a 2 ^ 32.

Al termine, lo posterò su pastebin se ci sono abbastanza righe. Puoi usarlo per verificare di averli tutti.


.5è più corto di0.5
mbomb007

0

Perl, 2 * 57-10 = 104

use ntheory":all";forprimes{say if is_prime(2*$_+1)}2**33

2
3
5
11
...
8589934091
8589934271

42 secondi a 2 ^ 32, 1m26s a 2 ^ 33. Funzionerà più velocemente del 50% se 2*$_+1è scritto come1+$_<<1 ma questo è un altro byte.

Il modulo installa anche primes.plche ha molti filtri incluso uno per i numeri primi di Sophie-Germain. Quindi: primes.pl --so 2**33(20 byte)


0

Rubino, 61 * 2 - 10 = 112

require'prime';Prime.each(1.0/0)do|n|p Prime.prime?(n*2+1)end

Ci vorrebbe un'eternità per stampare tutti i valori fino a 2 ** 32

modificare

Eliminato alcuni byte sostituendo Float :: INFINITY per 1.0 / 0


0

PARI / GP, 46 * 2 - 10 = 82

forprime(p=2,2^33,if(isprime(2*p+1),print(p)))
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.