Função de contagem principal


28

Introdução

A função de contagem primária , também conhecida como função Pi π(x) , retorna a quantidade de números primos menor ou igual a x.

Desafio

Seu programa pegará um número inteiro x que você pode assumir como positivo e produzirá um número inteiro igual à quantidade de números primos menor ou igual a x. Este é um desafio de , portanto, o vencedor será o programa com o menor número de bytes.

Você pode usar qualquer idioma de sua escolha, desde que existisse antes desse desafio, mas se o idioma tiver uma função de contagem primária incorporada ou uma função de verificação de primalidade (como o Mathematica), essa função não poderá ser usada no seu código .

Exemplo de entradas

Entrada:
1
Saída:
0

Entrada:
2
Saída:
1

Entrada:
5
Saída:
3

A000720 - OEIS


3
E quanto a outras funções relacionadas ao prime? Por exemplo, função "next prime"
Luis Mendo

6
e as funções de fatoração primária?
Maltysen 23/09/16

4
Bem-vindo à Programação de Puzzles e Code Golf!
Adnan

6
Como Adnan disse, seja bem-vindo ao PPCG! Para desafios futuros, deixe-me recomendar o Sandbox, onde você pode postar um desafio para obter comentários e críticas significativos antes de publicá-lo no site principal.
AdmBorkBork 23/09

Eu acho que isso é o que @TheBikingViking pretendia link: Relacionados
mbomb007

Respostas:


36

05AB1E , 3 bytes

!fg

Isso pressupõe que os built-ins de fatoração são permitidos. Experimente online!

Como funciona

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

5
Isso é realmente inteligente!
mbomb007

5
Porra, estou recebendo rekt no meu próprio idioma pela segunda vez haha. +1
Adnan

Por que isso funciona?
Oliver Ni

1
@ Oliver Porque o fatorial de n é divisível por todos os números inteiros 1, ..., n (em particular, os números primos p ≤ n ) e por nenhum outro número primo q> n, pois não pode ser expresso como um produto de números menores.
Dennis

10

Python 2, 45 bytes

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

Usa o gerador principal do Teorema de Wilson . O produto prastreia (k-1)!^2e p%ké 1 para números primos e 0 para não primos.


Calcular o fatorial de baixo para cima é um ótimo truque. +1
ETHproductions 23/09/16

6

MATL , 11, 10, 8 , 5 bytes

:pYFn

Experimente online!

Eu escrevi uma versão que tinha uma explicação muito legal de como as matrizes do MATL funcionam:

:YF!s1=1

Mas não é mais relevante. Confira o histórico de revisões, se você quiser vê-lo.

Nova explicação:

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

Três bytes salvos graças à solução genial de Dennis


É mais curto usar a função "expoentes da fatoração primária", porque essa vetoriza:YF!s1=s
Luis Mendo

@LuisMendo Essa é uma abordagem totalmente diferente, portanto, fique à vontade para publicá-la. (Embora se você não quer, eu felizmente faria)
DJMcMayhem

Continue. Vou porta que a Jelly para a prática :-)
Luis Mendo

5

Geléia , 8 5 bytes

3 bytes salvos graças ao @Dennis!

RÆESL

Experimente online!

Porto da resposta MATL do DJMcMayhem (versão anterior) refinada por 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
Correção: porto de Luis Mendo: resposta MATL de DJMcMayhem. : P
DJMcMayhem

2
Você só precisa do comprimento máximo dos resultados de ÆE, pois cada expoente corresponde a um fator primo diferente. RÆESLalcança exatamente isso. !ÆELseria ainda mais curto.
Dennis

1
@Dennis Thanks! Eu usei a primeira sugestão. A segunda é muito diferente, e é a sua abordagem
Luis Mendo

5

Modelos do MediaWiki com ParserFunctions , 220 + 19 = 239 bytes

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

Para chamar o modelo:

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

Organizados em estilo 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}}}}}}}}}}}}

Apenas um teste básico de primalidade de 2 a n . Os números com três chaves ao redor são as variáveis, onde {{{1}}}é n , {{{2}}}é o número que está sendo testado, {{{3}}}é o fator a ser verificado.


5

Perl, 33 bytes

Inclui +1 para -p

Dê o número de entrada no STDIN

primecount.pl

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

Dá o resultado errado, 0mas tudo bem, o op pediu suporte apenas para números inteiros positivos.




4

Gelatina , 13 11 10 9 8 7 6 bytes

Usando nenhuma função primária integrada
-1 byte graças a @miles (use uma tabela)
-1 byte graças a @Dennis (converta de unário para contar os divisores)

ḍþḅ1ċ2

TryItOnline
Ou veja os 100 primeiros termos da sérien=[1,100], também em TryItOnline

Quão?

