Chức năng đếm chính


28

Giới thiệu

Hàm đếm số nguyên tố , còn được gọi là hàm Pi , trả về số lượng các số nguyên tố nhỏ hơn hoặc bằng x.π(x)

Thử thách

Chương trình của bạn sẽ lấy một số nguyên x mà bạn có thể giả sử là dương và xuất ra một số nguyên duy nhất bằng số lượng các số nguyên tố nhỏ hơn hoặc bằng x. Đây là một thử thách , vì vậy người chiến thắng sẽ là chương trình có ít byte nhất.

Bạn có thể sử dụng bất kỳ ngôn ngữ nào bạn chọn với điều kiện nó tồn tại trước khi thử thách này xảy ra, nhưng nếu ngôn ngữ đó có chức năng đếm số nguyên tố tích hợp hoặc chức năng kiểm tra tính nguyên thủy (như Mathicala), thì chức năng đó không thể được sử dụng trong mã của bạn .

Ví dụ đầu vào

Đầu vào:
1
Đầu ra:
0

Đầu vào:
2
Đầu ra:
1

Đầu vào:
5
Đầu ra:
3

A000720 - OEIS


3
Còn các chức năng liên quan đến nguyên tố khác thì sao? Ví dụ: funciton "thủ tướng tiếp theo"
Luis Mendo

6
những gì về chức năng nhân tố chính?
Maltysen

4
Chào mừng bạn đến với Câu đố lập trình và Code Golf!
Ad Nam

6
Như Adnan đã nói, chào mừng bạn đến với PPCG! Đối với các thử thách trong tương lai, hãy để tôi giới thiệu Sandbox nơi bạn có thể đăng một thử thách để nhận phản hồi và phê bình có ý nghĩa trước khi đăng nó lên trang web chính.
admBorkBork

Tôi nghĩ đây là ý nghĩa của @TheBikingViking liên kết đến: Liên quan
mbomb007

Câu trả lời:


36

05AB1E , 3 byte

!fg

Điều này giả định rằng các yếu tố tích hợp được cho phép. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

5
Điều đó thực sự thông minh!
mbomb007

5
Chết tiệt, tôi đang nhận được rekt bằng ngôn ngữ của mình lần thứ hai haha. +1
Adnan

Tại sao điều này làm việc?
Oliver Ni

1
@Oliver Bởi vì giai thừa của n chia hết cho tất cả các số nguyên 1, ..., n (đặc biệt là các số nguyên tố p ≤ n ) và không có số nguyên tố nào khác q> n vì nó không thể được biểu diễn dưới dạng tích số nhỏ hơn.
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)

Sử dụng máy phát nguyên lý định lý Wilson . Các sản phẩm ptheo dõi (k-1)!^2, và p%klà 1 cho số nguyên tố và 0 cho số không.


Tính giai thừa từ dưới lên là một mẹo hay. +1
Sản phẩm ETH

6

MATL , 11, 10, 8 , 5 byte

:pYFn

Hãy thử trực tuyến!

Tôi đã viết một phiên bản có một lời giải thích thực sự hay về cách thức hoạt động của ma trận MATL:

:YF!s1=1

Nhưng nó không còn phù hợp nữa. Kiểm tra lịch sử sửa đổi nếu bạn muốn xem nó.

Giải thích mới:

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

Ba byte được lưu nhờ giải pháp thiên tài của Dennis


Nó ngắn hơn để sử dụng chức năng "số mũ của thừa số nguyên tố", bởi vì đó là một số hóa:YF!s1=s
Luis Mendo

@LuisMendo Đó là một cách tiếp cận hoàn toàn khác, vì vậy hãy thoải mái tiếp tục và đăng nó. (Mặc dù nếu bạn không muốn, tôi rất vui lòng)
DJMcMayhem

Đi về phía trước. Tôi sẽ chuyển nó đến Jelly để luyện tập :-)
Luis Mendo

5

Thạch , 8 5 byte

3 byte được lưu nhờ @Dennis!

RÆESL

Hãy thử trực tuyến!

Cảng câu trả lời MATL DJMcMayhem của (cựu version) tinh chế bởi 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
Sửa chữa: cổng của Luis Mendo's: Câu trả lời MATL của DJMcMayhem. : P
DJMcMayhem

2
Bạn chỉ cần độ dài tối đa của kết quả ÆE, vì mỗi số mũ tương ứng với một thừa số nguyên tố khác nhau. RÆESLđạt được điều đó !ÆELthậm chí sẽ ngắn hơn
Dennis

1
@Dennis Cảm ơn! Tôi đã sử dụng đề xuất đầu tiên. Cách thứ hai quá khác biệt và là cách tiếp cận của bạn
Luis Mendo

5

