Ana sayma fonksiyonu


28

Giriş

Prime Sayma Fonksiyonu da Pi fonksiyonu olarak bilinen, , en az asal miktarını döndürür x ya da eşittir.π(x)

Meydan okuma

Programınız, pozitif olduğunu varsayabileceğiniz bir x tamsayısını alır ve x'e eşit veya daha küçük asal sayıya eşit bir tamsayı üretir. Bu bir mücadelesi, bu yüzden kazanan en az baytlık program olacak.

Seçtiğiniz herhangi bir dili, bu zorluk çıkmadan önce mevcut olması koşuluyla kullanabilirsiniz, ancak dilin yerleşik bir birincil sayma işlevi veya bir birincillik denetimi işlevi (Mathematica gibi) varsa, bu işlev kodunuzda kullanılamaz. .

Örnek Girişler

Giriş:
1
Çıkış:
0

Giriş:
2
Çıkış:
1

Giriş:
5
Çıkış:
3

A000720 - OEIS


3
Peki ya asal ilgili diğer fonksiyonlar? Örneğin, "gelecek başbakan" funciton
Luis Mendo

6
ana faktörlendirme fonksiyonları ne durumda?
Maltysen

4
Programlama Bulmacaları ve Code Golf'a Hoş Geldiniz!
Adnan

6
Adnan'ın dediği gibi PPCG'ye hoş geldiniz! Gelecekteki zorluklar için, ana siteye göndermeden önce anlamlı geri bildirim ve eleştiri almak için zorluk çekebileceğiniz Sandbox'ı önereyim .
AdmBorkBork

Sanırım @TheBikingViking’in şu bağlantıya kurması gerekiyordu: Related
mbomb007

Yanıtlar:


36

05AB1E , 3 bayt

!fg

Bu, faktörizasyon yerleşik yapılarına izin verildiğini varsayar. Çevrimiçi deneyin!

Nasıl çalışır

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

5
Bu gerçekten zekice!
mbomb007

5
Kahretsin, ikinci kez kendi dilimde rekt alıyorum haha. +1
Adnan

Bu neden işe yarıyor?
Oliver Ni,

1
@Oliver n faktörü, 1, ..., n (özellikle asal sayılar p ) tarafından verilen tüm tamsayılar tarafından bölünebilir ve daha küçük sayılardan oluşan bir ürün olarak ifade edilemeyeceğinden, diğer asal q> n ile bölünemez .
Dennis,

10

Python 2,45 bayt

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

Wilson'un Teoremi üssü üretecini kullanır . Ürün pizler (k-1)!^2ve p%kprimerler için 1 ve primerler için 0'dır.


Faktoringin aşağıdan yukarıya doğru hesaplanması harika bir numaradır. +1
ETHProductions

6

MATL , 11, 10, 8 , 5 bayt

:pYFn

Çevrimiçi deneyin!

MATL matrislerinin nasıl çalıştığı hakkında gerçekten harika bir açıklaması olan bir versiyon yazdım:

:YF!s1=1

Ama artık alakalı değil. Görmek istiyorsanız revizyon geçmişine göz atın.

Yeni açıklama:

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

Dennis'in dahi çözümü sayesinde üç bayt kurtarıldı


"Asal çarpanlaştırmanın üsleri" işlevini kullanmak daha kısadır, çünkü bu bir vektörleştirir:YF!s1=s
Luis Mendo

@LuisMendo Bu tamamen farklı bir yaklaşım, bu yüzden devam edip göndermekten çekinmeyin. (Her ne kadar istemeseniz de, mutlu olurum)
DJMcMayhem

Devam et.
Jelly'i

5

Jöle , 8 5 bayt

@Dennis sayesinde 3 bayt kurtarıldı!

RÆESL

Çevrimiçi deneyin!

DJMcMayhem Limanı'nın MATL cevabı (eski versiyon) Dennis tarafından rafine edildi.

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
Düzeltme: Luis Mendo'nun limanı: DJMcMayhem'in MATL cevabı. : P
DJMcMayhem

2
ÆEHer üs, farklı bir ana faktöre karşılık geldiğinden, yalnızca sonuçların maksimum uzunluğuna ihtiyacınız vardır . RÆESLsadece bunu başarır. !ÆELdaha da kısa olurdu.
Dennis,

