Funzione di conteggio Prime


28

introduzione

La funzione di conteggio dei primi , nota anche come funzione Pi , restituisce la quantità di numeri primi minore o uguale a x.π(x)

Sfida

Il tuo programma prenderà un intero x che puoi assumere come positivo e produrrà un singolo intero uguale alla quantità di numeri primi minore o uguale a x. Questa è una sfida di , quindi il vincitore sarà il programma con il minor numero di byte.

Puoi usare qualsiasi linguaggio di tua scelta a condizione che esistesse prima che questa sfida si sollevasse, ma se il linguaggio ha una funzione di conteggio dei primi integrata o una funzione di controllo della primalità (come Mathematica), quella funzione non può essere utilizzata nel tuo codice .

Ingressi di esempio

Ingresso:
1
Uscita:
0

Ingresso:
2
Uscita:
1

Ingresso:
5
Uscita:
3

A000720 - OEIS


3
Che dire di altre funzioni relative a prime? Ad esempio, "next prime" funciton
Luis Mendo,

6
che dire delle funzioni di scomposizione in fattori primi?
Maltysen,

4
Benvenuti in Puzzle di programmazione e Code Golf!
Adnan,

6
Come ha detto Adnan, benvenuto in PPCG! Per le sfide future, lasciatemi consigliare Sandbox in cui è possibile pubblicare una sfida per ottenere feedback e critiche significative prima di pubblicarlo sul sito principale.
AdmBorkBork,

Penso che questo sia ciò che @TheBikingViking intendeva collegare a: correlati
mbomb007

Risposte:


36

05AB1E , 3 byte

!fg

Ciò presuppone che siano consentiti gli incorporamenti della fattorizzazione. Provalo online!

Come funziona

!    Compute the factorial of the input.
 f   Determine its unique prime factors.
  g  Get the length of the resulting list.

5
È davvero intelligente!
mbomb007,

5
Accidenti, sto ottenendo rekt nella mia lingua per la seconda volta ahah. +1
Adnan,

Perché funziona?
Oliver Ni,

1
@Oliver Perché il fattoriale di n è divisibile per tutti gli interi 1, ..., n (in particolare, i numeri primi p ≤ n ) e per nessun altro primo q> n poiché non può essere espresso come prodotto di numeri più piccoli.
Dennis,

10

Python 2, 45 byte

f=lambda n,k=1,p=1:n/k and p%k+f(n,k+1,p*k*k)

Utilizza il primo generatore di teoremi di Wilson . Il prodotto ptraccia (k-1)!^2ed p%kè 1 per i numeri primi e 0 per i nonprime.


Calcolare il fattoriale dal basso verso l'alto è un grande trucco. +1
ETHproductions

6

MATL , 11, 10, 8 , 5 byte

:pYFn

Provalo online!

Ho scritto una versione che aveva una spiegazione davvero interessante di come funzionano le matrici di MATL:

:YF!s1=1

Ma non è più rilevante. Controlla la cronologia delle revisioni se vuoi vederla.

Nuova spiegazione:

:p      % Compute factorial(input)
  YF    % Get the exponenents of prime factorization
    n   % Get the length of the array

Tre byte salvati grazie alla geniale soluzione di Dennis


È più breve usare la funzione "esponenti della scomposizione in fattori primi", perché si vettorializza:YF!s1=s
Luis Mendo,

@LuisMendo Questo è un approccio totalmente diverso, quindi sentiti libero di andare avanti e pubblicarlo. (Anche se non vuoi, lo farei felicemente)
DJMcMayhem

Vai avanti. Lo porterò a Jelly per esercitarsi :-)
Luis Mendo il

5

Gelatina , 8 5 byte

3 byte salvati grazie a @Dennis!

RÆESL

Provalo online!

Port della risposta MATL di DJMcMayhem (ex versione) perfezionata da Dennis.

R          Range of input argument
 ÆE        List of lists of exponents of prime-factor decomposition
   S       Vectorized sum. This right-pads inner lists with zeros
    L      Length of result

