ฟังก์ชั่นการนับเฉพาะ


28

บทนำ

ฟังก์ชั่นการนับนายกรัฐมนตรียังเป็นที่รู้จักฟังก์ชั่น Pi กลับปริมาณของจำนวนเฉพาะที่น้อยกว่าหรือเท่ากับ xπ(x)

ท้าทาย

โปรแกรมของคุณจะใช้จำนวนเต็ม x ซึ่งคุณสามารถถือว่าเป็นค่าบวกและส่งออกจำนวนเต็มเดียวเท่ากับจำนวนช่วงเวลาที่น้อยกว่าหรือเท่ากับ x นี่คือความท้าทายของดังนั้นผู้ชนะจะเป็นโปรแกรมที่มีจำนวนไบต์น้อยที่สุด

คุณสามารถใช้ภาษาใดก็ได้ที่คุณเลือกหากมีอยู่ก่อนที่ความท้าทายนี้จะเกิดขึ้น แต่ถ้าภาษานั้นมีฟังก์ชั่นการนับจำนวนเฉพาะหรือฟังก์ชั่นตรวจสอบเบื้องต้น (เช่น Mathematica) ฟังก์ชันนั้นไม่สามารถใช้ในรหัสของคุณได้ .

อินพุตตัวอย่าง

อินพุต:
1
เอาต์พุต:
0

อินพุต:
2
เอาต์พุต:
1

อินพุต:
5
เอาต์พุต:
3

A000720 - OEIS


3
แล้วฟังก์ชั่นที่เกี่ยวข้องกับไพรม์อื่น ๆ ล่ะ? ตัวอย่างเช่น funciton "นายกคนต่อไป"
Luis Mendo

6
ฟังก์ชั่นการแยกตัวประกอบเฉพาะ?
Maltysen

4
ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ!
Adnan

6
ดังที่ Adnan ได้กล่าวไว้ยินดีต้อนรับสู่ PPCG! สำหรับความท้าทายในอนาคตให้ฉันแนะนำSandboxซึ่งคุณสามารถโพสต์ความท้าทายเพื่อรับข้อเสนอแนะและคำวิจารณ์ที่มีความหมายก่อนโพสต์ลงในเว็บไซต์หลัก
AdmBorkBork

ฉันคิดว่านี่คือสิ่งที่ @TheBikingViking หมายถึงการเชื่อมโยงไปยัง: ที่เกี่ยวข้อง
mbomb007

คำตอบ:


36

05AB1E , 3 ไบต์

!fg

สิ่งนี้อนุมานว่ามีการสร้างบิวด์อินการแยกได้ ลองออนไลน์!

มันทำงานอย่างไร

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

5
มันฉลาดจริงๆ!
mbomb007

5
ประณามฉันเริ่มพูดภาษาของฉันเป็นครั้งที่สองฮ่าฮ่า +1
Adnan

ทำไมจึงใช้งานได้
Oliver Ni

1
@Oliver เนื่องจากแฟกทอเรียลของnหารด้วยจำนวนเต็มทั้งหมด1, ... , n (โดยเฉพาะ primes p ≤ n ) และไม่มีไพร์มqอื่น ๆเนื่องจากไม่สามารถแสดงเป็นผลคูณของจำนวนที่น้อยกว่า
เดนนิส

10

Python 2, 45 ไบต์

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

ใช้ทฤษฏีของวิลสันกำเนิดที่สำคัญ ผลิตภัณฑ์pติดตาม(k-1)!^2และp%kเป็น 1 สำหรับช่วงเวลาและ 0 สำหรับช่วงเวลาที่ไม่ใช่


การคำนวณแฟคทอเรียลจากล่างขึ้นบนเป็นเคล็ดลับที่ยอดเยี่ยม +1
ETHproductions

6

MATL , 11, 10, 8 , 5 ไบต์

:pYFn

ลองออนไลน์!

ฉันเขียนเวอร์ชันที่มีคำอธิบายที่ยอดเยี่ยมเกี่ยวกับวิธีการฝึกอบรมของ MATL:

:YF!s1=1

แต่มันไม่มีความเกี่ยวข้องอีกต่อไป ตรวจสอบประวัติการแก้ไขหากคุณต้องการดู

คำอธิบายใหม่:

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

บันทึกสามไบต์ด้วยโซลูชั่นอัจฉริยะของ Dennis


มันสั้นกว่าที่จะใช้ฟังก์ชั่น "เลขชี้กำลังของการแยกตัวประกอบเฉพาะ" เนื่องจากเวกเตอร์หนึ่งตัว:YF!s1=s
Luis Mendo