ḍþḅ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
Você pode obter 7 bytes %þ`¬Sċ2usando uma tabela de restos.
miles

1
ḍþḅ1ċ2salva um byte.
Dennis

4

JavaScript (ES6), 45 43 bytes

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

Uma modificação da minha função de primalidade 36 35 33 bytes (1 byte salvo por @Neil, 2 por @Arnauld):

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

(Não consigo postar isso em nenhum lugar porque esse número é primo? Só aceita programas completos ...)

Snippet de teste


Waw ... demorei um pouco para entender. Bom trabalho!
todeale 24/09/16

Infelizmente, isso não se aplica à sua resposta, mas você provavelmente pode se safar com uma &no meio da sua função de primalidade.
Neil

3

PowerShell v2 +, 98 bytes

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

Cuidado: Isso é lento para entradas grandes.

Basicamente, a pesquisa unária de Esse número é primo? , juntamente com um forloop e um $j++contador. Um pouco de lógica adicional na frente para explicar as entradas de casos extremos 1e 2, devido à maneira como a vedação funciona nos forloops.


3

05AB1E , 5 bytes

Supõe que os componentes principais de fatoração são permitidos.

Código:

LÒ1ùg

Explicação:

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

Usa a codificação CP-1252 . Experimente online!


ÅPgé o que seria agora, certo?
Magic Octopus Urn

3

CJam , 7 bytes

rim!mF,

Experimente online! Usa uma função de fatoração.

Explicação:

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

3

Gelatina , 6 bytes

Ḷ!²%RS

Isso usa apenas aritmética básica e o teorema de Wilson. Experimente online! ou verifique todos os casos de teste .

Como funciona

Ḷ!²%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

Bash + coreutils, 30

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

Ideone.


Pacote Bash + coreutils + BSD-games, 22

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

Esta resposta mais curto requer que você tenha o pacote bsdgames instalado: sudo apt install bsdgames.


2

Pyke, 8 6 bytes

SmPs}l

Experimente aqui!

Agradecimentos a Maltysen pelo novo algoritmo

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

2

C #, 157 bytes

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

Programa completo com casos de teste:

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

Começa a demorar um pouco quando você ultrapassa 1 milhão.


2

Matlab, 60 bytes

Continuando meu apego às funções Matlab de uma linha. Sem usar uma fatoração integrada:

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

Dado que um primo ypossui apenas dois fatores [1,y]: contamos os números no intervalo [1,x]que possuem apenas dois fatores.

O uso da fatoração permite um encurtamento significativo (até 46 bytes).

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

Conclusão: É necessário olhar para eles idiomas de golfe: D


2

Na verdade, 10 bytes

Essa foi a solução mais curta que encontrei e não encontrou erros de intérprete no TIO. Sugestões de golfe são bem-vindas. Experimente 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

Geléia , 3 bytes

ÆRL

O Jelly possui uma função de contagem primária incorporada ÆCe uma função de verificação primária, que ÆP, em vez disso, usa uma função geradora primária incorporada ÆRe leva o comprimento L.

Eu acho que isso é tão limítrofe quanto usar built-ins de fatoração primária, o que também levaria 3 bytes com !Æv( !fatorial, Ævfatores primários de contagem)


2

PHP, 96 92 bytes

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;

Guardado 4 bytes graças a Roman Gräf

Teste on-line

Código de teste ungolfed:

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

Teste on-line


Por que você usa isInt(...)?1:0e não apenasisInt(...)
Roman Gräf 25/09

@ RomanGräf Obrigado, você está certo. Deixei o ternário depois de muito semplification código, e que era tão óbvio que eu não podia vê-lo ...
Mario

2

APL (Dyalog Unicode) , SBCS de 13 bytes

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

Experimente online!

Ɩ ndices 1 ... N
 ⧽ ∘.| restante-tabela (usando os dois como eixos)
ɩ ndices 1 ... N

0+.= a soma dos elementos igual a zero (ou seja, quantos divisores cada um possui)

2+.= a soma dos elementos igual a dois (ou seja, quantos primos existem)


2

Python 3, 40 bytes

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

Um número inteiro ímpar k é primo se apenas se 2 ** (k-1) for congruente a 1 mod k. Assim, basta verificar esta condição e adicionar 1 para o caso de k = 2.


2 ** n% n == 2 não é suficiente como teste
primariamente

@RosLuP É por isso que o caso base de n == 0 deve adicionar 1 (para explicar o caso n = 2).
Sandeep Silwal

2 ** n% n == 2 não é suficiente, em geral ... Existem muitos (infinito em que eu me lembro) números onde 2 ^ n% n = 2 que são não primos
RosLuP

Por exemplo 341 = 11 * 31 mas (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: Ah ok sim, eu procurei. Esses números são chamados Fermat Psuedoprimes, mas parecem bastante raros: P
Sandeep Silwal

2

MATL , 9 bytes

Isso evita a decomposição do fator primo. Sua complexidade é O ( n ²).

:t!\~s2=s

Experimente 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 bytes

Economizou 3 5 bytes graças a Neil:

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

evalpode acessar o nparâmetro
As eval(...)verificações sen é primo.


Soluções anteriores:
contagem de bytes deve ser +2 porque esqueci de nomear a funçãof= (necessária para recursão)

46 + 2 bytes (economizados 3 bytes graças a ETHproductions):

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

50 + 2 bytes:

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

1
Pelo menos no meu navegador, evalpode acessar o nparâmetro para sua função (que você esqueceu de nomear, custando 2 bytes; é bom saber que eu não sou o único que cometeu esse erro) que economiza 5 bytes.
Neil

@ Neil eu não sabia eval. Testado com firefox, chrome e edge funcionou para mim. A explicação é eval () analisa no contexto da declaração . Dois exemplos: a=12;f=b=>eval('a + 5');f(8)monitores 17e a=12;f=a=>eval('a + 5');f(8)monitores 13.
Hedi

1

Java 7.102 bytes

Força 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;
 }

No momento, isso está fornecendo um resultado incorreto para a entrada 1. Atualmente, ele retorna em 1vez de 0. Você pode corrigir isto por qualquer mudança return c;para return n<2?0:c;ou alterar ,c=1,a ,c=n<2?0:1,.
Kevin Cruijssen


1

Na verdade, 10 bytes

Se minha primeira resposta Realmente não é permitida por usar uma função de geração primária, aqui está uma resposta alternativa usando o teorema de Wilson. Sugestões de golfe são bem-vindas. Experimente online!

R`;D!²%`MΣ

Experimente 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.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.