1
Correzione: porto di Luis Mendo: la risposta MATL di DJMcMayhem. : P
DJMcMayhem

2
Hai solo bisogno della lunghezza massima dei risultati di ÆE, poiché ogni esponente corrisponde a un diverso fattore primo. RÆESLraggiunge proprio questo. !ÆELsarebbe ancora più breve.
Dennis,

1
@Dennis Grazie! Ho usato il primo suggerimento. Il secondo è troppo diverso, ed è il tuo approccio
Luis Mendo,

5

Modelli MediaWiki con ParserFunctions , 220 + 19 = 239 byte

{{#ifexpr:{{{2}}}+1={{{1}}}|0|{{#ifexpr:{{{3}}}={{{2}}}|{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{#ifexpr:{{{2}}} mod {{{3}}}=0|{{#expr:1+{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}}+1}}}}}}}}}}}}

Per chiamare il modello:

{{{P|{{{n}}}|2|2}}}

Disposto in stile Lisp:

{{#ifexpr:{{{2}}} + 1 = {{{1}}}|0|
    {{#ifexpr:{{{3}}} = {{{2}}} |
        {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
            {{#ifexpr:{{{2}}} mod {{{3}}} = 0 |
                {{#expr:1 + {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
                {{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}} + 1}}}}}}}}}}}}

Solo un test di primalità di base da 2 a n . I numeri con tre parentesi graffe sono le variabili, dove {{{1}}}è n , {{{2}}}è il numero da testare, {{{3}}}è il fattore da controllare.


5

Perl, 33 byte

Include +1 per -p

Fornire il numero di input su STDIN

primecount.pl

#!/usr/bin/perl -p
$_=1x$_;$_=s%(?!(11+)\1+$)%%eg-2

Fornisce il risultato sbagliato per 0ma va bene, l'op ha richiesto il supporto solo per numeri interi positivi.




4

Gelatina , 13 11 10 9 8 7 6 byte

Non utilizzare nessuna funzione primaria integrata di
-1 byte grazie a @miles (utilizzare una tabella)
-1 byte grazie a @Dennis (convertire da unario a contare i divisori)

ḍþḅ1ċ2

TryItOnline
Oppure guarda i primi 100 termini della serien=[1,100], anche su TryItOnline

Come?

ḍþḅ1ċ2 - Main link: n
 þ     - table or outer product, n implicitly becomes [1,2,3,...n]
ḍ      - divides
  ḅ1   - Convert from unary: number of numbers in [1,2,3,...,n] that divide x
                             (numbers greater than x do not divide x)
    ċ2 - count 2s: count the numbers in [1,2,3,...,n] with exactly 2 divisors
                   (only primes have 2 divisors: 1 and themselves)

