Numeri di Primes con indice primo


13

Scrivere un programma o una funzione che emetta / restituisca i primi 10000 numeri primi indicizzati in numeri primi.

Se chiamiamo l' ennesimo numero primo p(n), questo è l'elenco

3, 5, 11, 17, 31, 41, 59 ... 1366661

perché

p(p(1)) = p(2) = 3
p(p(2)) = p(3) = 5
p(p(3)) = p(5) = 11
p(p(4)) = p(7) = 17
...
p(p(10000)) = p(104729) = 1366661

Sono vietate le scappatoie standard e sono consentiti metodi di output standard. Puoi rispondere con un programma completo, una funzione con nome o una funzione anonima.


2
Dovresti generalmente provare a pubblicare prima le sfide nella sandbox (vedi il link a destra) per risolvere i problemi.
Aditsu ha smesso perché SE è MALE

6
L'ottimizzazione per il runtime non è ciò che facciamo in una sfida di code-golf; vince sempre il programma più breve.
lirtosiast,

1
Primes con abbonamenti primi: A006450 .

1
@bilbo Le risposte per il golf del codice sono generalmente accettate dopo una settimana e devono essere accettate come codice di successo più breve . Se volevi la velocità del codice , c'è un tag per quello. Vedi questa pagina sul tag code-golf .
Addison Crump,

1
Tutti i concorsi necessitano di un criterio obiettivo vincente; altrimenti sono fuori tema. Se giudicherai le risposte in base a dimensioni e velocità, devi indicare un modo per combinare entrambi. Questo dovrebbe essere fatto quando il concorso viene pubblicato, non dopo 14 ore e 10 risposte in seguito. Ho annullato tutte le modifiche relative alla velocità, poiché l'unica altra opzione sarebbe quella di chiudere questo post per essere fuori tema.
Dennis,

Risposte:


15

MATLAB / Octave, 25 byte

p=primes(2e6)
p(p(1:1e4))

Non è molto più semplice di così.


9

Python, 72 byte

P=p=1;l=[]
while p<82e5/6:l+=P%p*[p];P*=p*p;p+=1
for x in l:print l[x-1]

Ciò termina con un "errore elenco fuori intervallo" dopo la stampa dei 10000 numeri, che è consentito per impostazione predefinita .

Utilizza il metodo del teorema di Wilson per generare un elenco ldi numeri primi fino al 10000esimo numero primo. Quindi, stampa i numeri primi con le posizioni nell'elenco, spostati di 1 per l'indicizzazione zero, fino a quando non finiamo i limiti dopo il 10000esimo primo-primo primo.

Per comodità, il limite superiore di 1366661può essere stimato come 82e5/6che è 1366666.6666666667, il salvataggio di un char.

Vorrei un metodo a ciclo singolo, stampa dei numeri primi indicizzati come li aggiungiamo, ma sembra essere più lungo.

P=p=1;l=[]
while p<104730:
 l+=P%p*[p]
 if len(l)in P%p*l:print p
 P*=p*p;p+=1

Questo è molto meglio della spazzatura che stavo scrivendo. +1
Mego,

Questo stampa solo 1229 numeri
aditsu smetti perché SE è MALE

@aditsu Penso di vedere il mio errore. Sei in grado di eseguire questo codice con il limite maggiore?
xnor

Probabilmente ci vorrà molto tempo: p
aditsu smette perché SE è MALE

Penso che sia finito seems (@ ; ◇ ; @) /, sembra corretto
aditsu smetti perché SE è MALE

8

J, 11 byte

p:<:p:i.1e4

Stampa i numeri primi nel formato

3 5 11 17 31 41 59 67 83 109 127 ...

Spiegazione

        1e4  Fancy name for 10000
      i.     Integers from 0 to 9999
    p:       Index into primes: this gives 2 3 5 7 11 ...
  <:         Decrement each prime (J arrays are 0-based)
p:           Index into primes again

4

Mathematica, 26 25 23 byte

Prime@Prime@Range@1*^4&

Funzione pura che restituisce l'elenco.


1
Prime è Listablequindi un semplice Prime@Prime@Range@1*^4&farà

Conosco la sensazione ... In ogni caso, penso che questa sia la più bella soluzione Mathematica che abbia mai visto qui!

Fammi indovinare, l' @operatore ha una precedenza maggiore rispetto a ^quando scrive Range@10^4? È il classico Mathematica che rovina il tuo gioco di golf. Buon trucco!

4

Haskell, 65 byte

p=[x|x<-[2..],all((>0).mod x)[2..x-1]]
f=take 10000$map((0:p)!!)p

Uscite: [3,5,11,17,31,41,59,67,83,109,127.....<five hours later>...,1366661]