1
@Dennis Teşekkürler! İlk öneriyi kullandım. İkincisi çok farklı ve senin yaklaşımın
Luis Mendo

5

ParserFunctions ile MediaWiki şablonları , 220 + 19 = 239 bayt

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

Şablonu aramak için:

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

Lisp tarzında düzenlenmiş:

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

Sadece 2'den n'ye kadar olan basit bir ilkellik testi . Çevrelerindeki üç parantezi ile sayılar değişkenler, nerede {{{1}}}olduğu , n , {{{2}}}sayı test ediliyorsa, {{{3}}}kontrol etmek faktördür.


5

Perl, 33 bayt

İçin +1 içerir -p

STDIN'e giriş numarasını verin

primecount.pl

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

Bunun için yanlış sonuç verir, 0ancak sorun değil, sadece pozitif tamsayılar için destek istedi.




4

Jelly , 13 11 10 9 8 7 6 bayt

Yerleşik asal işlev
kullanmamak, miller sayesinde -1 bayt (bir tablo kullanın)
@Dennis sayesinde (baytları saymak için unary'den dönüştürün ) -1 bayt

ḍþḅ1ċ2

TryItOnline
Veya TryItOnline'da serinin ilk 100 teriminin=[1,100]de görebilirsiniz.

Nasıl?

ḍþḅ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
Bir %þ`¬Sċ2kalan tabloyu kullanarak 7 bayta ulaşabilirsiniz .
mil

1
ḍþḅ1ċ2bir bayt kaydeder.
Dennis,

4

JavaScript (ES6), 45 43 bayt

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

36 35 33 bayt primallik fonksiyonumun bir modifikasyonu ( @Neil, 2 @Arnauld tarafından kaydedilen 1 byte):

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

(Bunu hiçbir yerde yayınlayamam çünkü bu sayı bir asal mı? Sadece tam programları kabul ediyor ...)

Test pasajı


Waw ... anlamam biraz zaman aldı. İyi iş!
todeale

Maalesef cevabınız için geçerli değil ama muhtemelen &asallık fonksiyonunuzun ortasında bir taneden uzaklaşabilirsiniz .
Neil

3

PowerShell v2 +, 98 bayt

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

Dikkat: Bu, büyük girişler için yavaştır .

Temelde gelen tek taraflı tabanlı arama Bu sayı bir asal mı? , bir fordöngü ve bir $j++sayaç ile birleştiğinde . Biraz ek kenar vakalar girişi için hesaba ön mantık 1ve 2bağlı fenceposting nasıl işlediğini için, fordöngüler.


3

05AB1E , 5 bayt

Asal çarpanlara ayırma yapılarına izin verildiğini varsayar.

Kod:

LÒ1ùg

Açıklama:

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

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin!


ÅPgŞimdi ne olacaktı değil mi?
Magic Octopus Urn

3

CJam , 7 bayt

rim!mF,

Çevrimiçi deneyin! Bir faktoring işlevini kullanır.

Açıklama:

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

3

Jöle , 6 bayt

Ḷ!²%RS

Bu sadece temel aritmetik ve Wilson teoremini kullanır. Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

Ḷ!²%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 + BSD oyun paketi, 22

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

Bu kısa cevap yüklü bsdgames pakete sahip olmasını gerektirir: sudo apt install bsdgames.


2

Pyke, 8 6 bayt

SmPs}l

Burada dene!

Yeni algoritma için Maltysen'e teşekkürler

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

2

C #, 157 bayt

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

Test vakaları ile tam program:

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

1 milyonun üzerine çıkınca biraz zaman almaya başlar.


2

Matlab, 60 bayt

Bir satırlık Matlab fonksiyonlarına ekim devam ediyor. Yerleşik bir faktoring kullanmadan:

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

Asal bir maddenin ysadece iki faktöre sahip olduğu göz önüne alındığında [1,y]: aralıktaki [1,x]sadece iki faktöre sahip sayıları sayarız .

Faktoringi kullanmak önemli ölçüde kısaltmaya izin verir (46 bayta kadar).

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

Sonuç: Golf dillerine göz atmanız gerekiyor: D


2

Aslında 10 bayt

Bu, TIO'da tercüman hatalarına rastlamadığım en kısa çözümdü. Golf önerileri kabul edilir. Çevrimiçi deneyin!

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

Jöle , 3 bayt

ÆRL

Jelly, dahili bir asal sayma fonksiyonuna ÆCve bir asal kontrol fonksiyonuna sahiptir, ÆPbunun yerine yerleşik bir asal oluşturma fonksiyonunu kullanır ÆRve uzunluğu alır L.

Sanırım bu, 3 bayt alabilen birincil çarpanlara ayırma yerleşiklerini kullanmak kadar sınır çizgisidir !Æv( !faktoring, Ævsayma temel faktörleri)


2

PHP, 96 92 bayt

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;

Roman Gräf sayesinde 4 bayt kaydedildi

Çevrimiçi test

Ungolfed test kodu:

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

Çevrimiçi test


Neden kullanıyorsunuz isInt(...)?1:0ve sadece kullanmıyorsunuzisInt(...)
Roman Gräf

@ RomanGräf Teşekkürler, haklısın. Bir sürü kod basitleştirmeden sonra üçlüyü terk ettim ve bu çok açıktı. Bunu göremedim ...
Mario

2

APL (Dyalog Unicode) , 13 bayt SBCS

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

Çevrimiçi deneyin!

ɩ ndices 1 ... N
 ⧽ ∘.| (eksenleri olarak bu iki kullanılarak) geri kalan tablo
ɩ ndices 1 ... K

0+.= elemanların toplamı sıfıra eşit (yani, her birinin kaç bölücüsü var)

2+.= elemanların toplamı ikiye eşit (yani kaç tane asal sayı vardır)


2

Python 3, 40 bayt

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

Tek bir tamsayı k, eğer sadece 2 ** (k-1) 1 mod k ile uyumlu ise, asal değerdir. Bu nedenle, sadece bu durumu kontrol edip k = 2 durumunda 1 ekleriz.


2 ** n% n == 2 primaly testi olarak yeterli değil
RosLuP

@RosLuP Bu nedenle n == 0'ın temel durumu 1 eklemelidir (n = 2 durumu hesaba katacaktır).
Sandeep Silwal,

2 ** n% n == 2 genel olarak yeterli değil ... Çok fazla (hatırlayacağım şeylerle sınırsız) sayıların mevcut olduğu 2 ^ n% n = 2 asal değildir
RosLuP

Örneğin 341 = 11 * 31 ancak (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: Ah tamam evet, baktım. Bu sayılara Fermat Psuedoprimes deniyor ancak oldukça nadir görünüyorlar: P
Sandeep Silwal

2

MATL , 9 bayt

Bu, ana faktör ayrışmasını önler. Karmaşıklığı O ( n ²).

:t!\~s2=s

Çevrimiçi deneyin!

:     % 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 bayt

Neil sayesinde 3 5 bayt kaydedildi :

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

evalnparametreye erişebilir . Çekler ise asal olduğunu.
eval(...)n


Önceki çözümler:
Bayt sayısı +2 olmalıdır çünkü işlevi isimlendirmeyi unuttum f=(özyineleme için gerekli)

46 + 2 bayt (ETHproductions sayesinde 3 bayt kaydedildi):

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

50 + 2 bayt:

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

1
En azından tarayıcımda, parametrenizin işlevine evalerişebiliyorsunuz n(isimlendirmeyi unuttuysanız, size 2 bayta mal oluyor; bu hatayı yapan sadece ben olmadığımı bilmek güzel) 5 bayt.
Neil

@Neil bilmiyordum eval. Firefox, chrome ve edge ile test edildi ve benim için çalıştı. Açıklama eval () ifadesi bağlamında ayrıştırılır . İki örnek: a=12;f=b=>eval('a + 5');f(8)görüntüler 17ve a=12;f=a=>eval('a + 5');f(8)görüntüler 13.
Hedi

1

Java 7,102 bayt

Kaba kuvvet

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

Bu şu anda giriş için yanlış bir sonuç veriyor 1. Şu anda 1yerine döner 0. Ya değiştirerek bunu düzeltebilirsiniz return c;için return n<2?0:c;veya değiştirilmesi ,c=1,için ,c=n<2?0:1,.
Kevin Cruijssen


1

Aslında 10 bayt

İlk gerçek cevabımın temel üretici bir işlev kullanmasına izin verilmezse, Wilson teoremini kullanan bir yedekleme cevabı. Golf önerileri kabul edilir. Çevrimiçi deneyin!

R`;D!²%`MΣ

Çevrimiçi deneyin

         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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.