1
È possibile arrivare a 7 byte %þ`¬Sċ2utilizzando una tabella di resti.
miglia

1
ḍþḅ1ċ2salva un byte.
Dennis,

4

JavaScript (ES6), 45 43 byte

f=(n,x=n)=>n>1&&(--x<2)+(n%x?f(n,x):f(n-1))

Una modifica della mia funzione di primalità 36 35 33 byte (1 byte salvato da @Neil, 2 da @Arnauld):

f=(n,x=n)=>n>1&--x<2||n%x&&f(n,x)

(Non posso pubblicarlo da nessuna parte perché questo numero è un numero primo? Accetta solo programmi completi ...)

Test snippet


Waw ... mi ci è voluto un po 'di tempo per capire. Bel lavoro!
todeale,

Purtroppo non si applica alla tua risposta, ma probabilmente puoi cavartela con uno &nel mezzo della tua funzione di primalità.
Neil,

3

PowerShell v2 +, 98 byte

param($n)if($j='001'[$n]){}else{for($i=1;$i-lt$n){for(;'1'*++$i-match'^(?!(..+)\1+$)..'){$j++}}}$j

Attenzione: questo è lento per input di grandi dimensioni.

Fondamentalmente la ricerca basata su unario da Questo numero è un numero primo? , accoppiato con un foranello e un $j++contatore. Un po 'di logica aggiuntiva nella parte anteriore per tenere conto dell'input dei casi limite 1e 2, a causa di come funziona la guida di recinzione nei forcircuiti.


3

05AB1E , 5 byte

Presuppone che siano ammessi i builtin di fattorizzazione primaria.

Codice:

LÒ1ùg

Spiegazione:

L      # Get the range [1, ..., input]
 Ò     # Prime factorize each with duplicates
  1ù   # Keep the elements with length 1
    g  # Get the length of the resulting array

Utilizza la codifica CP-1252 . Provalo online!


ÅPgè quello che sarebbe ora, giusto?
Magic Octopus Urn

3

CJam , 7 byte

rim!mF,

Provalo online! Utilizza una funzione di fattorizzazione.

Spiegazione:

ri      | read input as integer
  m!    | take the factorial
    mF  | factorize with exponents (one element per prime)
      , | find length

3

Gelatina , 6 byte

Ḷ!²%RS

Questo utilizza solo l'aritmetica di base e il teorema di Wilson. Provalo online! o verifica tutti i casi di test .

Come funziona

Ḷ!²%RS  Main link. Argument: n

Ḷ       Unlength; yield [0, ..., n - 1].
 !      Factorial; yield [0!, ..., (n - 1)!].
  ²     Square; yield [0!², ..., (n - 1)!²].
    R   Range; yield [1, ..., n].
   %    Modulus; yield [0!² % 1, ..., (n - 1)!² % n].
        By a corollary to Wilson's theorem, (k - 1)!² % k yields 1 if k is prime
        and 0 if k is 1 or composite.
     S  Sum; add the resulting Booleans.


2

Pyth - 7 6 byte

Dato che altri stanno usando le funzioni di fattorizzazione primaria ...

l{sPMS

Test Suite .


2

Bash + coreutils, 30

seq $1|factor|egrep -c :.\\S+$

Ideone.


Bash + coreutils + pacchetto di giochi BSD, 22

primes 1 $[$1+1]|wc -l

Questa risposta più breve richiede di avere il pacchetto installato bsdgames: sudo apt install bsdgames.


2

Pyke, 8 6 byte

SmPs}l

Provalo qui!

Grazie a Maltysen per il nuovo algoritmo

SmP    -    map(factorise, input)
   s   -   sum(^)
    }  -  uniquify(^)
     l - len(^)

2

C #, 157 byte

n=>{int c=0,i=1,j;bool f;for(;i<=n;i++){if(i==1);else if(i<=3)c++;else if(i%2==0|i%3==0);else{j=5;f=1>0;while(j*j<=i)if(i%j++==0)f=1<0;c+=f?1:0;}}return c;};

Programma completo con casi di test:

using System;

class a
{
    static void Main()
    {
        Func<int, int> s = n =>
            {
                int c = 0, i = 1, j;
                bool f;
                for (; i <= n; i++)
                {
                    if (i == 1) ;
                    else if (i <= 3) c++;
                    else if (i % 2 == 0 | i % 3 == 0) ;
                    else
                    {
                        j = 5;
                        f = 1 > 0;
                        while (j * j <= i)
                            if (i % j++ == 0)
                                f = 1 < 0;
                        c += f ? 1 : 0;
                    }
                }
                return c;
            };

        Console.WriteLine("1 -> 0 : " + (s(1) == 0 ? "OK" : "FAIL"));
        Console.WriteLine("2 -> 1 : " + (s(2) == 1 ? "OK" : "FAIL"));
        Console.WriteLine("5 -> 3 : " + (s(5) == 3 ? "OK" : "FAIL"));
        Console.WriteLine("10 -> 4 : " + (s(10) == 4 ? "OK" : "FAIL"));
        Console.WriteLine("100 -> 25 : " + (s(100) == 25 ? "OK" : "FAIL"));
        Console.WriteLine("1,000 -> 168 : " + (s(1000) == 168 ? "OK" : "FAIL"));
        Console.WriteLine("10,000 -> 1,229 : " + (s(10000) == 1229 ? "OK" : "FAIL"));
        Console.WriteLine("100,000 -> 9,592 : " + (s(100000) == 9592 ? "OK" : "FAIL"));
        Console.WriteLine("1,000,000 -> 78,498 : " + (s(1000000) == 78498 ? "OK" : "FAIL"));
    }
}

Inizia a prendere un po 'di tempo dopo aver superato 1 milione.


2

Matlab, 60 byte

Continuando il mio attaccamento alle funzioni di Matlab a una riga. Senza usare una fattorizzazione integrata:

f=@(x) nnz(arrayfun(@(x) x-2==nnz(mod(x,[1:1:x])),[1:1:x]));

Dato che un numero primo yha solo due fattori [1,y]: contiamo i numeri nell'intervallo [1,x]che hanno solo due fattori.

L'uso della fattorizzazione consente un accorciamento significativo (fino a 46 byte).

g=@(x) size(unique(factor(factorial(x))),2);

Conclusione: è necessario esaminare le lingue del golf: D


2

In realtà, 10 byte

Questa è stata la soluzione più breve che ho trovato che non si è imbattuto in bug di interprete su TIO. Suggerimenti di golf benvenuti. Provalo online!

;╗r`P╜>`░l

Ungolfing

         Implicit input n.
;╗       Duplicate n and save a copy of n to register 0.
r        Push range [0..(n-1)].
`...`░   Push values of the range where the following function returns a truthy value.
  P        Push the a-th prime
  ╜        Push n from register 0.
  >        Check if n > the a-th prime.
l        Push len(the_resulting_list).
         Implicit return.

2

Gelatina , 3 byte

ÆRL

Jelly ha una funzione di conteggio dei primi incorporata ÆCe una funzione di controllo dei primi ÆP, che utilizza invece una funzione di generazione dei primi integrata ÆRe prende la lunghezza L.

Immagino che questo sia tanto limite quanto l'utilizzo degli incorporati di fattorizzazione in primi, che richiederebbe anche 3 byte con !Æv( !fattoriale, Ævconta i fattori primi)


2

PHP, 96 92 byte

for($j=$argv[1]-1;$j>0;$j--){$p=1;for($i=2;$i<$j;$i++)if(is_int($j/$i))$p=0;$t+=$p;}echo $t;

Salvato 4 byte grazie a Roman Gräf

Test online

Codice test non golfato:

$argv[1] = 5;

for($j=$argv[1]-1;$j>0;$j--) {
    $p=1;
    for($i=2;$i<$j;$i++) {
        if(is_int($j/$i)) {
            $p=0;
        }
    }
    $t+=$p;
}
echo $t;

Test online


Perché usi isInt(...)?1:0e non soloisInt(...)
Roman Gräf,

@ RomanGräf Grazie, hai ragione. Ho lasciato il ternario dopo molta semplificazione del codice, ed era così ovvio che non riuscivo a vederlo ...
Mario,

2

APL (Dyalog Unicode) , 13 byte SBCS

2+.=0+.=⍳∘.|⍳

Provalo online!

ɩ ndices 1 ...
 N⧽ ∘.| tabella rimanente (usando questi due come assi)
ɩ ndices 1 ... N

0+.= la somma degli elementi pari a zero (cioè quanti divisori ha ciascuno)

2+.= la somma degli elementi è uguale a due (cioè quanti numeri primi ci sono)


2

Python 3, 40 byte

f=lambda n:1if n<1else(2**n%n==2)+f(n-1)

Un intero dispari k è primo se un solo se 2 ** (k-1) è congruente a 1 mod k. Quindi, controlliamo solo questa condizione e aggiungiamo 1 per il caso di k = 2.


2 ** n% n == 2 non è sufficiente come test di
primalità

@RosLuP Ecco perché il caso base di n == 0 dovrebbe aggiungere 1 (per tenere conto del caso n = 2).
Sandeep Silwal,

2 ** n% n == 2 non è abbastanza in generale ... Esistono molti (infiniti in ciò che vorrei ricordare) numeri in cui 2 ^ n% n = 2 che non sono numeri primi
RosLuP

Ad esempio 341 = 11 * 31 ma (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: Ah ok sì, l'ho cercato. Questi numeri si chiamano Fermat Psuedoprimes ma sembrano essere piuttosto rari: P
Sandeep Silwal,

2

MATL , 9 byte

Questo evita la decomposizione del fattore primo. La sua complessità è O ( n ²).

:t!\~s2=s

Provalo online!

:     % Range [1 2 ... n] (row vector)
t!    % Duplicate and transpose into a column vector
\     % Modulo with broadcast. Gives matrix in which entry (i,j) is i modulo j, with
      % i, j in [1 2 ... n]. A value 0 in entry (i,j) means i is divisible by j
~     % Negate. Now 1 means i is divisible by j
s     % Sum of each column. Gives row vector with the number of divisors of each j
2=    % Compare each entry with 2. A true result corresponds to a prime
s     % Sum

1

JavaScript (ES6), 50 + 2 46 + 2 43 byte

Risparmiato 3 5 byte grazie a Neil:

f=n=>n&&eval(`for(z=n;n%--z;);1==z`)+f(n-1)

evalpuò accedere al nparametro.
Il eval(...)controllo se nè primo.


Soluzioni precedenti: il
conteggio dei byte dovrebbe essere +2 perché ho dimenticato di nominare la funzione f=(necessaria per la ricorsione)

46 + 2 byte (3 byte salvati grazie alle produzioni ETH):

n=>n&&eval(`for(z=n=${n};n%--z;);1==z`)+f(n-1)

50 + 2 byte:

n=>n&&eval(`for(z=${n};${n}%--z&&z;);1==z`)+f(n-1)

1
Almeno sul mio browser, evalposso accedere al nparametro per la tua funzione (che hai dimenticato di nominare, costandoti 2 byte; è bello sapere che non sono l'unico che fa quell'errore) che ti fa risparmiare 5 byte.
Neil,

@Neil non lo sapevo eval. Testato con Firefox, Chrome e Edge ha funzionato per me. La spiegazione è eval () analizza nel contesto dell'istruzione . Due esempi: a=12;f=b=>eval('a + 5');f(8)display 17e a=12;f=a=>eval('a + 5');f(8)display 13.
Hedi,

1

Java 7.102 byte

Forza bruta

int f(int n){int i=2,j=2,c=1,t=0;for(;i<=n;j=2,c+=t==1?1:0,i++)for(;j<i;t=i%j++==0?j=i+1:1);return c;}

Ungolfed

int f(int n){
int i=2,j=2,c=1,t=0;
for(;i<=n;j=2,c+=t==1?1:0,i++)
    for(;j<i;)
        t=i%j++==0?j=i+1:1;
    return c;
 }

Questo sta attualmente dando un risultato errato per l'input 1. Attualmente restituisce 1invece di 0. È possibile risolvere questo o cambiando return c;a return n<2?0:c;o cambiare ,c=1,a ,c=n<2?0:1,.
Kevin Cruijssen,


1

In realtà, 10 byte

Se la mia prima risposta effettiva non è consentita per l'utilizzo di una funzione di generazione primaria, ecco una risposta di backup che utilizza il teorema di Wilson. Suggerimenti di golf benvenuti. Provalo online!

R`;D!²%`MΣ

Provalo online

         Implicit input n.
R        Push range [1..n]
`...`M   Map the following function over the range. Variable k.
  ;        Duplicate k.
  D        Decrement one of the copies of k.
  !²       Push ((k-1)!)².
  %        Push ((k-1)!)² % k. This returns 1 if k is prime, else 0.
Σ        Sums the result of the map, adding all the 1s that represent primes, 
          giving the total number of primes less than n.
         Implicit return.
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.