Non molto veloce Come funziona: pè l'elenco infinito di numeri primi (che controlla in modo ingenuo tutte le mod x ys per y in [2..x-1]). Prendi i primi 10000elementi dell'elenco che ottieni quando 0:p!!(ottieni l'ennesimo elemento di p) è mappato p. Devo modificare l'elenco dei numeri primi da cui prendo gli elementi anteponendo un numero (-> 0:), perché la funzione indice ( !!) è basata su zero.



3

AWK - 129 byte

... oookay ... troppo tempo per guadagnare punti per compattezza ... ma forse può guadagnare un po 'di onore per la velocità?

Il xfile:

BEGIN{n=2;i=0;while(n<1366662){if(n in L){p=L[n];del L[n]}else{P[p=n]=++i;if(i in P)print n}j=n+p;while(j in L)j=j+p;L[j]=p;n++}}

In esecuzione:

$ awk -f x | nl | tail
  9991  1365913
  9992  1365983
  9993  1366019
  9994  1366187
  9995  1366327
  9996  1366433
  9997  1366483
  9998  1366531
  9999  1366609
 10000  1366661

Leggibile:

BEGIN {
        n=2
        i=0
        while( n<1366662 ) {
                if( n in L ) {
                        p=L[n]
                        del L[n]
                } else {
                        P[p=n]=++i
                        if( i in P ) print n
                }
                j=n+p
                while( j in L ) j=j+p
                L[j]=p
                n++
        }
}

Il programma calcola un flusso di numeri primi usando Lcome "nastro di numeri" tenendo in mano i numeri primi saltando su Lper contrassegnare i numeri vicini già noti per avere un divisore. Questi numeri primi che saltano avanzeranno mentre il "nastro di numeri" Lviene tagliato numero per numero dall'inizio.

Mentre tagliare la testina del nastro L[n]essendo vuota significa che non esiste un divisore (primo) noto.

L[n]detenere un valore significa che questo valore è un numero primo e noto per dividere n.

Quindi o abbiamo trovato un divisore primo o un nuovo primo. Quindi il primo verrà spostato al successivo L[n+m*p]sul nastro trovato vuoto.

Questo è come il setaccio di Eratostene "tirato attraverso una bottiglia di Klein". Agisci sempre all'inizio del nastro. Invece di sparare multipli di numeri primi attraverso il nastro, usi i numeri primi già trovati mentre i cursori che saltano via dal nastro iniziano per più distanze del loro stesso valore fino a quando non viene trovata una posizione libera.

Mentre il ciclo esterno genera una decisione principale o meno per ciclo, i numeri primi trovati vengono contati e memorizzati Pcome chiave, il valore di questa coppia (chiave, valore) non è rilevante per il flusso del programma.

Se la loro chiave si itrova Pgià in ( i in P), abbiamo un numero primo della razza p (p (i)).

In esecuzione:

$ time awk -f x.awk | wc -l
10000

real    0m3.675s
user    0m3.612s
sys     0m0.052s

Tenere presente che questo codice non utilizza tabelle primi precalcolate esterne.

Tempo impiegato sul mio buon vecchio Thinkpad T60, quindi penso che meriti di essere chiamato velocemente.

Testato con mawke gawksu Debian8 / AMD64


buoni 129 byte in gawk: ora con Debian10 / AMD64 sul mio corei7-i870@3.6Ghz: reale 0m2.417s utente 0m2.205s sys 0m0.042s
JeanClaudeDaudin

puoi salvare un byte con: BEGIN {n = 2; i = 0; while (n <1366662) {if (n in L) {p = L [n]; del L [n]} else {P [p = n] = ++ i; if (i in P) stampa n} j = n + p; while (j in L) j + = p; L [j] = p; n ++}}
JeanClaudeDaudin


1

Perl, 55 byte

use ntheory':all';forprimes{print nth_prime$_,$/}104729

Utilizza il modulo di @DanaJMath::Prime::Util per perl (caricato con il pragma ntheory). Ottienilo con:

cpan install Math::Prime::Util
cpan install Math::Prime::Util::GMP

0

05AB1E, 7 byte (non concorrenti)

Codice:

4°L<Ø<Ø

Provalo online! , si noti che ho modificato il 4in a 2. Se hai molto tempo, puoi cambiare la parte 2posteriore 4, ma ci vorrà molto tempo. Ho bisogno di fissare l'algoritmo per questo.

Spiegazione:

4°       # Push 10000 (10 ^ 4)
  L      # Create the list [1 ... 10000]
   <     # Decrement on every element, [0 ... 9999]
    Ø    # Compute the nth prime
     <   # Decrement on every element
      Ø  # Compute the nth prime
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.