Pierwsza funkcja zliczania


28

Wprowadzenie

Prime Funkcja zliczania , znany również jako funkcja Pi , powraca się liczb pierwszych ilości mniejszej niż lub równą x.π(x)

Wyzwanie

Twój program przyjmie liczbę całkowitą x, którą możesz założyć jako dodatnią, i wyświetli jedną liczbę całkowitą równą liczbie liczb pierwszych mniejszej lub równej x. To wyzwanie dla , więc zwycięzcą zostanie program z najmniejszą liczbą bajtów.

Możesz użyć dowolnego języka, który wybrałeś, pod warunkiem, że istniał przed tym wyzwaniem, ale jeśli język ma wbudowaną funkcję liczenia liczb pierwszych lub funkcję sprawdzania pierwotności (taką jak Mathematica), nie można użyć tej funkcji w kodzie .

Przykładowe dane wejściowe

Wejście:
1
Wyjście:
0

Wejście:
2
Wyjście:
1

Wejście:
5
Wyjście:
3

A000720 - OEIS


3
Co z innymi funkcjami związanymi z liczbą pierwszą? Na przykład funkcja „next prime”
Luis Mendo

6
co z pierwszymi funkcjami faktoryzacji?
Maltysen

4
Witamy w Programowaniu zagadek i Code Golf!
Adnan

6
Jak powiedział Adnan, witamy w PPCG! W przypadku przyszłych wyzwań pozwól mi polecić piaskownicę, w której możesz opublikować wyzwanie, aby uzyskać znaczącą opinię i krytykę przed opublikowaniem go na głównej stronie.
AdmBorkBork,

Myślę, że właśnie to @TheBikingViking miał na myśli link: Powiązane
mbomb007

Odpowiedzi:


36

05AB1E , 3 bajty

!fg

Zakłada się, że dozwolone są wbudowane czynniki. Wypróbuj online!

Jak to działa

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

5
To naprawdę sprytne!
mbomb007,

5
Cholera, po raz drugi dostaję rekt w swoim własnym języku haha. +1
Adnan

Dlaczego to działa?
Oliver Ni

1
@Oliver Ponieważ silnia n jest podzielna przez wszystkie liczby całkowite 1, ..., n (w szczególności liczby pierwsze p ≤ n ), i przez żadną inną liczbę pierwszą q> n, ponieważ nie może być wyrażona jako iloczyn mniejszych liczb.
Dennis

10

Python 2, 45 bajtów

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

Wykorzystuje generator liczb pierwszych Twierdzenia Wilsona . Produkt pśledzi (k-1)!^2i p%kwynosi 1 dla liczb pierwszych i 0 dla liczb niepierwszych.


Obliczanie silni od podstaw jest świetną sztuczką. +1
ETHprodukcje

6

MATL , 11, 10, 8 , 5 bajtów

:pYFn

Wypróbuj online!

Napisałem wersję, która miała naprawdę fajne wyjaśnienie działania macierzy MATL:

:YF!s1=1

Ale to już nie ma znaczenia. Sprawdź historię zmian, jeśli chcesz ją zobaczyć.

Nowe wyjaśnienie:

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

Trzy bajty zaoszczędzone dzięki genialnemu rozwiązaniu Dennisa


Krótsze jest użycie funkcji „wykładników podziału na czynniki pierwsze”, ponieważ ta wektoryzuje:YF!s1=s
Luis Mendo

@LuisMendo To zupełnie inne podejście, więc śmiało zachęcamy do opublikowania go. (Chociaż, jeśli nie chcesz, chętnie bym to zrobił)
DJMcMayhem

Śmiało. Prześlę to do Jelly, żeby ćwiczyć :-)
Luis Mendo

5

Galaretka , 8 5 bajtów

3 bajty zapisane dzięki @Dennis!

RÆESL

Wypróbuj online!

Port odpowiedzi MATL DJMcMayhem (poprzednia wersja) udoskonalony przez Dennisa.

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
Korekta: port odpowiedzi Luis Mendo: MATL DJMcMayhem. : P
DJMcMayhem

2
Potrzebujesz tylko maksymalnej długości wyników ÆE, ponieważ każdy wykładnik odpowiada innemu współczynnikowi pierwszemu. RÆESLosiąga właśnie to. !ÆELbyłby jeszcze krótszy.
Dennis,