@ LuisMendo นั่นเป็นวิธีการที่แตกต่างกันโดยสิ้นเชิงดังนั้นอย่าลังเลที่จะไปข้างหน้าและโพสต์มัน (แม้ว่าคุณจะไม่ต้องการฉันก็มีความสุข)
DJMcMayhem

ไปข้างหน้า ฉันจะพอร์ตนั้นให้ Jelly ฝึกหัด :-)
Luis Mendo

5

เจลลี่ , 8ไบต์ 5

บันทึก 3 ไบต์ด้วย @Dennis!

RÆESL

ลองออนไลน์!

พอร์ตของคำตอบ MATLABของDJMcMayhem (เวอร์ชั่นเดิม) ปรับปรุงโดย 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
การแก้ไข: พอร์ตของ Luis Mendo: คำตอบ MATL ของ DJMcMayhem : P
DJMcMayhem

2
คุณต้องการความยาวสูงสุดของผลลัพธ์ÆEเท่านั้นเนื่องจากเลขชี้กำลังแต่ละตัวสอดคล้องกับปัจจัยหลักที่แตกต่างกัน RÆESLประสบความสำเร็จเพียงแค่นั้น !ÆELจะสั้นกว่านี้
เดนนิส

1
@ เดนนิสขอบคุณ! ฉันใช้คำแนะนำแรก คนที่สองแตกต่างกันมากเกินไปและเป็นแนวทางของคุณ
Luis Mendo

5

เทมเพลต MediaWiki ที่มีParserFunctions , 220 + 19 = 239 ไบต์

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

วิธีเรียกเทมเพลต:

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

จัดในรูปแบบเสียงกระเพื่อม:

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

เพียง primality ทดสอบขั้นพื้นฐานตั้งแต่ 2 ถึงn ตัวเลขที่มีสามวงเล็บรอบตัวพวกเขาเป็นตัวแปรที่{{{1}}}เป็นn , {{{2}}}เป็นจำนวนที่ได้รับการทดสอบ{{{3}}}เป็นปัจจัยในการตรวจสอบ


5

Perl, 33 ไบต์

รวม +1 สำหรับ -p

ระบุหมายเลขอินพุตใน STDIN

primecount.pl

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

ให้ผลลัพธ์ที่ไม่ถูกต้อง0แต่ก็ไม่เป็นไร op ขอการสนับสนุนสำหรับจำนวนเต็มบวกเท่านั้น


4

เรติน่า 31 ไบต์

จำนวนไบต์ถือว่าการเข้ารหัส ISO 8859-1 แปลงอินพุตเป็น unary สร้างช่วงจาก1ถึงnแต่ละบรรทัดของตัวเอง ตรงกับช่วงเวลา

.*
$*
\B
¶$`
m`^(?!(..+)\1+$)..

ลองออนไลน์ - อินพุตใหญ่กว่า 2,800 ครั้งหรือหน่วยความจำหมด

อ้างอิง:

เครื่องกำเนิดไฟฟ้าของมาร์ติน

ตัวตรวจสอบที่สำคัญของ Martin



4

เยลลี่ , 13 11 10 9 8 7 6 ไบต์

การใช้ไม่มีฟังก์ชั่นเฉพาะในตัว แต่อย่างใด
-1 ไบต์ขอบคุณ @miles (ใช้ตาราง)
-1 ไบต์ขอบคุณ @Dennis (แปลงจากเอกภาพเพื่อนับตัวหาร)

ḍþḅ1ċ2

TryItOnline
หรือดูข้อกำหนด 100 ชุดn=[1,100]แรกที่ TryItOnline

อย่างไร?