Các mẫu MediaWiki với ParserFifts , 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}}}}}}}}}}}}

Để gọi mẫu:

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

Sắp xếp theo phong cách 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}}}}}}}}}}}}

Chỉ là một bài kiểm tra nguyên thủy cơ bản từ 2 đến n . Những con số với ba niềng răng xung quanh họ là các biến, mà {{{1}}}n , {{{2}}}là số đang được thử nghiệm, {{{3}}}là yếu tố để kiểm tra.


5

Perl, 33 byte

Bao gồm +1 cho -p

Cho số đầu vào trên STDIN

primecount.pl

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

Cung cấp kết quả sai cho 0nhưng điều đó không sao, op chỉ yêu cầu hỗ trợ cho các số nguyên dương.




4

Thạch , 13 11 10 9 8 7 6 byte

Không sử dụng các hàm số nguyên tố tích hợp nào
-1 byte nhờ @miles (sử dụng bảng)
-1 byte nhờ @Dennis (chuyển đổi từ unary để đếm các ước số)

ḍþḅ1ċ2

TryItOnline
Hoặc xem 100 điều khoản đầu tiên của loạt bàin=[1,100], cũng tại TryItOnline

Làm sao?

ḍþḅ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
Bạn có thể nhận được tới 7 byte %þ`¬Sċ2bằng cách sử dụng bảng còn lại.
dặm

1
ḍþḅ1ċ2tiết kiệm một byte.
Dennis

4

JavaScript (ES6), 45 43 byte

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

Một sửa đổi của chức năng nguyên thủy 36 35 33 byte của tôi (1 byte được lưu bởi @Neil, 2 bởi @Arnauld):

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

(Tôi không thể đăng bài này ở bất cứ đâu vì số này có phải là số nguyên tố không? Chỉ chấp nhận các chương trình đầy đủ ...)

Kiểm tra đoạn


Waw ... tôi phải mất một lúc để hiểu. Công việc tốt!
thiệu

Đáng buồn thay, nó không áp dụng cho câu trả lời của bạn nhưng có lẽ bạn có thể thoát khỏi một câu &ở giữa chức năng nguyên thủy của bạn.
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

Chú ý: Đây là chậm cho đầu vào lớn.

Về cơ bản việc tra cứu dựa trên đơn nguyên từ số này có phải là số nguyên tố không? , kết hợp với một forvòng lặp và một bộ $j++đếm. Một chút logic bổ sung ở mặt trước để giải thích cho các trường hợp cạnh đầu vào 12, do cách thức hoạt động của hàng rào trong các forvòng lặp.


3

05AB1E , 5 byte

Giả sử rằng các phần tử nhân tố chính được cho phép.

Mã số:

LÒ1ùg

Giải trình:

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

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến!


ÅPgbây giờ là gì phải không?
Bạch tuộc ma thuật Urn

3

CJam , 7 byte

rim!mF,

Hãy thử trực tuyến! Sử dụng một chức năng nhân tố.

Giải trình:

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

3

Thạch , 6 byte

Ḷ!²%RS

Điều này chỉ sử dụng số học cơ bản và định lý Wilson. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

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

3

C # 5.0 78 77

int F(int n){int z=n;if(n<2)return 0;for(;n%--z!=0;);return(2>z?1:0)+F(n-1);}

Bị đánh cắp

int F(int n)
{
    var z = n;
    if (n < 2) return 0;
    for (; n % --z != 0;) ;
    return F(n - 1) + (2 > z ? 1 : 0);
}

@tfbninja vâng bạn đúng, nhưng tôi chỉ cung cấp phần chức năng, phần này không được biên dịch bởi chính nó
Ariel Bereslavsky


âm thanh mát mẻ tốt!
FantaC


2

Bash + coreutils, 30

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

Ideone.


Bash + coreutils + gói trò chơi BSD, 22

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

Câu trả lời ngắn hơn này yêu cầu bạn phải cài đặt gói bsdgames : sudo apt install bsdgames.



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

Chương trình đầy đủ với các trường hợp thử nghiệm:

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

Bắt đầu mất một lúc sau khi bạn vượt quá 1 triệu.


2

Matlab, 60 byte

Tiếp tục tệp đính kèm của tôi với các hàm Matlab một dòng. Không sử dụng hệ số tích hợp:

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

Cho rằng một số nguyên tố ychỉ có hai yếu tố [1,y]: chúng tôi đếm các số trong phạm vi [1,x]chỉ có hai yếu tố.

Sử dụng hệ số cho phép rút ngắn đáng kể (xuống tới 46 byte).

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

Kết luận: Cần xem xét ngôn ngữ chơi gôn của họ: D


2

Trên thực tế, 10 byte

Đây là giải pháp ngắn nhất mà tôi thấy không gặp phải lỗi phiên dịch trên TIO. Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

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

Thạch , 3 byte

ÆRL

Jelly có chức năng đếm số nguyên tố tích hợp, ÆC và chức năng kiểm tra số nguyên tố ÆP, thay vào đó, nó sử dụng chức năng tạo số nguyên tố tích hợp ÆRvà lấy độ dài L.

Tôi đoán đây là về đường biên như sử dụng các phần tử nguyên tố tích hợp, cũng sẽ mất 3 byte với !Æv( !giai thừa, Ævtính các thừa số nguyên tố)


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;

Đã lưu 4 byte nhờ Roman Gräf

Kiểm tra trực tuyến

Mã kiểm tra bị đánh cắp:

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

Kiểm tra trực tuyến


Tại sao bạn sử dụng isInt(...)?1:0và không chỉisInt(...)
Roman Gräf

@ RomanGräf Cảm ơn, bạn đã đúng. Tôi đã rời khỏi ternary sau rất nhiều mã hóa, và điều đó rõ ràng đến mức tôi không thể nhìn thấy nó ...
Mario

2

APL (Dyalog Unicode) , 13 byte SBCS

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

Hãy thử trực tuyến!

ɩ ndices 1 ... N
 ⧽ ∘.| còn lại-bảng (sử dụng hai như rìu)
ɩ ndices 1 lệch N

0+.= tổng các phần tử bằng 0 (tức là mỗi phần tử có bao nhiêu bộ chia)

2+.= tổng các phần tử bằng hai (tức là có bao nhiêu số nguyên tố)


2

Python 3, 40 byte

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

Một số nguyên k là số nguyên tố nếu chỉ khi 2 ** (k-1) đồng dạng với 1 mod k. Vì vậy, chúng tôi chỉ kiểm tra điều kiện này và thêm 1 cho trường hợp k = 2.


2 ** n% n == 2 là không đủ như thử nghiệm nguyên thủy
RosLuP

@RosLuP Đó là lý do tại sao trường hợp cơ sở của n == 0 nên thêm 1 (để tính cho trường hợp n = 2).
Sandeep Silwal

2 ** n% n == 2 nói chung là không đủ ... Tồn tại nhiều số (vô hạn trong những gì tôi sẽ nhớ) trong đó 2 ^ n% n = 2 không phải là số nguyên tố
RosLuP

Ví dụ 341 = 11 * 31 nhưng (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: À đúng rồi, tôi đã tra cứu nó. Những con số này được gọi là Fermat Psuedoprimes nhưng chúng có vẻ khá hiếm: P
Sandeep Silwal

2

TOÁN , 9 byte

Điều này tránh sự phân hủy yếu tố chính. Độ phức tạp của nó là O ( n ²).

:t!\~s2=s

Hãy thử trực tuyến!

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

Đã lưu 3 5 byte nhờ Neil:

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

evalcó thể truy cập ntham số.
Việc eval(...)kiểm tra nếu nlà số nguyên tố.


Các giải pháp trước đây:
Số lượng byte nên là +2 vì tôi quên đặt tên hàm f=(cần thiết cho đệ quy)

46 + 2 byte (Đã lưu 3 byte nhờ ETHproductions):

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
Ít nhất trên trình duyệt của tôi, evalcó thể truy cập ntham số vào chức năng của bạn (mà bạn quên đặt tên, làm bạn tốn 2 byte; thật tốt khi biết rằng tôi không phải là người duy nhất mắc lỗi đó) giúp bạn tiết kiệm 5 byte.
Neil

@ Tôi không biết eval. Đã thử nghiệm với firefox, chrome và edge nó hoạt động với tôi. Giải thích là phân tích eval () trong ngữ cảnh câu lệnh . Hai ví dụ: a=12;f=b=>eval('a + 5');f(8)hiển thị 17a=12;f=a=>eval('a + 5');f(8)hiển thị 13.
Hedi

1

Java 7,102 byte

Lực lượng vũ phu

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

Bị đánh cắp

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

Điều này hiện đang đưa ra một kết quả không chính xác cho đầu vào 1. Nó hiện đang trả lại 1thay vì 0. Bạn có thể sửa lỗi này bằng một trong hai thay đổi return c;để return n<2?0:c;hoặc thay đổi ,c=1,để ,c=n<2?0:1,.
Kevin Cruijssen


1

Trên thực tế, 10 byte

Nếu câu trả lời thực tế đầu tiên của tôi không được phép sử dụng hàm tạo nguyên tố, thì đây là câu trả lời dự phòng sử dụng định lý Wilson. Gợi ý chơi golf chào mừng. Hãy thử trực tuyến!

R`;D!²%`MΣ

Dùng thử trực tuyến

         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.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.