1
@Dennis Thanks! Użyłem pierwszej sugestii. Drugi jest zbyt odmienny i jest to twoje podejście
Luis Mendo

5

Szablony MediaWiki z ParserFunctions , 220 + 19 = 239 bajtów

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

Aby wywołać szablon:

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

Ułożone w stylu 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}}}}}}}}}}}}

Tylko podstawowy test pierwotności od 2 do n . Numery z trzech szelki wokół nich są zmienne, gdzie {{{1}}}jest n , {{{2}}}to liczba testowany, {{{3}}}jest czynnikiem, który należy sprawdzić.


5

Perl, 33 bajty

Obejmuje +1 dla -p

Podaj numer wejściowy na STDIN

primecount.pl

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

Daje zły wynik, 0ale to jest OK, operacja poprosiła o wsparcie tylko dla dodatnich liczb całkowitych.




4

Galaretka , 13 11 10 9 8 7 6 bajtów

Bez
użycia wbudowanych funkcji pierwszych -1 bajt dzięki @miles (użyj tabeli)
-1 bajt dzięki @Dennis (konwertuj z unarnego na zliczanie dzielników)

ḍþḅ1ċ2

TryItOnline
Lub zobacz pierwsze 100 terminów seriin=[1,100], również na TryItOnline

W jaki sposób?