ḍþḅ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
คุณสามารถรับได้ถึง 7 ไบต์%þ`¬Sċ2โดยใช้ตารางที่เหลือ
ไมล์

1
ḍþḅ1ċ2บันทึกเป็นไบต์
เดนนิส

4

JavaScript (ES6), 45 43 ไบต์

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

การปรับเปลี่ยนฟังก์ชัน primality 36 35 33- ไบต์ของฉัน(1 ไบต์บันทึกโดย @Neil, 2 โดย @Arnauld):

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

(ฉันไม่สามารถโพสต์สิ่งนี้ได้ทุกที่เพราะเป็นหมายเลขนี้ใช่หรือไม่ยอมรับเฉพาะโปรแกรมเต็มรูปแบบ ... )

ตัวอย่างการทดสอบ


ว้าว ... ฉันต้องใช้เวลาพอสมควรในการทำความเข้าใจ งานที่ดี!
todeale

น่าเศร้าที่มันไม่ได้ใช้กับคำตอบของคุณ แต่คุณอาจจะไปกับหนึ่ง&ในช่วงกลางของการทำงานของคุณ
Neil

3

PowerShell v2 +, 98 ไบต์

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

ข้อควรระวัง:สิ่งนี้ช้าสำหรับอินพุตขนาดใหญ่

โดยพื้นฐานแล้วการค้นหาที่แยกจากกันเป็นจำนวนนี้หรือไม่ รวมกับforห่วงและตัว$j++นับ ตรรกะเพิ่มเติมเล็กน้อยที่ด้านหน้าเพื่ออธิบายการป้อนข้อมูลเคสขอบ1และ2เนื่องจากการทำงานของเสารั้วในforลูป


3

05AB1E , 5 ไบต์

สมมติว่าบิวด์อินการแยกตัวประกอบเฉพาะ

รหัส:

LÒ1ùg

คำอธิบาย:

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 ลองออนไลน์!


ÅPgตอนนี้มันเป็นอะไรใช่ไหม?
Magic Octopus Urn


3

เยลลี่ 6 ไบต์

Ḷ!²%RS

สิ่งนี้ใช้เลขคณิตพื้นฐานและทฤษฎีบทของวิลสันเท่านั้น ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

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

C #, 157 ไบต์

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

โปรแกรมเต็มรูปแบบพร้อมกรณีทดสอบ:

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 ล้าน


2

Matlab, 60 ไบต์

ดำเนินการต่อไฟล์แนบของฉันกับฟังก์ชัน Matlab แบบบรรทัดเดียว โดยไม่ต้องใช้การแยกตัวประกอบ:

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

ระบุว่านายกyมีเพียงสองปัจจัยใน[1,y]: เรานับตัวเลขในช่วง[1,x]ที่มีเพียงสองปัจจัย

Using factorisation allows for significant shortening (down to 46 bytes).

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

Conclusion: Need to look into them golfing languages :D


2

Actually, 10 bytes

This was the shortest solution I found that didn't run into interpreter bugs on TIO. Golfing suggestions welcome. Try it 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

Jelly, 3 bytes

ÆRL

Jelly has a built-in prime counting function, ÆC and a prime checking function, ÆP, this instead uses a built-in prime generating function, ÆR and takes the length L.

I guess this is about as borderline as using prime factorisation built-ins, which would also take 3 bytes with !Æv (! factorial, Æv count prime factors)


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;

Saved 4 bytes thanks to Roman Gräf

Test online

Ungolfed testing code:

$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


Why do you use isInt(...)?1:0 and not just isInt(...)
Roman Gräf

@RomanGräf Thanks, you are right. I left the ternary after a lot of code semplification, and that was so obvious that I couldn't see it...
Mario


2

Python 3, 40 bytes

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

An odd integer k is prime if an only if 2**(k-1) is congruent to 1 mod k. Thus, we just check for this condition and add 1 for the case of k=2.


2**n % n==2 is not enough as primaly test
RosLuP

@RosLuP That is why the base case of n==0 should add 1 (to account for the n=2 case).
Sandeep Silwal

2**n % n==2 is not enough in general... Exist many (infinite in what I would remember) numbers where 2^n%n=2 that are not primes
RosLuP

For example 341=11*31 but ( 2^341) mod 341==2
RosLuP

@RosLuP: Ah ok yes, I looked it up. These numbers are called Fermat Psuedoprimes but they appear to be quite rare :P
Sandeep Silwal

2

MATL, 9 bytes

This avoids prime-factor decomposition. Its complexity is O(n²).

:t!\~s2=s

Try it 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

Saved 3 5 bytes thanks to Neil:

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

eval can access the n parameter.
The eval(...) checks if n is prime.


Previous solutions:
Byte count should be +2 because I forgot to name the function f= (needed for recursion)

46+2 bytes (Saved 3 bytes thanks to 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
At least on my browser, eval can access the n parameter to your function (which you forgot to name, costing you 2 bytes; it's good to know that I'm not the only one who makes that mistake) which saves you 5 bytes.
Neil

@Neil I didn't know for eval. Tested with firefox, chrome and edge it worked for me. The explanation is eval() parses in statement context. Two examples: a=12;f=b=>eval('a + 5');f(8) displays 17 and a=12;f=a=>eval('a + 5');f(8) displays 13.
Hedi

1

Java 7,102 bytes

Brute force

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

This is currently giving an incorrect result for input 1. It currently returns 1 instead of 0. You can fix this by either changing return c; to return n<2?0:c; or changing ,c=1, to ,c=n<2?0:1,.
Kevin Cruijssen


1

Actually, 10 bytes

If my first Actually answer is disallowed for using a prime-generating function, here is a backup answer using Wilson's theorem. Golfing suggestions welcome. Try it online!

R`;D!²%`MΣ

Try it 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.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.