ḍþḅ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
Możesz dostać się do 7 bajtów %þ`¬Sċ2używając tabeli reszt.
mil

1
ḍþḅ1ċ2zapisuje bajt.
Dennis

4

JavaScript (ES6), 45 43 bajtów

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

Modyfikacja My 36 35 33 bajtów funkcja pierwszości (1 bajt zapisywane @Neil, 2 przez @Arnauld)

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

(Nie mogę tego nigdzie opublikować, ponieważ Czy ten numer jest liczbą pierwszą? Akceptuje tylko pełne programy ...)

Testowy fragment kodu


Waw ... zrozumienie zajęło mi trochę czasu. Dobra robota!
todeale

Niestety, nie ma to zastosowania do twojej odpowiedzi, ale prawdopodobnie możesz uciec od jednego &w środku swojej funkcji pierwotności.
Neil

3

PowerShell v2 +, 98 bajtów

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

Uwaga: Jest to powolne dla dużych danych wejściowych.

Zasadniczo wyszukiwanie jednostronne z Czy liczba ta jest liczbą pierwszą? , w połączeniu z forpętlą i $j++licznikiem. Trochę dodatkowej logiki z przodu, aby uwzględnić wkłady skrzynek krawędziowych 1oraz 2, ze względu na to, jak słupek ogrodzeniowy działa w forpętlach.


3

05AB1E , 5 bajtów

Zakłada, że ​​dozwolone są wbudowane czynniki pierwsze.

Kod:

LÒ1ùg

Wyjaśnienie:

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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online!


ÅPgco by to było teraz, prawda?
Magic Octopus Urn

3

CJam , 7 bajtów

rim!mF,

Wypróbuj online! Wykorzystuje funkcję faktoryzacji.

Wyjaśnienie:

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

3

Galaretka , 6 bajtów

Ḷ!²%RS

Wykorzystuje tylko podstawową arytmetykę i twierdzenie Wilsona. Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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


Bash + coreutils + pakiet gier BSD, 22

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

Ta krótsza odpowiedź wymaga posiadania zainstalowanego pakietu bsdgames: sudo apt install bsdgames.



2

C #, 157 bajtów

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

Pełny program z przypadkami testowymi:

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

Zaczyna chwilę, gdy przekroczysz 1 milion.


2

Matlab, 60 bajtów

Kontynuując moje przywiązanie do jednowierszowych funkcji Matlaba. Bez użycia wbudowanej faktoryzacji:

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

Biorąc pod uwagę, że liczba pierwsza yma tylko dwa czynniki [1,y]: liczymy liczby w zakresie, [1,x]który ma tylko dwa czynniki.

Zastosowanie faktoryzacji pozwala na znaczne skrócenie (do 46 bajtów).

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

Wniosek: Muszę przyjrzeć się im golfowym językom: D


2

Właściwie 10 bajtów

To było najkrótsze rozwiązanie, jakie znalazłem, i które nie napotkało błędów interpretera w TIO. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj 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

Galaretka , 3 bajty

ÆRL

Galaretka ma wbudowaną funkcję zliczania liczb pierwszych ÆCi funkcję sprawdzania liczb pierwszych ÆP, zamiast tego wykorzystuje wbudowaną funkcję generowania liczb pierwszych ÆRi przyjmuje długość L.

Wydaje mi się, że jest to mniej więcej tak graniczne, jak użycie wbudowanych czynników pierwszej generacji, które również zajęłyby 3 bajty !Æv( !czynnikowe, Ævliczby pierwsze)


2

PHP, 96 92 bajtów

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;

Oszczędność 4 bajtów dzięki Romanowi Gräfowi

Przetestuj online

Nie testowany kod testowy:

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

Przetestuj online


Dlaczego używasz, isInt(...)?1:0a nie tylkoisInt(...)
Roman Gräf

@ RomanGräf Dzięki, masz rację. Opuściłem trójskładnik po wielu próbach kodu i było to tak oczywiste, że nie mogłem go zobaczyć ...
Mario,

2

APL (Dyalog Unicode) , 13 bajtów SBCS

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

Wypróbuj online!

d ndices 1…
 N⧽ ∘.| tabela reszty (używając tych dwóch jako osi)
ɩ ndices 1… N

0+.= suma elementów równa zero (tj. ile dzielników ma każdy)

2+.= suma elementów równa się dwóm (tj. ile jest liczb pierwszych)


2

Python 3, 40 bajtów

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

Dziwna liczba całkowita k jest liczbą pierwszą, jeśli tylko jeśli 2 ** (k-1) jest zgodne z 1 mod k. Tak więc sprawdzamy tylko ten warunek i dodajemy 1 dla przypadku k = 2.


2 ** n% n == 2 to za mało jak pierwotny test
RosLuP

@RosLuP Dlatego podstawowy przypadek n == 0 powinien dodać 1 (aby uwzględnić przypadek n = 2).
Sandeep Silwal

2 ** n% n == 2 w ogóle nie wystarcza ... Istnieje wiele (nieskończonych w tym, co pamiętam) liczb, w których 2 ^ n% n = 2, które nie są liczbami pierwszymi
RosLuP

Na przykład 341 = 11 * 31, ale (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: Ach, tak, sprawdziłem to. Te liczby nazywa się Fermat Psuedoprimes, ale wydają się dość rzadkie: P
Sandeep Silwal

2

MATL , 9 bajtów

Pozwala to uniknąć rozkładu pierwszorzędowego. Jego złożoność wynosi O ( n ²).

:t!\~s2=s

Wypróbuj 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 bajty

Zaoszczędzono 3 5 bajtów dzięki Neilowi:

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

evalmoże uzyskać dostęp do nparametru.
Do eval(...)sprawdza czy njest liczbą pierwszą.


Poprzednie rozwiązania:
liczba bajtów powinna wynosić +2, ponieważ zapomniałem nazwać funkcję f=(potrzebne do rekurencji)

46 + 2 bajty (Zapisane 3 bajty dzięki produktom ETH):

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

50 + 2 bajty:

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

1
Przynajmniej w mojej przeglądarce evalmoże uzyskać dostęp do nparametru do funkcji (o której zapomniałeś nazwać, co kosztuje 2 bajty; dobrze wiedzieć, że nie jestem jedynym, który popełnia ten błąd), co pozwala zaoszczędzić 5 bajtów.
Neil

@ Nee, dla którego nie wiedziałem eval. Testowany z firefox, chrome i edge, działał dla mnie. Wyjaśnienie to eval () parsuje w kontekście instrukcji . Dwa przykłady: a=12;f=b=>eval('a + 5');f(8)wyświetlacze 17i a=12;f=a=>eval('a + 5');f(8)wyświetlacze 13.
Hedi

1

Java 7,102 bajtów

Brutalna siła

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

Nie golfił

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

To daje obecnie niepoprawny wynik dla danych wejściowych 1. Obecnie zwraca 1zamiast 0. Możesz to naprawić, zmieniając return c;na return n<2?0:c;lub zmieniając ,c=1,na ,c=n<2?0:1,.
Kevin Cruijssen


1

Właściwie 10 bajtów

Jeśli moja pierwsza odpowiedź jest niedozwolona za użycie funkcji generowania liczb pierwszych, oto odpowiedź rezerwowa z twierdzeniem Wilsona. Sugestie dotyczące gry w golfa mile widziane. Wypróbuj online!

R`;D!²%`MΣ

Wypróbuj 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.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.